Merge branch 'master' of github.com:raysan5/raylib
This commit is contained in:
commit
c8d907ed89
|
|
@ -9,6 +9,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.0** | [Beef](https://www.beeflang.org) | MIT |
|
||||
| [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT |
|
||||
| [raybit](https://github.com/Alex-Velez/raybit) | 3.7 | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
|
|
@ -21,7 +22,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
||||
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||
| [dray](https://github.com/redthing1/dray) | 4.2 | [D](https://dlang.org) | Apache-2.0 |
|
||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.0** | [D](https://dlang.org) | Zlib |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
|
||||
|
|
@ -149,7 +150,7 @@ These are older raylib bindings that are more than 2 versions old or have not be
|
|||
| [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) |
|
||||
| [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) |
|
||||
| [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) |
|
||||
| [raylib-carp](https://github.com/pluckyporcupine/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
|
||||
| [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
|
||||
| [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) |
|
||||
| [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) |
|
||||
| [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) |
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
|||
[](LICENSE)
|
||||
|
||||
[](https://discord.gg/raylib)
|
||||
[](https://www.reddit.com/r/raylib/)
|
||||
[](https://www.reddit.com/r/raylib/)
|
||||
[](https://www.youtube.com/c/raylib)
|
||||
[](https://www.twitch.tv/raysan5)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ endfunction()
|
|||
|
||||
if(${CUSTOMIZE_BUILD})
|
||||
target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS)
|
||||
define_if("raylib" USE_AUDIO)
|
||||
|
||||
foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
|
||||
string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})
|
||||
|
|
|
|||
|
|
@ -479,6 +479,7 @@ CORE = \
|
|||
core/core_automation_events \
|
||||
core/core_basic_screen_manager \
|
||||
core/core_basic_window \
|
||||
core/core_basic_window_web \
|
||||
core/core_custom_frame_control \
|
||||
core/core_custom_logging \
|
||||
core/core_drop_files \
|
||||
|
|
@ -528,6 +529,7 @@ TEXTURES = \
|
|||
textures/textures_draw_tiled \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_gif_player \
|
||||
textures/textures_image_channel \
|
||||
textures/textures_image_drawing \
|
||||
textures/textures_image_generation \
|
||||
textures/textures_image_kernel \
|
||||
|
|
@ -566,6 +568,7 @@ TEXT = \
|
|||
MODELS = \
|
||||
models/models_animation \
|
||||
models/models_billboard \
|
||||
models/models_bone_socket \
|
||||
models/models_box_collisions \
|
||||
models/models_cubicmap \
|
||||
models/models_draw_cube_texture \
|
||||
|
|
@ -586,6 +589,7 @@ MODELS = \
|
|||
|
||||
SHADERS = \
|
||||
shaders/shaders_basic_lighting \
|
||||
shaders/shaders_basic_pbr \
|
||||
shaders/shaders_custom_uniform \
|
||||
shaders/shaders_deferred_render \
|
||||
shaders/shaders_eratosthenes \
|
||||
|
|
@ -608,7 +612,8 @@ SHADERS = \
|
|||
shaders/shaders_texture_outline \
|
||||
shaders/shaders_texture_tiling \
|
||||
shaders/shaders_texture_waves \
|
||||
shaders/shaders_write_depth
|
||||
shaders/shaders_write_depth \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_mixed_processor \
|
||||
|
|
|
|||
|
|
@ -476,7 +476,8 @@ SHADERS = \
|
|||
shaders/shaders_texture_outline \
|
||||
shaders/shaders_texture_tiling \
|
||||
shaders/shaders_texture_waves \
|
||||
shaders/shaders_write_depth
|
||||
shaders/shaders_write_depth \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_mixed_processor \
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
|||
| 115 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 116 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||
| 117 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
||||
| 118 | [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) | <img src="shaders/shaders_vertex_displacement.png" alt="shaders_deferred_render" width="80"> | ⭐️☆☆☆ | 1.5 | 1.5 | [Alex ZH](https://github.com/ZzzhHe) |
|
||||
|
||||
### category: audio
|
||||
|
||||
|
|
@ -185,10 +186,10 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
|||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 118 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 119 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 120 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 121 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 119 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 120 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 121 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 122 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
|
||||
### category: others
|
||||
|
||||
|
|
@ -196,11 +197,11 @@ Examples showing raylib misc functionality that does not fit in other categories
|
|||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 122 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 123 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
|
||||
| 124 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
| 125 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
|
||||
| 126 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||
| 123 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 124 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
|
||||
| 125 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
| 126 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
|
||||
| 127 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||
|
||||
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ int main(void)
|
|||
DrawRectangle(199, 199, 402, 34, LIGHTGRAY);
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
DrawLine(201 + i, 232 - (int)averageVolume[i] * 32, 201 + i, 232, MAROON);
|
||||
DrawLine(201 + i, 232 - (averageVolume[i] * 32), 201 + i, 232, MAROON);
|
||||
}
|
||||
DrawRectangleLines(199, 199, 402, 34, GRAY);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ int main(void)
|
|||
// NOTE: Billboard locked on axis-Y
|
||||
Vector3 billUp = { 0.0f, 1.0f, 0.0f };
|
||||
|
||||
// Set the height of the rotating billboard to 1.0 with the aspect ratio fixed
|
||||
Vector2 size = { source.width/source.height, 1.0f };
|
||||
|
||||
// Rotate around origin
|
||||
// Here we choose to rotate around the image center
|
||||
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture
|
||||
Vector2 rotateOrigin = { 0.0f };
|
||||
Vector2 origin = Vector2Scale(size, 0.5f);
|
||||
|
||||
// Distance is needed for the correct billboard draw order
|
||||
// Larger distance (further away from the camera) should be drawn prior to smaller distance.
|
||||
|
|
@ -84,11 +86,11 @@ int main(void)
|
|||
if (distanceStatic > distanceRotating)
|
||||
{
|
||||
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
|
||||
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
|
||||
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
|
||||
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, WHITE);
|
||||
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ int main(void)
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading gltf");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading gltf animations");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
||||
camera.position = (Vector3){ 6.0f, 6.0f, 6.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 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
|
||||
|
|
@ -42,6 +42,7 @@ int main(void)
|
|||
|
||||
// Load gltf model
|
||||
Model model = LoadModel("resources/models/gltf/robot.glb");
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
// Load gltf model animations
|
||||
int animsCount = 0;
|
||||
|
|
@ -49,10 +50,6 @@ int main(void)
|
|||
unsigned int animCurrentFrame = 0;
|
||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
|
||||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -61,7 +58,8 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
// Select current animation
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
|
||||
|
|
@ -79,10 +77,8 @@ int main(void)
|
|||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
|
||||
|
|
@ -101,3 +97,6 @@ int main(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ uniform vec2 resolution;
|
|||
//
|
||||
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
|
||||
#define AA 1 // make this 1 is your machine is too slow
|
||||
#define AA 1 // make this 1 if your machine is too slow
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from fragment shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying float height;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
|
||||
vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
// Interpolate between two colors based on height
|
||||
vec4 finalColor = mix(darkblue, lightblue, height);
|
||||
|
||||
gl_FragColor = finalColor;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
|
||||
uniform float time;
|
||||
|
||||
uniform sampler2D perlinNoiseMap;
|
||||
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec3 fragNormal;
|
||||
varying float height;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Calculate animated texture coordinates based on time and vertex position
|
||||
vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
|
||||
|
||||
// Normalize animated texture coordinates to range [0, 1]
|
||||
animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
|
||||
|
||||
// Fetch displacement from the perlin noise map
|
||||
float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r * 7.0; // Amplified displacement
|
||||
|
||||
// Displace vertex position
|
||||
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
|
||||
|
||||
// Send vertex attributes to fragment shader
|
||||
fragPosition = vec3(matModel * vec4(displacedPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
|
||||
height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp * vec4(displacedPosition, 1.0);
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#version 120
|
||||
|
||||
precision mediump float;
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define LIGHT_DIRECTIONAL 0
|
||||
#define LIGHT_POINT 1
|
||||
|
|
@ -17,12 +15,12 @@ struct Light {
|
|||
};
|
||||
|
||||
// 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;
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
varying vec4 shadowPos;
|
||||
varying mat3 TBN;
|
||||
|
||||
|
||||
// Input uniform values
|
||||
|
|
|
|||
427
examples/shaders/resources/shaders/glsl120/raymarching.fs
Normal file
427
examples/shaders/resources/shaders/glsl120/raymarching.fs
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
#version 120
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
uniform vec3 viewEye;
|
||||
uniform vec3 viewCenter;
|
||||
uniform float runTime;
|
||||
uniform vec2 resolution;
|
||||
|
||||
// The MIT License
|
||||
// Copyright © 2013 Inigo Quilez
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// A list of useful distance function to simple primitives, and an example on how to
|
||||
// do some interesting boolean operations, repetition and displacement.
|
||||
//
|
||||
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
|
||||
#define AA 1 // make this 1 if your machine is too slow
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
float sdPlane( vec3 p )
|
||||
{
|
||||
return p.y;
|
||||
}
|
||||
|
||||
float sdSphere( vec3 p, float s )
|
||||
{
|
||||
return length(p)-s;
|
||||
}
|
||||
|
||||
float sdBox( vec3 p, vec3 b )
|
||||
{
|
||||
vec3 d = abs(p) - b;
|
||||
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
|
||||
}
|
||||
|
||||
float sdEllipsoid( in vec3 p, in vec3 r )
|
||||
{
|
||||
return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
|
||||
}
|
||||
|
||||
float udRoundBox( vec3 p, vec3 b, float r )
|
||||
{
|
||||
return length(max(abs(p)-b,0.0))-r;
|
||||
}
|
||||
|
||||
float sdTorus( vec3 p, vec2 t )
|
||||
{
|
||||
return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
|
||||
}
|
||||
|
||||
float sdHexPrism( vec3 p, vec2 h )
|
||||
{
|
||||
vec3 q = abs(p);
|
||||
#if 0
|
||||
return max(q.z-h.y,max((q.x*0.866025+q.y*0.5),q.y)-h.x);
|
||||
#else
|
||||
float d1 = q.z-h.y;
|
||||
float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x;
|
||||
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
|
||||
#endif
|
||||
}
|
||||
|
||||
float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
|
||||
{
|
||||
vec3 pa = p-a, ba = b-a;
|
||||
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
return length( pa - ba*h ) - r;
|
||||
}
|
||||
|
||||
float sdEquilateralTriangle( in vec2 p )
|
||||
{
|
||||
const float k = sqrt(3.0);
|
||||
p.x = abs(p.x) - 1.0;
|
||||
p.y = p.y + 1.0/k;
|
||||
if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0;
|
||||
p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 );
|
||||
return -length(p)*sign(p.y);
|
||||
}
|
||||
|
||||
float sdTriPrism( vec3 p, vec2 h )
|
||||
{
|
||||
vec3 q = abs(p);
|
||||
float d1 = q.z-h.y;
|
||||
#if 1
|
||||
// distance bound
|
||||
float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5;
|
||||
#else
|
||||
// correct distance
|
||||
h.x *= 0.866025;
|
||||
float d2 = sdEquilateralTriangle(p.xy/h.x)*h.x;
|
||||
#endif
|
||||
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
|
||||
}
|
||||
|
||||
float sdCylinder( vec3 p, vec2 h )
|
||||
{
|
||||
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
|
||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
||||
}
|
||||
|
||||
float sdCone( in vec3 p, in vec3 c )
|
||||
{
|
||||
vec2 q = vec2( length(p.xz), p.y );
|
||||
float d1 = -q.y-c.z;
|
||||
float d2 = max( dot(q,c.xy), q.y);
|
||||
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
|
||||
}
|
||||
|
||||
float sdConeSection( in vec3 p, in float h, in float r1, in float r2 )
|
||||
{
|
||||
float d1 = -p.y - h;
|
||||
float q = p.y - h;
|
||||
float si = 0.5*(r1-r2)/h;
|
||||
float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );
|
||||
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
|
||||
}
|
||||
|
||||
float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
|
||||
{
|
||||
// Tetrahedron = Octahedron - Cube
|
||||
float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) );
|
||||
|
||||
float d = 0.0;
|
||||
d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) ));
|
||||
d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) ));
|
||||
d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) ));
|
||||
d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) ));
|
||||
float octa = d - h.z;
|
||||
return max(-box,octa); // Subtraction
|
||||
}
|
||||
|
||||
float length2( vec2 p )
|
||||
{
|
||||
return sqrt( p.x*p.x + p.y*p.y );
|
||||
}
|
||||
|
||||
float length6( vec2 p )
|
||||
{
|
||||
p = p*p*p; p = p*p;
|
||||
return pow( p.x + p.y, 1.0/6.0 );
|
||||
}
|
||||
|
||||
float length8( vec2 p )
|
||||
{
|
||||
p = p*p; p = p*p; p = p*p;
|
||||
return pow( p.x + p.y, 1.0/8.0 );
|
||||
}
|
||||
|
||||
float sdTorus82( vec3 p, vec2 t )
|
||||
{
|
||||
vec2 q = vec2(length2(p.xz)-t.x,p.y);
|
||||
return length8(q)-t.y;
|
||||
}
|
||||
|
||||
float sdTorus88( vec3 p, vec2 t )
|
||||
{
|
||||
vec2 q = vec2(length8(p.xz)-t.x,p.y);
|
||||
return length8(q)-t.y;
|
||||
}
|
||||
|
||||
float sdCylinder6( vec3 p, vec2 h )
|
||||
{
|
||||
return max( length6(p.xz)-h.x, abs(p.y)-h.y );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
float opS( float d1, float d2 )
|
||||
{
|
||||
return max(-d2,d1);
|
||||
}
|
||||
|
||||
vec2 opU( vec2 d1, vec2 d2 )
|
||||
{
|
||||
return (d1.x<d2.x) ? d1 : d2;
|
||||
}
|
||||
|
||||
vec3 opRep( vec3 p, vec3 c )
|
||||
{
|
||||
return mod(p,c)-0.5*c;
|
||||
}
|
||||
|
||||
vec3 opTwist( vec3 p )
|
||||
{
|
||||
float c = cos(10.0*p.y+10.0);
|
||||
float s = sin(10.0*p.y+10.0);
|
||||
mat2 m = mat2(c,-s,s,c);
|
||||
return vec3(m*p.xz,p.y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
vec2 map( in vec3 pos )
|
||||
{
|
||||
vec2 res = opU( vec2( sdPlane( pos), 1.0 ),
|
||||
vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );
|
||||
res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );
|
||||
res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );
|
||||
res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );
|
||||
res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) );
|
||||
res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );
|
||||
res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );
|
||||
res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );
|
||||
res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );
|
||||
res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );
|
||||
res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );
|
||||
res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );
|
||||
res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) );
|
||||
res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
|
||||
sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );
|
||||
res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
|
||||
sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) );
|
||||
res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) );
|
||||
res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );
|
||||
res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );
|
||||
res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
vec2 castRay( in vec3 ro, in vec3 rd )
|
||||
{
|
||||
float tmin = 0.2;
|
||||
float tmax = 30.0;
|
||||
|
||||
#if 1
|
||||
// bounding volume
|
||||
float tp1 = (0.0-ro.y)/rd.y; if( tp1>0.0 ) tmax = min( tmax, tp1 );
|
||||
float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 );
|
||||
else tmax = min( tmax, tp2 ); }
|
||||
#endif
|
||||
|
||||
float t = tmin;
|
||||
float m = -1.0;
|
||||
for( int i=0; i<64; i++ )
|
||||
{
|
||||
float precis = 0.0005*t;
|
||||
vec2 res = map( ro+rd*t );
|
||||
if( res.x<precis || t>tmax ) break;
|
||||
t += res.x;
|
||||
m = res.y;
|
||||
}
|
||||
|
||||
if( t>tmax ) m=-1.0;
|
||||
return vec2( t, m );
|
||||
}
|
||||
|
||||
|
||||
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
|
||||
{
|
||||
float res = 1.0;
|
||||
float t = mint;
|
||||
for( int i=0; i<16; i++ )
|
||||
{
|
||||
float h = map( ro + rd*t ).x;
|
||||
res = min( res, 8.0*h/t );
|
||||
t += clamp( h, 0.02, 0.10 );
|
||||
if( h<0.001 || t>tmax ) break;
|
||||
}
|
||||
return clamp( res, 0.0, 1.0 );
|
||||
}
|
||||
|
||||
vec3 calcNormal( in vec3 pos )
|
||||
{
|
||||
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
|
||||
return normalize( e.xyy*map( pos + e.xyy ).x +
|
||||
e.yyx*map( pos + e.yyx ).x +
|
||||
e.yxy*map( pos + e.yxy ).x +
|
||||
e.xxx*map( pos + e.xxx ).x );
|
||||
/*
|
||||
vec3 eps = vec3( 0.0005, 0.0, 0.0 );
|
||||
vec3 nor = vec3(
|
||||
map(pos+eps.xyy).x - map(pos-eps.xyy).x,
|
||||
map(pos+eps.yxy).x - map(pos-eps.yxy).x,
|
||||
map(pos+eps.yyx).x - map(pos-eps.yyx).x );
|
||||
return normalize(nor);
|
||||
*/
|
||||
}
|
||||
|
||||
float calcAO( in vec3 pos, in vec3 nor )
|
||||
{
|
||||
float occ = 0.0;
|
||||
float sca = 1.0;
|
||||
for( int i=0; i<5; i++ )
|
||||
{
|
||||
float hr = 0.01 + 0.12*float(i)/4.0;
|
||||
vec3 aopos = nor * hr + pos;
|
||||
float dd = map( aopos ).x;
|
||||
occ += -(dd-hr)*sca;
|
||||
sca *= 0.95;
|
||||
}
|
||||
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
|
||||
}
|
||||
|
||||
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
|
||||
float checkersGradBox( in vec2 p )
|
||||
{
|
||||
// filter kernel
|
||||
vec2 w = fwidth(p) + 0.001;
|
||||
// analytical integral (box filter)
|
||||
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
|
||||
// xor pattern
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
}
|
||||
|
||||
vec3 render( in vec3 ro, in vec3 rd )
|
||||
{
|
||||
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
|
||||
vec2 res = castRay(ro,rd);
|
||||
float t = res.x;
|
||||
float m = res.y;
|
||||
if( m>-0.5 )
|
||||
{
|
||||
vec3 pos = ro + t*rd;
|
||||
vec3 nor = calcNormal( pos );
|
||||
vec3 ref = reflect( rd, nor );
|
||||
|
||||
// material
|
||||
col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
|
||||
if( m<1.5 )
|
||||
{
|
||||
|
||||
float f = checkersGradBox( 5.0*pos.xz );
|
||||
col = 0.3 + f*vec3(0.1);
|
||||
}
|
||||
|
||||
// lighting
|
||||
float occ = calcAO( pos, nor );
|
||||
vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
|
||||
vec3 hal = normalize( lig-rd );
|
||||
float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
|
||||
float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
|
||||
float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
|
||||
float dom = smoothstep( -0.1, 0.1, ref.y );
|
||||
float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
|
||||
|
||||
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
|
||||
dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
|
||||
|
||||
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
|
||||
dif *
|
||||
(0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
|
||||
|
||||
vec3 lin = vec3(0.0);
|
||||
lin += 1.30*dif*vec3(1.00,0.80,0.55);
|
||||
lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;
|
||||
lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;
|
||||
lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ;
|
||||
lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;
|
||||
col = col*lin;
|
||||
col += 10.00*spe*vec3(1.00,0.90,0.70);
|
||||
|
||||
col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
|
||||
}
|
||||
|
||||
return vec3( clamp(col,0.0,1.0) );
|
||||
}
|
||||
|
||||
mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
|
||||
{
|
||||
vec3 cw = normalize(ta-ro);
|
||||
vec3 cp = vec3(sin(cr), cos(cr),0.0);
|
||||
vec3 cu = normalize( cross(cw,cp) );
|
||||
vec3 cv = normalize( cross(cu,cw) );
|
||||
return mat3( cu, cv, cw );
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 tot = vec3(0.0);
|
||||
#if AA>1
|
||||
for( int m=0; m<AA; m++ )
|
||||
for( int n=0; n<AA; n++ )
|
||||
{
|
||||
// pixel coordinates
|
||||
vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
|
||||
vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y;
|
||||
#else
|
||||
vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
|
||||
#endif
|
||||
|
||||
// RAY: Camera is provided from raylib
|
||||
//vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) );
|
||||
|
||||
vec3 ro = viewEye;
|
||||
vec3 ta = viewCenter;
|
||||
|
||||
// camera-to-world transformation
|
||||
mat3 ca = setCamera( ro, ta, 0.0 );
|
||||
// ray direction
|
||||
vec3 rd = ca * normalize( vec3(p.xy,2.0) );
|
||||
|
||||
// render
|
||||
vec3 col = render( ro, rd );
|
||||
|
||||
// gamma
|
||||
col = pow( col, vec3(0.4545) );
|
||||
|
||||
tot += col;
|
||||
#if AA>1
|
||||
}
|
||||
tot /= float(AA*AA);
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4( tot, 1.0 );
|
||||
}
|
||||
|
|
@ -1,15 +1,13 @@
|
|||
#version 120
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// This shader is based on the basic lighting shader
|
||||
// This only supports one light, which is directional, and it (of course) supports shadows
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying in vec3 fragPosition;
|
||||
varying in vec2 fragTexCoord;
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
//varying in vec4 fragColor;
|
||||
varying in vec3 fragNormal;
|
||||
varying vec3 fragNormal;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#version 330
|
||||
|
||||
// Input fragment attributes (from fragment shader)
|
||||
in vec2 fragTexCoord;
|
||||
in float height;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
|
||||
vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
// interplate between two colors based on height
|
||||
finalColor = mix(darkblue, lightblue, height);
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
|
||||
uniform float time;
|
||||
|
||||
uniform sampler2D perlinNoiseMap;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPosition;
|
||||
out vec2 fragTexCoord;
|
||||
out vec3 fragNormal;
|
||||
out float height;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Calculate animated texture coordinates based on time and vertex position
|
||||
vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
|
||||
|
||||
// Normalize animated texture coordinates to range [0, 1]
|
||||
animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
|
||||
|
||||
// Fetch displacement from the perlin noise map
|
||||
float displacement = texture(perlinNoiseMap, animatedTexCoord).r * 7; // Amplified displacement
|
||||
|
||||
// Displace vertex position
|
||||
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
|
||||
|
||||
// Send vertex attributes to fragment shader
|
||||
fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
|
||||
height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp*vec4(displacedPosition , 1.0);
|
||||
}
|
||||
118
examples/shaders/shaders_vertex_displacement.c
Normal file
118
examples/shaders/shaders_vertex_displacement.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shaders] example - Vertex displacement
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 4.5
|
||||
*
|
||||
* Example contributed by <Alex ZH> (@ZzzhHe) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2023 <Alex ZH> (@ZzzhHe)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "rlgl.h"
|
||||
|
||||
#define RLIGHTS_IMPLEMENTATION
|
||||
#include "rlights.h"
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement");
|
||||
|
||||
// set up camera
|
||||
Camera camera = {0};
|
||||
camera.position = (Vector3) {20.0f, 5.0f, -20.0f};
|
||||
camera.target = (Vector3) {0.0f, 0.0f, 0.0f};
|
||||
camera.up = (Vector3) {0.0f, 1.0f, 0.0f};
|
||||
camera.fovy = 60.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// Load vertex and fragment shaders
|
||||
Shader shader = LoadShader(
|
||||
TextFormat("resources/shaders/glsl%i/vertex_displacement.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/vertex_displacement.fs", GLSL_VERSION));
|
||||
|
||||
// Load perlin noise texture
|
||||
Image perlinNoiseImage = GenImagePerlinNoise(512, 512, 0, 0, 1.0f);
|
||||
Texture perlinNoiseMap = LoadTextureFromImage(perlinNoiseImage);
|
||||
UnloadImage(perlinNoiseImage);
|
||||
|
||||
// Set shader uniform location
|
||||
int perlinNoiseMapLoc = GetShaderLocation(shader, "perlinNoiseMap");
|
||||
rlEnableShader(shader.id);
|
||||
rlActiveTextureSlot(1);
|
||||
rlEnableTexture(perlinNoiseMap.id);
|
||||
rlSetUniformSampler(perlinNoiseMapLoc, 1);
|
||||
|
||||
// Create a plane mesh and model
|
||||
Mesh planeMesh = GenMeshPlane(50, 50, 50, 50);
|
||||
Model planeModel = LoadModelFromMesh(planeMesh);
|
||||
// Set plane model material
|
||||
planeModel.materials[0].shader = shader;
|
||||
|
||||
float time = 0.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_FREE); // Update camera
|
||||
|
||||
time += GetFrameTime(); // Update time variable
|
||||
SetShaderValue(shader, GetShaderLocation(shader, "time"), &time, SHADER_UNIFORM_FLOAT); // Send time value to shader
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
BeginShaderMode(shader);
|
||||
// Draw plane model
|
||||
DrawModel(planeModel, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, (Color) {255, 255, 255, 255});
|
||||
EndShaderMode();
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Vertex displacement", 10, 10, 20, DARKGRAY);
|
||||
DrawFPS(10, 40);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader);
|
||||
UnloadModel(planeModel);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/shaders/shaders_vertex_displacement.png
Normal file
BIN
examples/shaders/shaders_vertex_displacement.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 302 KiB |
|
|
@ -63,11 +63,11 @@ int main(void)
|
|||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", NULL, &startAngle, 0, 720);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", NULL, &endAngle, 0, 720);
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", TextFormat("%.2f", startAngle), &startAngle, 0, 720);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", TextFormat("%.2f", endAngle), &endAngle, 0, 720);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", NULL, &outerRadius, 0, 200);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", NULL, &segments, 0, 100);
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", TextFormat("%.2f", outerRadius), &outerRadius, 0, 200);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", TextFormat("%.2f", segments), &segments, 0, 100);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = truncf(ceilf((endAngle - startAngle) / 90));
|
||||
|
|
|
|||
|
|
@ -66,11 +66,11 @@ int main(void)
|
|||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", NULL, &width, 0, (float)GetScreenWidth() - 300);
|
||||
GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", NULL, &height, 0, (float)GetScreenHeight() - 50);
|
||||
GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", NULL, &roundness, 0.0f, 1.0f);
|
||||
GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", NULL, &lineThick, 0, 20);
|
||||
GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", NULL, &segments, 0, 60);
|
||||
GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", TextFormat("%.2f", width), &width, 0, (float)GetScreenWidth() - 300);
|
||||
GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", TextFormat("%.2f", height), &height, 0, (float)GetScreenHeight() - 50);
|
||||
GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", TextFormat("%.2f", roundness), &roundness, 0.0f, 1.0f);
|
||||
GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", TextFormat("%.2f", lineThick), &lineThick, 0, 20);
|
||||
GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", TextFormat("%.2f", segments), &segments, 0, 60);
|
||||
|
||||
GuiCheckBox((Rectangle){ 640, 320, 20, 20 }, "DrawRoundedRect", &drawRoundedRect);
|
||||
GuiCheckBox((Rectangle){ 640, 350, 20, 20 }, "DrawRoundedLines", &drawRoundedLines);
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@ int main(void)
|
|||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", NULL, &startAngle, -450, 450);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", NULL, &endAngle, -450, 450);
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", TextFormat("%.2f", startAngle), &startAngle, -450, 450);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", TextFormat("%.2f", endAngle), &endAngle, -450, 450);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", NULL, &innerRadius, 0, 100);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", NULL, &outerRadius, 0, 200);
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", TextFormat("%.2f", innerRadius), &innerRadius, 0, 100);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", TextFormat("%.2f", outerRadius), &outerRadius, 0, 200);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", NULL, &segments, 0, 100);
|
||||
GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", TextFormat("%.2f", segments), &segments, 0, 100);
|
||||
|
||||
GuiCheckBox((Rectangle){ 600, 320, 20, 20 }, "Draw Ring", &drawRing);
|
||||
GuiCheckBox((Rectangle){ 600, 350, 20, 20 }, "Draw RingLines", &drawRingLines);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
{
|
||||
"name": "RAYLIB_VERSION",
|
||||
"type": "STRING",
|
||||
"value": "5.5",
|
||||
"value": "5.5-dev",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
|
|
@ -1058,7 +1058,7 @@
|
|||
{
|
||||
"type": "Vector3",
|
||||
"name": "direction",
|
||||
"description": "Ray direction"
|
||||
"description": "Ray direction (normalized)"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -10400,7 +10400,7 @@
|
|||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "size"
|
||||
"name": "scale"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ return {
|
|||
{
|
||||
name = "RAYLIB_VERSION",
|
||||
type = "STRING",
|
||||
value = "5.5",
|
||||
value = "5.5-dev",
|
||||
description = ""
|
||||
},
|
||||
{
|
||||
|
|
@ -1058,7 +1058,7 @@ return {
|
|||
{
|
||||
type = "Vector3",
|
||||
name = "direction",
|
||||
description = "Ray direction"
|
||||
description = "Ray direction (normalized)"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -7230,7 +7230,7 @@ return {
|
|||
{type = "Camera", name = "camera"},
|
||||
{type = "Texture2D", name = "texture"},
|
||||
{type = "Vector3", name = "position"},
|
||||
{type = "float", name = "size"},
|
||||
{type = "float", name = "scale"},
|
||||
{type = "Color", name = "tint"}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Define 004: RAYLIB_VERSION_PATCH
|
|||
Define 005: RAYLIB_VERSION
|
||||
Name: RAYLIB_VERSION
|
||||
Type: STRING
|
||||
Value: "5.5"
|
||||
Value: "5.5-dev"
|
||||
Description:
|
||||
Define 006: __declspec(x)
|
||||
Name: __declspec(x)
|
||||
|
|
@ -473,7 +473,7 @@ Struct 23: Ray (2 fields)
|
|||
Name: Ray
|
||||
Description: Ray, ray for raycasting
|
||||
Field[1]: Vector3 position // Ray position (origin)
|
||||
Field[2]: Vector3 direction // Ray direction
|
||||
Field[2]: Vector3 direction // Ray direction (normalized)
|
||||
Struct 24: RayCollision (4 fields)
|
||||
Name: RayCollision
|
||||
Description: RayCollision, ray hit information
|
||||
|
|
@ -3968,7 +3968,7 @@ Function 466: DrawBillboard() (5 input parameters)
|
|||
Param[1]: camera (type: Camera)
|
||||
Param[2]: texture (type: Texture2D)
|
||||
Param[3]: position (type: Vector3)
|
||||
Param[4]: size (type: float)
|
||||
Param[4]: scale (type: float)
|
||||
Param[5]: tint (type: Color)
|
||||
Function 467: DrawBillboardRec() (6 input parameters)
|
||||
Name: DrawBillboardRec
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="5" desc="" />
|
||||
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="5" desc="" />
|
||||
<Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" />
|
||||
<Define name="RAYLIB_VERSION" type="STRING" value="5.5" desc="" />
|
||||
<Define name="RAYLIB_VERSION" type="STRING" value="5.5-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="" />
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
</Struct>
|
||||
<Struct name="Ray" fieldCount="2" desc="Ray, ray for raycasting">
|
||||
<Field type="Vector3" name="position" desc="Ray position (origin)" />
|
||||
<Field type="Vector3" name="direction" desc="Ray direction" />
|
||||
<Field type="Vector3" name="direction" desc="Ray direction (normalized)" />
|
||||
</Struct>
|
||||
<Struct name="RayCollision" fieldCount="4" desc="RayCollision, ray hit information">
|
||||
<Field type="bool" name="hit" desc="Did the ray hit something?" />
|
||||
|
|
@ -2645,7 +2645,7 @@
|
|||
<Param type="Camera" name="camera" desc="" />
|
||||
<Param type="Texture2D" name="texture" desc="" />
|
||||
<Param type="Vector3" name="position" desc="" />
|
||||
<Param type="float" name="size" desc="" />
|
||||
<Param type="float" name="scale" desc="" />
|
||||
<Param type="Color" name="tint" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawBillboardRec" retType="void" paramCount="6" desc="Draw a billboard texture defined by source">
|
||||
|
|
|
|||
|
|
@ -376,6 +376,9 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\examples\models\models_loading_gltf.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\..\examples\examples.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\raylib\raylib.vcxproj">
|
||||
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ set(raylib_public_headers
|
|||
|
||||
# Sources to be compiled
|
||||
set(raylib_sources
|
||||
raudio.c
|
||||
rcore.c
|
||||
rmodels.c
|
||||
rshapes.c
|
||||
|
|
@ -47,14 +48,12 @@ endif ()
|
|||
# Produces a variable LIBS_PRIVATE that will be used later
|
||||
include(LibraryConfigurations)
|
||||
|
||||
if (USE_AUDIO)
|
||||
if (SUPPORT_MODULE_RAUDIO)
|
||||
MESSAGE(STATUS "Audio Backend: miniaudio")
|
||||
list(APPEND raylib_sources raudio.c)
|
||||
else ()
|
||||
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
||||
MESSAGE(STATUS "Audio Backend: None (-DCUSTOMIZE_BUILD=ON -DSUPPORT_MODULE_RAUDIO=OFF)")
|
||||
endif ()
|
||||
|
||||
|
||||
add_library(raylib ${raylib_sources} ${raylib_public_headers})
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
|
|
@ -71,7 +70,8 @@ endif()
|
|||
if (${PLATFORM} MATCHES "Web")
|
||||
target_link_options(raylib PUBLIC "-sUSE_GLFW=3")
|
||||
if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3")
|
||||
target_link_options(raylib PUBLIC "-sFULL_ES3")
|
||||
target_link_options(raylib PUBLIC "-sMIN_WEBGL_VERSION=2")
|
||||
target_link_options(raylib PUBLIC "-sMAX_WEBGL_VERSION=2")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
.shared = options.shared,
|
||||
.linux_display_backend = options.linux_display_backend,
|
||||
.opengl_version = options.opengl_version,
|
||||
.config = options.config,
|
||||
});
|
||||
const raylib = raylib_dep.artifact("raylib");
|
||||
|
||||
|
|
@ -52,6 +53,36 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
||||
});
|
||||
if (options.config) |config| {
|
||||
const file = try std.fs.path.join(b.allocator, &.{ std.fs.path.dirname(@src().file) orelse ".", "config.h" });
|
||||
defer b.allocator.free(file);
|
||||
const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize));
|
||||
defer b.allocator.free(content);
|
||||
|
||||
var lines = std.mem.split(u8, content, "\n");
|
||||
while (lines.next()) |line| {
|
||||
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||
|
||||
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
|
||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
||||
flag = flag[0..std.mem.indexOf(u8, flag, " ").?]; // Flag is only one word, so capture till space
|
||||
flag = try std.fmt.allocPrint(b.allocator, "-D{s}", .{flag}); // Prepend with -D
|
||||
|
||||
// If user specifies the flag skip it
|
||||
if (std.mem.containsAtLeast(u8, config, 1, flag)) continue;
|
||||
|
||||
// Append default value from config.h to compile flags
|
||||
try raylib_flags_arr.append(b.allocator, flag);
|
||||
}
|
||||
|
||||
// Append config flags supplied by user to compile flags
|
||||
try raylib_flags_arr.append(b.allocator, config);
|
||||
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
}
|
||||
|
||||
if (options.shared) {
|
||||
try raylib_flags_arr.appendSlice(b.allocator, shared_flags);
|
||||
}
|
||||
|
|
@ -117,13 +148,20 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
|
||||
raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
|
||||
raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
|
||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||
|
||||
switch (options.linux_display_backend) {
|
||||
.X11 => {
|
||||
raylib.defineCMacro("_GLFW_X11", null);
|
||||
raylib.linkSystemLibrary("X11");
|
||||
},
|
||||
.Wayland => {
|
||||
}
|
||||
|
||||
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
|
||||
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
|
||||
std.log.err(
|
||||
\\ Wayland may not be installed on the system.
|
||||
\\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
|
||||
, .{});
|
||||
@panic("No Wayland");
|
||||
};
|
||||
raylib.defineCMacro("_GLFW_WAYLAND", null);
|
||||
raylib.linkSystemLibrary("wayland-client");
|
||||
raylib.linkSystemLibrary("wayland-cursor");
|
||||
|
|
@ -139,9 +177,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
waylandGenerate(b, raylib, "fractional-scale-v1.xml", "fractional-scale-v1-client-protocol");
|
||||
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
|
||||
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
|
||||
},
|
||||
}
|
||||
|
||||
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
||||
} else {
|
||||
if (options.opengl_version == .auto) {
|
||||
|
|
@ -253,8 +289,9 @@ pub const Options = struct {
|
|||
raygui: bool = false,
|
||||
platform_drm: bool = false,
|
||||
shared: bool = false,
|
||||
linux_display_backend: LinuxDisplayBackend = .X11,
|
||||
linux_display_backend: LinuxDisplayBackend = .Both,
|
||||
opengl_version: OpenglVersion = .auto,
|
||||
config: ?[]const u8 = null,
|
||||
|
||||
raygui_dependency_name: []const u8 = "raygui",
|
||||
};
|
||||
|
|
@ -284,6 +321,7 @@ pub const OpenglVersion = enum {
|
|||
pub const LinuxDisplayBackend = enum {
|
||||
X11,
|
||||
Wayland,
|
||||
Both,
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
|
|
@ -308,6 +346,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
||||
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
||||
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
||||
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse null,
|
||||
};
|
||||
|
||||
const lib = try compileRaylib(b, target, optimize, options);
|
||||
|
|
|
|||
5873
src/external/RGFW.h
vendored
5873
src/external/RGFW.h
vendored
File diff suppressed because it is too large
Load Diff
10
src/external/jar_xm.h
vendored
10
src/external/jar_xm.h
vendored
|
|
@ -1204,7 +1204,7 @@ static void jar_xm_tone_portamento(jar_xm_context_t* ctx, jar_xm_channel_context
|
|||
}
|
||||
|
||||
static void jar_xm_pitch_slide(jar_xm_context_t* ctx, jar_xm_channel_context_t* ch, float period_offset) {
|
||||
/* Don't ask about the 4.f coefficient. I found mention of it nowhere. Found by ear™. */
|
||||
/* Don't ask about the 4.f coefficient. I found mention of it nowhere. Found by ear. */
|
||||
if(ctx->module.frequency_type == jar_xm_LINEAR_FREQUENCIES) {period_offset *= 4.f; }
|
||||
ch->period += period_offset;
|
||||
jar_xm_CLAMP_DOWN(ch->period);
|
||||
|
|
@ -1507,7 +1507,7 @@ static void jar_xm_handle_note_and_instrument(jar_xm_context_t* ctx, jar_xm_chan
|
|||
jar_xm_volume_slide(ch, ch->fine_volume_slide_param);
|
||||
break;
|
||||
case 0xD: /* EDy: Note delay */
|
||||
/* XXX: figure this out better. EDx triggers the note even when there no note and no instrument. But ED0 acts like like a ghost note, EDx (x ≠ 0) does not. */
|
||||
/* XXX: figure this out better. EDx triggers the note even when there no note and no instrument. But ED0 acts like like a ghost note, EDx (x != 0) does not. */
|
||||
if(s->note == 0 && s->instrument == 0) {
|
||||
unsigned int flags = jar_xm_TRIGGER_KEEP_VOLUME;
|
||||
if(ch->current->effect_param & 0x0F) {
|
||||
|
|
@ -1795,7 +1795,7 @@ static void jar_xm_tick(jar_xm_context_t* ctx) {
|
|||
if(ch->current->effect_param > 0) {
|
||||
char arp_offset = ctx->tempo % 3;
|
||||
switch(arp_offset) {
|
||||
case 2: /* 0 -> x -> 0 -> y -> x -> … */
|
||||
case 2: /* 0 -> x -> 0 -> y -> x -> ... */
|
||||
if(ctx->current_tick == 1) {
|
||||
ch->arp_in_progress = true;
|
||||
ch->arp_note_offset = ch->current->effect_param >> 4;
|
||||
|
|
@ -1803,7 +1803,7 @@ static void jar_xm_tick(jar_xm_context_t* ctx) {
|
|||
break;
|
||||
}
|
||||
/* No break here, this is intended */
|
||||
case 1: /* 0 -> 0 -> y -> x -> … */
|
||||
case 1: /* 0 -> 0 -> y -> x -> ... */
|
||||
if(ctx->current_tick == 0) {
|
||||
ch->arp_in_progress = false;
|
||||
ch->arp_note_offset = 0;
|
||||
|
|
@ -1811,7 +1811,7 @@ static void jar_xm_tick(jar_xm_context_t* ctx) {
|
|||
break;
|
||||
}
|
||||
/* No break here, this is intended */
|
||||
case 0: /* 0 -> y -> x -> … */
|
||||
case 0: /* 0 -> y -> x -> ... */
|
||||
jar_xm_arpeggio(ctx, ch, ch->current->effect_param, ctx->current_tick - arp_offset);
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
2
src/external/miniaudio.h
vendored
2
src/external/miniaudio.h
vendored
|
|
@ -21473,7 +21473,9 @@ static ma_result ma_context_get_MMDevice__wasapi(ma_context* pContext, ma_device
|
|||
MA_ASSERT(pContext != NULL);
|
||||
MA_ASSERT(ppMMDevice != NULL);
|
||||
|
||||
ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
|
||||
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
|
||||
ma_CoUninitialize(pContext);
|
||||
if (FAILED(hr)) {
|
||||
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create IMMDeviceEnumerator.\n");
|
||||
return ma_result_from_HRESULT(hr);
|
||||
|
|
|
|||
|
|
@ -632,6 +632,13 @@ void SetMouseCursor(int cursor)
|
|||
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||
return "";
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1075,6 +1075,12 @@ void SetMouseCursor(int cursor)
|
|||
}
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
return glfwGetKeyName(key, glfwGetKeyScancode(key));
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
@ -1269,6 +1275,11 @@ int InitPlatform(void)
|
|||
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
|
||||
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
|
||||
|
||||
// Disable GlFW auto iconify behaviour
|
||||
// Auto Iconify automatically minimizes (iconifies) the window if the window loses focus
|
||||
// additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window
|
||||
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
||||
|
||||
// Check window creation flags
|
||||
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
|
||||
|
||||
|
|
@ -1448,11 +1459,6 @@ int InitPlatform(void)
|
|||
// No-fullscreen window creation
|
||||
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
|
||||
|
||||
// If we are windowed fullscreen, ensures that window does not minimize when focus is lost.
|
||||
// This hinting code will not work if the user already specified the correct monitor dimensions;
|
||||
// at this point we don't know the monitor's dimensions. (Though, how did the user then?)
|
||||
if (requestWindowedFullscreen) glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
||||
|
||||
// Default to at least one pixel in size, as creation with a zero dimension is not allowed.
|
||||
int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1;
|
||||
int creationHeight = CORE.Window.screen.height != 0 ? CORE.Window.screen.height : 1;
|
||||
|
|
@ -1617,6 +1623,10 @@ int InitPlatform(void)
|
|||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
// Workaround for NetBSD
|
||||
char *glfwPlatform = "X11";
|
||||
#else
|
||||
char *glfwPlatform = "";
|
||||
switch (glfwGetPlatform())
|
||||
{
|
||||
|
|
@ -1625,10 +1635,11 @@ int InitPlatform(void)
|
|||
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
|
||||
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
|
||||
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform);
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully");
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW - %s): Initialized successfully", glfwPlatform);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1664,23 +1675,9 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
|||
if (IsWindowFullscreen()) return;
|
||||
|
||||
// Set current screen size
|
||||
#if defined(__APPLE__)
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
#else
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
|
||||
{
|
||||
Vector2 windowScaleDPI = GetWindowScaleDPI();
|
||||
|
||||
CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x);
|
||||
CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: Postprocessing texture is not scaled to new size
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,19 +8,17 @@
|
|||
* - MacOS (Cocoa)
|
||||
*
|
||||
* LIMITATIONS:
|
||||
* - Limitation 01
|
||||
* - Limitation 02
|
||||
* - TODO
|
||||
*
|
||||
* POSSIBLE IMPROVEMENTS:
|
||||
* - Improvement 01
|
||||
* - Improvement 02
|
||||
* - TODO
|
||||
*
|
||||
* ADDITIONAL NOTES:
|
||||
* - TRACELOG() function is located in raylib [utils] module
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define RCORE_PLATFORM_CUSTOM_FLAG
|
||||
* Custom flag for rcore on target platform -not used-
|
||||
* #define RCORE_PLATFORM_RGFW
|
||||
* Custom flag for rcore on target platform RGFW
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* - RGFW.h (main library): Windowing and inputs management
|
||||
|
|
@ -48,14 +46,14 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifdef GRAPHICS_API_OPENGL_ES2
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#define RGFW_OPENGL_ES2
|
||||
#endif
|
||||
|
||||
void ShowCursor(void);
|
||||
void CloseWindow(void);
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__)
|
||||
#define _INPUT_EVENT_CODES_H
|
||||
#endif
|
||||
|
||||
|
|
@ -73,19 +71,17 @@ void CloseWindow(void);
|
|||
#define _APISETSTRING_
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__)
|
||||
#define Point NSPOINT
|
||||
#define Size NSSIZE
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
||||
#endif
|
||||
|
||||
#include "../external/RGFW.h"
|
||||
|
||||
|
||||
|
||||
#if defined(__WIN32) || defined(__WIN64)
|
||||
#undef DrawText
|
||||
#undef ShowCursor
|
||||
|
|
@ -93,12 +89,13 @@ __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage,
|
|||
#undef Rectangle
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__)
|
||||
#undef Point
|
||||
#undef Size
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h> // Required for: strcmp()
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
|
|
@ -114,6 +111,8 @@ extern CoreData CORE; // Global CORE state context
|
|||
|
||||
static PlatformData platform = { NULL }; // Platform specific
|
||||
|
||||
static bool RGFW_disableCursor = false;
|
||||
|
||||
static const unsigned short keyMappingRGFW[] = {
|
||||
[RGFW_KEY_NULL] = KEY_NULL,
|
||||
[RGFW_Quote] = KEY_APOSTROPHE,
|
||||
|
|
@ -183,7 +182,7 @@ static const unsigned short keyMappingRGFW[] = {
|
|||
[RGFW_u] = KEY_U,
|
||||
[RGFW_v] = KEY_V,
|
||||
[RGFW_w] = KEY_W,
|
||||
[RGFW_x] KEY_X,
|
||||
[RGFW_x] = KEY_X,
|
||||
[RGFW_y] = KEY_Y,
|
||||
[RGFW_z] = KEY_Z,
|
||||
[RGFW_Bracket] = KEY_LEFT_BRACKET,
|
||||
|
|
@ -252,10 +251,10 @@ void ToggleFullscreen(void)
|
|||
// Toggle borderless windowed mode
|
||||
void ToggleBorderlessWindowed(void)
|
||||
{
|
||||
CORE.Window.flags & FLAG_WINDOW_UNDECORATED;
|
||||
|
||||
if (platform.window != NULL)
|
||||
TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform");
|
||||
{
|
||||
RGFW_window_setBorder(platform.window, CORE.Window.flags & FLAG_WINDOW_UNDECORATED);
|
||||
}
|
||||
}
|
||||
|
||||
// Set window state: maximized, if resizable
|
||||
|
|
@ -292,6 +291,7 @@ void SetWindowState(unsigned int flags)
|
|||
}
|
||||
if (flags & FLAG_WINDOW_RESIZABLE)
|
||||
{
|
||||
printf("%i %i\n", platform.window->r.w, platform.window->r.h);
|
||||
RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
||||
RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ void SetWindowState(unsigned int flags)
|
|||
}
|
||||
if (flags & FLAG_WINDOW_UNFOCUSED)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW");
|
||||
}
|
||||
if (flags & FLAG_WINDOW_TOPMOST)
|
||||
{
|
||||
|
|
@ -325,7 +325,7 @@ void SetWindowState(unsigned int flags)
|
|||
}
|
||||
if (flags & FLAG_WINDOW_TRANSPARENT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW");
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT post window creation post window creation is not supported on PLATFORM_DESKTOP_RGFW");
|
||||
}
|
||||
if (flags & FLAG_WINDOW_HIGHDPI)
|
||||
{
|
||||
|
|
@ -333,7 +333,7 @@ void SetWindowState(unsigned int flags)
|
|||
}
|
||||
if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
|
||||
RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
|
||||
}
|
||||
if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
|
||||
{
|
||||
|
|
@ -408,7 +408,7 @@ void ClearWindowState(unsigned int flags)
|
|||
}
|
||||
if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
|
||||
{
|
||||
//SDL_SetWindowGrab(platform.window, SDL_TRUE);
|
||||
RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
|
||||
}
|
||||
if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
|
||||
|
|
@ -483,14 +483,14 @@ void SetWindowIcons(Image *images, int count)
|
|||
// Set title for window
|
||||
void SetWindowTitle(const char *title)
|
||||
{
|
||||
RGFW_window_setName(platform.window, title);
|
||||
RGFW_window_setName(platform.window, (char*)title);
|
||||
CORE.Window.title = title;
|
||||
}
|
||||
|
||||
// Set window position on screen (windowed mode)
|
||||
void SetWindowPosition(int x, int y)
|
||||
{
|
||||
RGFW_window_move(platform.window, RGFW_VECTOR(x, y));
|
||||
RGFW_window_move(platform.window, RGFW_POINT(x, y));
|
||||
}
|
||||
|
||||
// Set monitor for the current window
|
||||
|
|
@ -536,7 +536,9 @@ void SetWindowFocused(void)
|
|||
// Get native window handle
|
||||
void *GetWindowHandle(void)
|
||||
{
|
||||
#ifndef RGFW_WINDOWS
|
||||
#ifdef RGFW_WEBASM
|
||||
return (void*)platform.window->src.ctx;
|
||||
#elif !defined(RGFW_WINDOWS)
|
||||
return (void *)platform.window->src.window;
|
||||
#else
|
||||
return platform.window->src.hwnd;
|
||||
|
|
@ -566,16 +568,15 @@ int GetMonitorCount(void)
|
|||
// Get number of monitors
|
||||
int GetCurrentMonitor(void)
|
||||
{
|
||||
int current = 0;
|
||||
RGFW_monitor *mons = RGFW_getMonitors();
|
||||
RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) current = i;
|
||||
if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) return i;
|
||||
}
|
||||
|
||||
return current;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get selected monitor position
|
||||
|
|
@ -644,7 +645,7 @@ Vector2 GetWindowScaleDPI(void)
|
|||
{
|
||||
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
|
||||
|
||||
return (Vector2){((u32)monitor.scaleX)*platform.window->r.w, ((u32) monitor.scaleX)*platform.window->r.h};
|
||||
return (Vector2){monitor.scaleX, monitor.scaleX};
|
||||
}
|
||||
|
||||
// Set clipboard text content
|
||||
|
|
@ -674,8 +675,6 @@ void HideCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
bool RGFW_disableCursor = false;
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
|
|
@ -692,8 +691,8 @@ void EnableCursor(void)
|
|||
void DisableCursor(void)
|
||||
{
|
||||
RGFW_disableCursor = true;
|
||||
// Set cursor position in the middle
|
||||
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
|
||||
|
||||
RGFW_window_mouseHold(platform.window, RGFW_AREA(CORE.Window.screen.width / 2, CORE.Window.screen.height / 2));
|
||||
|
||||
HideCursor();
|
||||
}
|
||||
|
|
@ -729,7 +728,7 @@ void OpenURL(const char *url)
|
|||
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
||||
else
|
||||
{
|
||||
// TODO:
|
||||
// TODO: Open URL implementation
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -747,7 +746,7 @@ int SetGamepadMappings(const char *mappings)
|
|||
// Set mouse position XY
|
||||
void SetMousePosition(int x, int y)
|
||||
{
|
||||
RGFW_window_moveMouse(platform.window, RGFW_VECTOR(x, y));
|
||||
RGFW_window_moveMouse(platform.window, RGFW_POINT(x, y));
|
||||
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
|
||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||
}
|
||||
|
|
@ -758,8 +757,67 @@ void SetMouseCursor(int cursor)
|
|||
RGFW_window_setMouseStandard(platform.window, cursor);
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||
return "";
|
||||
}
|
||||
|
||||
static KeyboardKey ConvertScancodeToKey(u32 keycode);
|
||||
|
||||
// TODO: Review function to avoid duplicate with RSGL
|
||||
char RSGL_keystrToChar(const char *str)
|
||||
{
|
||||
if (str[1] == 0) return str[0];
|
||||
|
||||
static const char *map[] = {
|
||||
"asciitilde", "`",
|
||||
"grave", "~",
|
||||
"exclam", "!",
|
||||
"at", "@",
|
||||
"numbersign", "#",
|
||||
"dollar", "$",
|
||||
"percent", "%%",
|
||||
"asciicircum", "^",
|
||||
"ampersand", "&",
|
||||
"asterisk", "*",
|
||||
"parenleft", "(",
|
||||
"parenright", ")",
|
||||
"underscore", "_",
|
||||
"minus", "-",
|
||||
"plus", "+",
|
||||
"equal", "=",
|
||||
"braceleft", "{",
|
||||
"bracketleft", "[",
|
||||
"bracketright", "]",
|
||||
"braceright", "}",
|
||||
"colon", ":",
|
||||
"semicolon", ";",
|
||||
"quotedbl", "\"",
|
||||
"apostrophe", "'",
|
||||
"bar", "|",
|
||||
"backslash", "\'",
|
||||
"less", "<",
|
||||
"comma", ",",
|
||||
"greater", ">",
|
||||
"period", ".",
|
||||
"question", "?",
|
||||
"slash", "/",
|
||||
"space", " ",
|
||||
"Return", "\n",
|
||||
"Enter", "\n",
|
||||
"enter", "\n",
|
||||
};
|
||||
|
||||
for (unsigned char i = 0; i < (sizeof(map)/sizeof(char *)); i += 2)
|
||||
{
|
||||
if (strcmp(map[i], str) == 0) return *map[i + 1];
|
||||
}
|
||||
|
||||
return '\0';
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
@ -812,8 +870,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];
|
||||
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
|
||||
|
||||
// Poll input events for current platform
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -822,12 +879,13 @@ void PollInputEvents(void)
|
|||
|
||||
#define RGFW_HOLD_MOUSE (1L<<2)
|
||||
#if defined(RGFW_X11) //|| defined(RGFW_MACOS)
|
||||
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE)
|
||||
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
||||
{
|
||||
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
|
||||
CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -924,7 +982,7 @@ void PollInputEvents(void)
|
|||
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
|
||||
{
|
||||
// Add character (codepoint) to the queue
|
||||
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RGFW_keystrToChar(event->keyName);
|
||||
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RSGL_keystrToChar(event->keyName);
|
||||
CORE.Input.Keyboard.charPressedQueueCount++;
|
||||
}
|
||||
} break;
|
||||
|
|
@ -974,17 +1032,17 @@ void PollInputEvents(void)
|
|||
} break;
|
||||
case RGFW_mousePosChanged:
|
||||
{
|
||||
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE)
|
||||
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
||||
{
|
||||
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
|
||||
|
||||
if ((event->point.x - (platform.window->r.w/2))*2)
|
||||
if (event->point.x)
|
||||
CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
|
||||
if ((event->point.y - (platform.window->r.h/2))*2)
|
||||
if (event->point.y)
|
||||
CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
|
||||
|
||||
CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w/2))*2;
|
||||
CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h/2))*2;
|
||||
CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
|
||||
CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1109,6 +1167,7 @@ void PollInputEvents(void)
|
|||
int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
|
||||
int pressed = (value > 0.1f);
|
||||
CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed;
|
||||
|
||||
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
|
||||
else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
|
||||
}
|
||||
|
|
@ -1147,8 +1206,6 @@ void PollInputEvents(void)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (RGFW_disableCursor && platform.window->event.inFocus) RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
|
||||
//-----------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
|
@ -1200,8 +1257,17 @@ int InitPlatform(void)
|
|||
|
||||
platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags);
|
||||
|
||||
if (CORE.Window.flags & FLAG_VSYNC_HINT)
|
||||
RGFW_window_swapInterval(platform.window, 1);
|
||||
RGFW_area screenSize = RGFW_getScreenSize();
|
||||
CORE.Window.display.width = screenSize.w;
|
||||
CORE.Window.display.height = screenSize.h;
|
||||
/*
|
||||
I think this is needed by Raylib now ?
|
||||
If so, rcore_destkop_sdl should be updated too
|
||||
*/
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
|
||||
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
|
||||
|
||||
RGFW_window_makeCurrent(platform.window);
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ typedef struct {
|
|||
SDL_Window *window;
|
||||
SDL_GLContext glContext;
|
||||
|
||||
SDL_Joystick *gamepad[MAX_GAMEPADS];
|
||||
SDL_GameController *gamepad[MAX_GAMEPADS];
|
||||
SDL_Cursor *cursor;
|
||||
bool cursorRelative;
|
||||
} PlatformData;
|
||||
|
|
@ -944,7 +944,7 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
|
|||
|
||||
if (IsGamepadAvailable(gamepad))
|
||||
{
|
||||
SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));
|
||||
SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -966,6 +966,12 @@ void SetMouseCursor(int cursor)
|
|||
CORE.Input.Mouse.cursor = cursor;
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
return SDL_GetKeyName(key);
|
||||
}
|
||||
|
||||
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
|
||||
{
|
||||
CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
|
||||
|
|
@ -1245,15 +1251,15 @@ void PollInputEvents(void)
|
|||
|
||||
if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))
|
||||
{
|
||||
platform.gamepad[jid] = SDL_JoystickOpen(jid);
|
||||
platform.gamepad[jid] = SDL_GameControllerOpen(jid);
|
||||
|
||||
if (platform.gamepad[jid])
|
||||
{
|
||||
CORE.Input.Gamepad.ready[jid] = true;
|
||||
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(platform.gamepad[jid]);
|
||||
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[jid]));
|
||||
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
||||
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
||||
strncpy(CORE.Input.Gamepad.name[jid], SDL_JoystickName(platform.gamepad[jid]), 63);
|
||||
strncpy(CORE.Input.Gamepad.name[jid], SDL_GameControllerNameForIndex(jid), 63);
|
||||
CORE.Input.Gamepad.name[jid][63] = '\0';
|
||||
}
|
||||
else
|
||||
|
|
@ -1266,15 +1272,15 @@ void PollInputEvents(void)
|
|||
{
|
||||
int jid = event.jdevice.which;
|
||||
|
||||
if (jid == SDL_JoystickInstanceID(platform.gamepad[jid]))
|
||||
if (jid == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid])))
|
||||
{
|
||||
SDL_JoystickClose(platform.gamepad[jid]);
|
||||
platform.gamepad[jid] = SDL_JoystickOpen(0);
|
||||
SDL_GameControllerClose(platform.gamepad[jid]);
|
||||
platform.gamepad[jid] = SDL_GameControllerOpen(0);
|
||||
CORE.Input.Gamepad.ready[jid] = false;
|
||||
memset(CORE.Input.Gamepad.name[jid], 0, 64);
|
||||
}
|
||||
} break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
{
|
||||
int button = -1;
|
||||
|
||||
|
|
@ -1308,7 +1314,7 @@ void PollInputEvents(void)
|
|||
CORE.Input.Gamepad.lastButtonPressed = button;
|
||||
}
|
||||
} break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
{
|
||||
int button = -1;
|
||||
|
||||
|
|
@ -1342,7 +1348,7 @@ void PollInputEvents(void)
|
|||
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
|
||||
}
|
||||
} break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
int axis = -1;
|
||||
|
||||
|
|
@ -1548,15 +1554,15 @@ int InitPlatform(void)
|
|||
// Initialize gamepads
|
||||
for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
|
||||
{
|
||||
platform.gamepad[i] = SDL_JoystickOpen(i);
|
||||
platform.gamepad[i] = SDL_GameControllerOpen(i);
|
||||
|
||||
if (platform.gamepad[i])
|
||||
{
|
||||
CORE.Input.Gamepad.ready[i] = true;
|
||||
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(platform.gamepad[i]);
|
||||
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
|
||||
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
||||
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
||||
strncpy(CORE.Input.Gamepad.name[i], SDL_JoystickName(platform.gamepad[i]), 63);
|
||||
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), 63);
|
||||
CORE.Input.Gamepad.name[i][63] = '\0';
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
|
||||
|
|
|
|||
|
|
@ -628,6 +628,13 @@ void SetMouseCursor(int cursor)
|
|||
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||
return "";
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -384,6 +384,13 @@ void SetMouseCursor(int cursor)
|
|||
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||
return "";
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -884,6 +884,13 @@ void SetMouseCursor(int cursor)
|
|||
}
|
||||
}
|
||||
|
||||
// Get physical key name.
|
||||
const char *GetKeyName(int key)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||
return "";
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v5.5-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
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
#define RAYLIB_VERSION_MAJOR 5
|
||||
#define RAYLIB_VERSION_MINOR 5
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "5.5"
|
||||
#define RAYLIB_VERSION "5.5-dev"
|
||||
|
||||
// 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
|
||||
|
|
@ -421,7 +421,7 @@ typedef struct ModelAnimation {
|
|||
// Ray, ray for raycasting
|
||||
typedef struct Ray {
|
||||
Vector3 position; // Ray position (origin)
|
||||
Vector3 direction; // Ray direction
|
||||
Vector3 direction; // Ray direction (normalized)
|
||||
} Ray;
|
||||
|
||||
// RayCollision, ray hit information
|
||||
|
|
@ -1546,7 +1546,7 @@ RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, floa
|
|||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
||||
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
|
||||
|
||||
|
|
|
|||
|
|
@ -2549,9 +2549,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||
|
||||
// Extract scale
|
||||
const float det = a*A + b*B + c*C;
|
||||
float scalex = Vector3Length((Vector3){ a, b, c });
|
||||
float scaley = Vector3Length((Vector3){ d, e, f });
|
||||
float scalez = Vector3Length((Vector3){ g, h, i });
|
||||
Vector3 abc = { a, b, c };
|
||||
Vector3 def = { d, e, f };
|
||||
Vector3 ghi = { g, h, i };
|
||||
|
||||
float scalex = Vector3Length(abc);
|
||||
float scaley = Vector3Length(def);
|
||||
float scalez = Vector3Length(ghi);
|
||||
Vector3 s = { scalex, scaley, scalez };
|
||||
|
||||
if (det < 0) s = Vector3Negate(s);
|
||||
|
|
|
|||
27
src/rcore.c
27
src/rcore.c
|
|
@ -668,21 +668,15 @@ void InitWindow(int width, int height, const char *title)
|
|||
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
|
||||
#endif
|
||||
#endif
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
|
||||
{
|
||||
// Set default font texture filter for HighDPI (blurry)
|
||||
// RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR);
|
||||
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CORE.Time.frameCounter = 0;
|
||||
CORE.Window.shouldClose = false;
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
|
||||
}
|
||||
|
||||
// Close window and unload OpenGL context
|
||||
|
|
@ -2958,10 +2952,14 @@ int GetGamepadAxisCount(int gamepad)
|
|||
// Get axis movement vector for a gamepad
|
||||
float GetGamepadAxisMovement(int gamepad, int axis)
|
||||
{
|
||||
float value = 0;
|
||||
float value = (axis == GAMEPAD_AXIS_LEFT_TRIGGER || axis == GAMEPAD_AXIS_RIGHT_TRIGGER)? -1.0f : 0.0f;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS) &&
|
||||
(fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) > 0.1f)) value = CORE.Input.Gamepad.axisState[gamepad][axis]; // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) {
|
||||
float movement = value < 0.0f ? CORE.Input.Gamepad.axisState[gamepad][axis] : fabs(CORE.Input.Gamepad.axisState[gamepad][axis]);
|
||||
|
||||
// 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
|
||||
if (movement > value + 0.1f) value = CORE.Input.Gamepad.axisState[gamepad][axis];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -3482,7 +3480,7 @@ static void RecordAutomationEvent(void)
|
|||
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
||||
currentEventList->events[currentEventList->count].type = INPUT_MOUSE_WHEEL_MOTION;
|
||||
currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x;
|
||||
currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;;
|
||||
currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;
|
||||
currentEventList->events[currentEventList->count].params[2] = 0;
|
||||
|
||||
TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_WHEEL_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
||||
|
|
@ -3605,7 +3603,8 @@ static void RecordAutomationEvent(void)
|
|||
for (int axis = 0; axis < MAX_GAMEPAD_AXIS; axis++)
|
||||
{
|
||||
// Event type: INPUT_GAMEPAD_AXIS_MOTION
|
||||
if (CORE.Input.Gamepad.axisState[gamepad][axis] > 0.1f)
|
||||
float defaultMovement = (axis == GAMEPAD_AXIS_LEFT_TRIGGER || axis == GAMEPAD_AXIS_RIGHT_TRIGGER)? -1.0f : 0.0f;
|
||||
if (GetGamepadAxisMovement(gamepad, axis) != defaultMovement)
|
||||
{
|
||||
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
||||
currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_AXIS_MOTION;
|
||||
|
|
|
|||
41
src/rlgl.h
41
src/rlgl.h
|
|
@ -844,9 +844,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP,
|
||||
// NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms,
|
||||
// in that case, functions are loaded from a custom glad for OpenGL ES 2.0
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
||||
#if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
|
||||
#define GLAD_GLES2_IMPLEMENTATION
|
||||
#include "external/glad_gles2.h"
|
||||
#else
|
||||
|
|
@ -2390,7 +2390,7 @@ void rlLoadExtensions(void *loader)
|
|||
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
||||
#if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
|
||||
// TODO: Support GLAD loader for OpenGL ES 3.0
|
||||
if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions");
|
||||
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully");
|
||||
|
|
@ -4397,11 +4397,11 @@ void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSi
|
|||
// Get SSBO buffer size
|
||||
unsigned int rlGetShaderBufferSize(unsigned int id)
|
||||
{
|
||||
long long size = 0;
|
||||
GLint64 size = 0;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_43)
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
|
||||
glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size);
|
||||
glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
|
||||
#endif
|
||||
|
||||
return (size > 0)? (unsigned int)size : 0;
|
||||
|
|
@ -4756,7 +4756,16 @@ static void rlLoadShaderDefault(void)
|
|||
"out vec2 fragTexCoord; \n"
|
||||
"out vec4 fragColor; \n"
|
||||
#endif
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES3)
|
||||
"#version 300 es \n"
|
||||
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2) (on some browsers)
|
||||
"in vec3 vertexPosition; \n"
|
||||
"in vec2 vertexTexCoord; \n"
|
||||
"in vec4 vertexColor; \n"
|
||||
"out vec2 fragTexCoord; \n"
|
||||
"out vec4 fragColor; \n"
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
"#version 100 \n"
|
||||
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers)
|
||||
"attribute vec3 vertexPosition; \n"
|
||||
|
|
@ -4765,6 +4774,7 @@ static void rlLoadShaderDefault(void)
|
|||
"varying vec2 fragTexCoord; \n"
|
||||
"varying vec4 fragColor; \n"
|
||||
#endif
|
||||
|
||||
"uniform mat4 mvp; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
|
|
@ -4799,7 +4809,21 @@ static void rlLoadShaderDefault(void)
|
|||
" finalColor = texelColor*colDiffuse*fragColor; \n"
|
||||
"} \n";
|
||||
#endif
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES3)
|
||||
"#version 300 es \n"
|
||||
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2)
|
||||
"in vec2 fragTexCoord; \n"
|
||||
"in vec4 fragColor; \n"
|
||||
"out vec4 finalColor; \n"
|
||||
"uniform sampler2D texture0; \n"
|
||||
"uniform vec4 colDiffuse; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
|
||||
" finalColor = texelColor*colDiffuse*fragColor; \n"
|
||||
"} \n";
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
"#version 100 \n"
|
||||
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
|
||||
"varying vec2 fragTexCoord; \n"
|
||||
|
|
@ -4969,7 +4993,8 @@ static int rlGetPixelDataSize(int width, int height, int format)
|
|||
default: break;
|
||||
}
|
||||
|
||||
dataSize = width*height*bpp/8; // Total data size in bytes
|
||||
double bytesPerPixel = (double)bpp/8.0;
|
||||
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
||||
|
||||
// Most compressed formats works on 4x4 blocks,
|
||||
// if texture is smaller, minimum dataSize is 8 or 16
|
||||
|
|
|
|||
164
src/rmodels.c
164
src/rmodels.c
|
|
@ -1072,16 +1072,10 @@ void DrawGrid(int slices, float spacing)
|
|||
if (i == 0)
|
||||
{
|
||||
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||
}
|
||||
|
||||
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
|
||||
|
|
@ -3638,11 +3632,11 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
|
|||
}
|
||||
|
||||
// Draw a billboard
|
||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint)
|
||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint)
|
||||
{
|
||||
Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
|
||||
|
||||
DrawBillboardRec(camera, texture, source, position, (Vector2){ size, size }, tint);
|
||||
DrawBillboardRec(camera, texture, source, position, (Vector2) { scale*fabsf((float)source.width/source.height), scale }, tint);
|
||||
}
|
||||
|
||||
// Draw a billboard (part of a texture defined by a rectangle)
|
||||
|
|
@ -3651,116 +3645,82 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
|
|||
// NOTE: Billboard locked on axis-Y
|
||||
Vector3 up = { 0.0f, 1.0f, 0.0f };
|
||||
|
||||
DrawBillboardPro(camera, texture, source, position, up, size, Vector2Zero(), 0.0f, tint);
|
||||
DrawBillboardPro(camera, texture, source, position, up, size, Vector2Scale(size, 0.5), 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a billboard with additional parameters
|
||||
// NOTE: Size defines the destination rectangle size, stretching the source texture as required
|
||||
void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint)
|
||||
{
|
||||
// NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width
|
||||
Vector2 sizeRatio = { size.x*fabsf((float)source.width/source.height), size.y };
|
||||
|
||||
// Compute the up vector and the right vector
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
Vector3 right = { matView.m0, matView.m4, matView.m8 };
|
||||
//Vector3 up = { matView.m1, matView.m5, matView.m9 };
|
||||
right = Vector3Scale(right, size.x);
|
||||
up = Vector3Scale(up, size.y);
|
||||
|
||||
Vector3 rightScaled = Vector3Scale(right, sizeRatio.x/2);
|
||||
Vector3 upScaled = Vector3Scale(up, sizeRatio.y/2);
|
||||
|
||||
Vector3 p1 = Vector3Add(rightScaled, upScaled);
|
||||
Vector3 p2 = Vector3Subtract(rightScaled, upScaled);
|
||||
|
||||
Vector3 topLeft = Vector3Scale(p2, -1);
|
||||
Vector3 topRight = p1;
|
||||
Vector3 bottomRight = p2;
|
||||
Vector3 bottomLeft = Vector3Scale(p1, -1);
|
||||
|
||||
if (rotation != 0.0f)
|
||||
// Flip the content of the billboard while maintaining the counterclockwise edge rendering order
|
||||
if (size.x < 0.0f)
|
||||
{
|
||||
float sinRotation = sinf(rotation*DEG2RAD);
|
||||
float cosRotation = cosf(rotation*DEG2RAD);
|
||||
|
||||
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture
|
||||
float rotateAboutX = sizeRatio.x*origin.x/2;
|
||||
float rotateAboutY = sizeRatio.y*origin.y/2;
|
||||
|
||||
float xtvalue, ytvalue;
|
||||
float rotatedX, rotatedY;
|
||||
|
||||
xtvalue = Vector3DotProduct(right, topLeft) - rotateAboutX; // Project points to x and y coordinates on the billboard plane
|
||||
ytvalue = Vector3DotProduct(up, topLeft) - rotateAboutY;
|
||||
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; // Rotate about the point origin
|
||||
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
|
||||
topLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); // Translate back to cartesian coordinates
|
||||
|
||||
xtvalue = Vector3DotProduct(right, topRight) - rotateAboutX;
|
||||
ytvalue = Vector3DotProduct(up, topRight) - rotateAboutY;
|
||||
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
|
||||
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
|
||||
topRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
|
||||
|
||||
xtvalue = Vector3DotProduct(right, bottomRight) - rotateAboutX;
|
||||
ytvalue = Vector3DotProduct(up, bottomRight) - rotateAboutY;
|
||||
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
|
||||
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
|
||||
bottomRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
|
||||
|
||||
xtvalue = Vector3DotProduct(right, bottomLeft)-rotateAboutX;
|
||||
ytvalue = Vector3DotProduct(up, bottomLeft)-rotateAboutY;
|
||||
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
|
||||
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
|
||||
bottomLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
|
||||
source.x += size.x;
|
||||
source.width *= -1.0;
|
||||
right = Vector3Negate(right);
|
||||
origin.x *= -1.0f;
|
||||
}
|
||||
if (size.y < 0.0f)
|
||||
{
|
||||
source.y += size.y;
|
||||
source.height *= -1.0;
|
||||
up = Vector3Negate(up);
|
||||
origin.y *= -1.0f;
|
||||
}
|
||||
|
||||
// Translate points to the draw center (position)
|
||||
topLeft = Vector3Add(topLeft, position);
|
||||
topRight = Vector3Add(topRight, position);
|
||||
bottomRight = Vector3Add(bottomRight, position);
|
||||
bottomLeft = Vector3Add(bottomLeft, position);
|
||||
// Draw the texture region described by source on the following rectangle in 3D space:
|
||||
//
|
||||
// size.x <--.
|
||||
// 3 ^---------------------------+ 2 \ rotation
|
||||
// | | /
|
||||
// | |
|
||||
// | origin.x position |
|
||||
// up |.............. | size.y
|
||||
// | . |
|
||||
// | . origin.y |
|
||||
// | . |
|
||||
// 0 +---------------------------> 1
|
||||
// right
|
||||
Vector3 forward;
|
||||
if (rotation != 0.0) forward = Vector3CrossProduct(right, up);
|
||||
|
||||
Vector3 origin3D = Vector3Add(Vector3Scale(Vector3Normalize(right), origin.x), Vector3Scale(Vector3Normalize(up), origin.y));
|
||||
|
||||
Vector3 points[4];
|
||||
points[0] = Vector3Zero();
|
||||
points[1] = right;
|
||||
points[2] = Vector3Add(up, right);
|
||||
points[3] = up;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
points[i] = Vector3Subtract(points[i], origin3D);
|
||||
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation * DEG2RAD);
|
||||
points[i] = Vector3Add(points[i], position);
|
||||
}
|
||||
|
||||
Vector2 texcoords[4];
|
||||
texcoords[0] = (Vector2) { (float)source.x/texture.width, (float)(source.y + source.height)/texture.height };
|
||||
texcoords[1] = (Vector2) { (float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height };
|
||||
texcoords[2] = (Vector2) { (float)(source.x + source.width)/texture.width, (float)source.y/texture.height };
|
||||
texcoords[3] = (Vector2) { (float)source.x/texture.width, (float)source.y/texture.height };
|
||||
|
||||
rlSetTexture(texture.id);
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
|
||||
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||
|
||||
if (sizeRatio.x*sizeRatio.y >= 0.0f)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// Bottom-left corner for texture and quad
|
||||
rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height);
|
||||
rlVertex3f(topLeft.x, topLeft.y, topLeft.z);
|
||||
|
||||
// Top-left corner for texture and quad
|
||||
rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height);
|
||||
rlVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
|
||||
|
||||
// Top-right corner for texture and quad
|
||||
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height);
|
||||
rlVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
|
||||
|
||||
// Bottom-right corner for texture and quad
|
||||
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height);
|
||||
rlVertex3f(topRight.x, topRight.y, topRight.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reverse vertex order if the size has only one negative dimension
|
||||
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height);
|
||||
rlVertex3f(topRight.x, topRight.y, topRight.z);
|
||||
|
||||
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height);
|
||||
rlVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
|
||||
|
||||
rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height);
|
||||
rlVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
|
||||
|
||||
rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height);
|
||||
rlVertex3f(topLeft.x, topLeft.y, topLeft.z);
|
||||
rlTexCoord2f(texcoords[i].x, texcoords[i].y);
|
||||
rlVertex3f(points[i].x, points[i].y, points[i].z);
|
||||
}
|
||||
|
||||
rlEnd();
|
||||
|
||||
rlSetTexture(0);
|
||||
}
|
||||
|
||||
|
|
@ -5206,7 +5166,7 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
// Transform the vertices
|
||||
float *vertices = model.meshes[meshIndex].vertices;
|
||||
for (int k = 0; k < attribute->count; k++)
|
||||
for (unsigned int k = 0; k < attribute->count; k++)
|
||||
{
|
||||
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
|
||||
vertices[3*k] = vt.x;
|
||||
|
|
@ -5230,7 +5190,7 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
// Transform the normals
|
||||
float *normals = model.meshes[meshIndex].normals;
|
||||
for (int k = 0; k < attribute->count; k++)
|
||||
for (unsigned int k = 0; k < attribute->count; k++)
|
||||
{
|
||||
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
|
||||
normals[3*k] = nt.x;
|
||||
|
|
@ -5254,7 +5214,7 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
// Transform the tangents
|
||||
float *tangents = model.meshes[meshIndex].tangents;
|
||||
for (int k = 0; k < attribute->count; k++)
|
||||
for (unsigned int k = 0; k < attribute->count; k++)
|
||||
{
|
||||
Vector3 tt = Vector3Transform((Vector3){ tangents[3*k], tangents[3*k+1], tangents[3*k+2] }, worldMatrix);
|
||||
tangents[3*k] = tt.x;
|
||||
|
|
|
|||
|
|
@ -2172,7 +2172,9 @@ bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius)
|
|||
{
|
||||
bool collision = false;
|
||||
|
||||
collision = CheckCollisionCircles(point, 0, center, radius);
|
||||
float distanceSquared = (point.x - center.x)*(point.x - center.x) + (point.y - center.y)*(point.y - center.y);
|
||||
|
||||
if (distanceSquared <= radius*radius) collision = true;
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,7 +503,16 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
|||
Image image = { 0 };
|
||||
|
||||
// Security check for input data
|
||||
if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image;
|
||||
if ((fileData == NULL) || (dataSize == 0))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "IMAGE: Invalid file data");
|
||||
return image;
|
||||
}
|
||||
if (fileType == NULL)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "IMAGE: Missing file extension");
|
||||
return image;
|
||||
}
|
||||
|
||||
if ((false)
|
||||
#if defined(SUPPORT_FILEFORMAT_PNG)
|
||||
|
|
@ -1213,6 +1222,7 @@ Image GenImageText(int width, int height, const char *text)
|
|||
{
|
||||
Image image = { 0 };
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT)
|
||||
int textLength = TextLength(text);
|
||||
int imageViewSize = width*height;
|
||||
|
||||
|
|
@ -1223,6 +1233,10 @@ Image GenImageText(int width, int height, const char *text)
|
|||
image.mipmaps = 1;
|
||||
|
||||
memcpy(image.data, text, (textLength > imageViewSize)? imageViewSize : textLength);
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "IMAGE: GenImageText() requires module: rtext");
|
||||
image = GenImageColor(width, height, BLACK); // Generating placeholder black image rectangle
|
||||
#endif
|
||||
|
||||
return image;
|
||||
}
|
||||
|
|
@ -3658,7 +3672,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
|
|||
{
|
||||
// Line is more horizontal
|
||||
// Calculate half the width of the line
|
||||
int wy = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dx));
|
||||
int wy = (thick - 1)*(int)sqrtf((float)(dx*dx + dy*dy))/(2*abs(dx));
|
||||
|
||||
// Draw additional lines above and below the main line
|
||||
for (int i = 1; i <= wy; i++)
|
||||
|
|
@ -3671,7 +3685,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
|
|||
{
|
||||
// Line is more vertical or perfectly horizontal
|
||||
// Calculate half the width of the line
|
||||
int wx = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dy));
|
||||
int wx = (thick - 1)*(int)sqrtf((float)(dx*dx + dy*dy))/(2*abs(dy));
|
||||
|
||||
// Draw additional lines to the left and right of the main line
|
||||
for (int i = 1; i <= wx; i++)
|
||||
|
|
@ -5389,7 +5403,8 @@ int GetPixelDataSize(int width, int height, int format)
|
|||
default: break;
|
||||
}
|
||||
|
||||
dataSize = width*height*bpp/8; // Total data size in bytes
|
||||
double bytesPerPixel = (double)bpp/8.0;
|
||||
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
||||
|
||||
// Most compressed formats works on 4x4 blocks,
|
||||
// if texture is smaller, minimum dataSize is 8 or 16
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user