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

This commit is contained in:
Jeffery Myers 2024-08-08 11:01:31 -07:00
commit c8d907ed89
48 changed files with 4932 additions and 3239 deletions

View File

@ -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) |

View File

@ -20,7 +20,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE)
[![Discord Members](https://img.shields.io/discord/426912293134270465.svg?label=Discord&logo=discord)](https://discord.gg/raylib)
[![Subreddit Subscribers](https://img.shields.io/reddit/subreddit-subscribers/raylib?label=reddit%20r%2Fraylib&logo=reddit)](https://www.reddit.com/r/raylib/)
[![Reddit Static Badge](https://img.shields.io/badge/-r%2Fraylib-red?style=flat&logo=reddit&label=reddit)](https://www.reddit.com/r/raylib/)
[![Youtube Subscribers](https://img.shields.io/youtube/channel/subscribers/UC8WIBkhYb5sBNqXO1mZ7WSQ?style=flat&label=Youtube&logo=youtube)](https://www.youtube.com/c/raylib)
[![Twitch Status](https://img.shields.io/twitch/status/raysan5?style=flat&label=Twitch&logo=twitch)](https://www.twitch.tv/raysan5)

View File

@ -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})

View File

@ -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 \

View File

@ -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 \

View File

@ -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!

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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
//------------------------------------------------------------------

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View 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 );
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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",

View File

@ -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"}
}
},

View File

@ -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

View File

@ -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">

View File

@ -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>

View File

@ -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()

View File

@ -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,31 +148,36 @@ 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 => {
raylib.defineCMacro("_GLFW_WAYLAND", null);
raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("wayland-cursor");
raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon");
raylib.addIncludePath(b.path("src"));
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-v1-client-protocol");
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");
},
}
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");
raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon");
raylib.addIncludePath(b.path("src"));
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-v1-client-protocol");
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);

6561
src/external/RGFW.h vendored

File diff suppressed because it is too large Load Diff

10
src/external/jar_xm.h vendored
View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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,18 +1623,23 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory();
//----------------------------------------------------------------------------
char* glfwPlatform = "";
#if defined(__NetBSD__)
// Workaround for NetBSD
char *glfwPlatform = "X11";
#else
char *glfwPlatform = "";
switch (glfwGetPlatform())
{
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break;
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break;
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; 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
}

View File

@ -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,57 +46,56 @@
*
**********************************************************************************************/
#ifdef GRAPHICS_API_OPENGL_ES2
#define RGFW_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_ES2)
#define RGFW_OPENGL_ES2
#endif
void ShowCursor(void);
void CloseWindow(void);
#ifdef __linux__
#define _INPUT_EVENT_CODES_H
#if defined(__linux__)
#define _INPUT_EVENT_CODES_H
#endif
#if defined(__unix__) || defined(__linux__)
#define _XTYPEDEF_FONT
#define _XTYPEDEF_FONT
#endif
#define RGFW_IMPLEMENTATION
#if defined(__WIN32) || defined(__WIN64)
#define WIN32_LEAN_AND_MEAN
#define Rectangle rectangle_win32
#define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor
#define _APISETSTRING_
#define WIN32_LEAN_AND_MEAN
#define Rectangle rectangle_win32
#define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor
#define _APISETSTRING_
#endif
#ifdef __APPLE__
#define Point NSPOINT
#define Size NSSIZE
#if defined(__APPLE__)
#define Point NSPOINT
#define Size NSSIZE
#endif
#ifdef _MSC_VER
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
#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
#undef CloseWindow
#undef Rectangle
#undef DrawText
#undef ShowCursor
#undef CloseWindow
#undef Rectangle
#endif
#ifdef __APPLE__
#undef Point
#undef Size
#if defined(__APPLE__)
#undef Point
#undef Size
#endif
#include <stdbool.h>
#include <string.h> // Required for: strcmp()
//----------------------------------------------------------------------------------
// Types and Structures Definition
@ -112,7 +109,9 @@ typedef struct {
//----------------------------------------------------------------------------------
extern CoreData CORE; // Global CORE state context
static PlatformData platform = { NULL }; // Platform specific
static PlatformData platform = { NULL }; // Platform specific
static bool RGFW_disableCursor = false;
static const unsigned short keyMappingRGFW[] = {
[RGFW_KEY_NULL] = KEY_NULL,
@ -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,15 +879,16 @@ 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
#endif
while (RGFW_window_checkEvent(platform.window))
{
@ -847,7 +905,7 @@ void PollInputEvents(void)
}
}
RGFW_Event* event = &platform.window->event;
RGFW_Event *event = &platform.window->event;
// All input events can be processed after polling
switch (event->type)
@ -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);
@ -1266,12 +1332,12 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory();
//----------------------------------------------------------------------------
#ifdef RGFW_X11
#ifdef RGFW_X11
for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
{
RGFW_registerJoystick(platform.window, i);
}
#endif
#endif
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully");

View File

@ -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());

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -1550,7 +1550,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0))
{
// Open ogg audio stream
stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char*)data, dataSize, NULL, NULL);
stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL);
if (ctxOgg != NULL)
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);
}
@ -4328,7 +4288,7 @@ static Model LoadIQM(const char *fileName)
// In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model;
const char* basePath = GetDirectoryPath(fileName);
const char *basePath = GetDirectoryPath(fileName);
// Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
@ -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;

View File

@ -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;
}

View File

@ -1572,7 +1572,7 @@ char *TextReplace(const char *text, const char *replace, const char *by)
byLen = TextLength(by);
// Count the number of replacements needed
insertPoint = (char*)text;
insertPoint = (char *)text;
for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen;
// Allocate returning string and point temp to it
@ -2339,7 +2339,7 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i
int readBytes = 0; // Data bytes read (line)
int readVars = 0; // Variables filled by sscanf()
const char *fileText = (const char*)fileData;
const char *fileText = (const char *)fileData;
const char *fileTextPtr = fileText;
bool fontMalformed = false; // Is the font malformed

View File

@ -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