aboutsummaryrefslogtreecommitdiff
path: root/raylib/examples/shaders
diff options
context:
space:
mode:
authorUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
committerUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
commit2bbf92ad5ae7708bf18ac7ef333e9a979d8d1bde (patch)
treec9d22bb0d73d9cc0c8586e4d31c93a561ea8e910 /raylib/examples/shaders
parent1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (diff)
Working so hard like a soldiermain
Can't afford a thing on TV
Diffstat (limited to 'raylib/examples/shaders')
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs32
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl100/lighting.fs6
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl100/swirl.fs2
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl100/tiling.fs21
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl120/lighting.fs6
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs55
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs11
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs22
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs24
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs34
-rw-r--r--raylib/examples/shaders/resources/shaders/glsl330/lighting.fs6
-rw-r--r--raylib/examples/shaders/shader_texture_tiling.c94
-rw-r--r--raylib/examples/shaders/shaders_custom_uniform.c2
-rw-r--r--raylib/examples/shaders/shaders_deferred_render.c336
-rw-r--r--raylib/examples/shaders/shaders_deferred_render.pngbin0 -> 81327 bytes
-rw-r--r--raylib/examples/shaders/shaders_hybrid_render.c10
-rw-r--r--raylib/examples/shaders/shaders_julia_set.c96
-rw-r--r--raylib/examples/shaders/shaders_raymarching.c3
-rw-r--r--raylib/examples/shaders/shaders_texture_tiling.c105
-rw-r--r--raylib/examples/shaders/shaders_texture_tiling.pngbin0 -> 139191 bytes
-rw-r--r--raylib/examples/shaders/shaders_write_depth.c4
21 files changed, 671 insertions, 198 deletions
diff --git a/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs b/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs
index 44d0834..82d0a75 100644
--- a/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs
@@ -6,30 +6,30 @@ precision mediump float;
varying vec2 fragTexCoord;
varying vec4 fragColor;
-uniform vec2 screenDims; // Dimensions of the screen
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
uniform vec2 offset; // Offset of the scale.
uniform float zoom; // Zoom of the scale.
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
// for example, on RasperryPi for this examply only supports up to 60
-const int MAX_ITERATIONS = 48; // Max iterations to do
+const int maxIterations = 48; // Max iterations to do.
+const float colorCycles = 1.0f; // Number of times the color palette repeats.
// Square a complex number
vec2 ComplexSquare(vec2 z)
{
return vec2(
- z.x * z.x - z.y * z.y,
- z.x * z.y * 2.0
+ z.x*z.x - z.y*z.y,
+ z.x*z.y*2.0f
);
}
// Convert Hue Saturation Value (HSV) color into RGB
vec3 Hsv2rgb(vec3 c)
{
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+ vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f);
+ vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www);
+ return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y);
}
void main()
@@ -45,8 +45,8 @@ void main()
If the number is below 2, we keep iterating.
But when do we stop iterating if the number is always below 2 (it converges)?
- That is what MAX_ITERATIONS is for.
- Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
+ That is what maxIterations is for.
+ Then we can divide the iterations by the maxIterations value to get a normalized value that we can
then map to a color.
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
@@ -55,13 +55,15 @@ void main()
// The pixel coordinates are scaled so they are on the mandelbrot scale
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
- vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
+ vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom;
+ z.x += offset.x;
+ z.y += offset.y;
int iter = 0;
for (int iterations = 0; iterations < 60; iterations++)
{
z = ComplexSquare(z) + c; // Iterate function
- if (dot(z, z) > 4.0) break;
+ if (dot(z, z) > 4.0f) break;
iter = iterations;
}
@@ -72,12 +74,12 @@ void main()
z = ComplexSquare(z) + c;
// This last part smooths the color (again see link above).
- float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
+ float smoothVal = float(iter) + 1.0f - (log(log(length(z)))/log(2.0f));
// Normalize the value so it is between 0 and 1.
- float norm = smoothVal/float(MAX_ITERATIONS);
+ float norm = smoothVal/float(maxIterations);
// If in set, color black. 0.999 allows for some float accuracy error.
- if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
- else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
+ if (norm > 0.999f) gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f);
}
diff --git a/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs
index 7367161..73531a8 100644
--- a/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs
@@ -18,12 +18,6 @@ uniform vec4 colDiffuse;
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
-struct MaterialProperty {
- vec3 color;
- int useSampler;
- sampler2D sampler;
-};
-
struct Light {
int enabled;
int type;
diff --git a/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs b/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs
index ec6c664..7ff401a 100644
--- a/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs
@@ -42,5 +42,5 @@ void main()
tc += center;
vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;;
- gl_FragColor = vec4(color.rgb, 1.0);;
+ gl_FragColor = vec4(color.rgb, 1.0);
}
diff --git a/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs b/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs
new file mode 100644
index 0000000..392786a
--- /dev/null
+++ b/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs
@@ -0,0 +1,21 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D diffuseMap;
+uniform vec4 tiling;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ vec2 texCoord = fragTexCoord*tiling;
+ fragColor = texture2D(diffuseMap, texCoord);
+
+ gl_FragColor = fragColor;
+}
diff --git a/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs
index d9cfb44..8dda5a5 100644
--- a/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs
@@ -16,12 +16,6 @@ uniform vec4 colDiffuse;
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
-struct MaterialProperty {
- vec3 color;
- int useSampler;
- sampler2D sampler;
-};
-
struct Light {
int enabled;
int type;
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs
new file mode 100644
index 0000000..c9c6a31
--- /dev/null
+++ b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs
@@ -0,0 +1,55 @@
+#version 330 core
+out vec4 finalColor;
+
+in vec2 texCoord;
+in vec2 texCoord2;
+
+uniform sampler2D gPosition;
+uniform sampler2D gNormal;
+uniform sampler2D gAlbedoSpec;
+
+struct Light {
+ int enabled;
+ int type; // Unused in this demo.
+ vec3 position;
+ vec3 target; // Unused in this demo.
+ vec4 color;
+};
+
+const int NR_LIGHTS = 4;
+uniform Light lights[NR_LIGHTS];
+uniform vec3 viewPosition;
+
+const float QUADRATIC = 0.032;
+const float LINEAR = 0.09;
+
+void main() {
+ vec3 fragPosition = texture(gPosition, texCoord).rgb;
+ vec3 normal = texture(gNormal, texCoord).rgb;
+ vec3 albedo = texture(gAlbedoSpec, texCoord).rgb;
+ float specular = texture(gAlbedoSpec, texCoord).a;
+
+ vec3 ambient = albedo * vec3(0.1f);
+ vec3 viewDirection = normalize(viewPosition - fragPosition);
+
+ for(int i = 0; i < NR_LIGHTS; ++i)
+ {
+ if(lights[i].enabled == 0) continue;
+ vec3 lightDirection = lights[i].position - fragPosition;
+ vec3 diffuse = max(dot(normal, lightDirection), 0.0) * albedo * lights[i].color.xyz;
+
+ vec3 halfwayDirection = normalize(lightDirection + viewDirection);
+ float spec = pow(max(dot(normal, halfwayDirection), 0.0), 32.0);
+ vec3 specular = specular * spec * lights[i].color.xyz;
+
+ // Attenuation
+ float distance = length(lights[i].position - fragPosition);
+ float attenuation = 1.0 / (1.0 + LINEAR * distance + QUADRATIC * distance * distance);
+ diffuse *= attenuation;
+ specular *= attenuation;
+ ambient += diffuse + specular;
+ }
+
+ finalColor = vec4(ambient, 1.0);
+}
+
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs
new file mode 100644
index 0000000..f2b1bd7
--- /dev/null
+++ b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs
@@ -0,0 +1,11 @@
+#version 330 core
+
+layout (location = 0) in vec3 vertexPosition;
+layout (location = 1) in vec2 vertexTexCoord;
+
+out vec2 texCoord;
+
+void main() {
+ gl_Position = vec4(vertexPosition, 1.0);
+ texCoord = vertexTexCoord;
+}
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs
new file mode 100644
index 0000000..c86e20a
--- /dev/null
+++ b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs
@@ -0,0 +1,22 @@
+#version 330 core
+layout (location = 0) out vec3 gPosition;
+layout (location = 1) out vec3 gNormal;
+layout (location = 2) out vec4 gAlbedoSpec;
+
+in vec3 fragPosition;
+in vec2 fragTexCoord;
+in vec3 fragNormal;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D specularTexture;
+
+void main() {
+ // store the fragment position vector in the first gbuffer texture
+ gPosition = fragPosition;
+ // also store the per-fragment normals into the gbuffer
+ gNormal = normalize(fragNormal);
+ // and the diffuse per-fragment color
+ gAlbedoSpec.rgb = texture(diffuseTexture, fragTexCoord).rgb;
+ // store specular intensity in gAlbedoSpec's alpha component
+ gAlbedoSpec.a = texture(specularTexture, fragTexCoord).r;
+}
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs
new file mode 100644
index 0000000..7d264ba
--- /dev/null
+++ b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs
@@ -0,0 +1,24 @@
+#version 330 core
+layout (location = 0) in vec3 vertexPosition;
+layout (location = 1) in vec2 vertexTexCoord;
+layout (location = 2) in vec3 vertexNormal;
+
+out vec3 fragPosition;
+out vec2 fragTexCoord;
+out vec3 fragNormal;
+
+uniform mat4 matModel;
+uniform mat4 matView;
+uniform mat4 matProjection;
+
+void main()
+{
+ vec4 worldPos = matModel * vec4(vertexPosition, 1.0);
+ fragPosition = worldPos.xyz;
+ fragTexCoord = vertexTexCoord;
+
+ mat3 normalMatrix = transpose(inverse(mat3(matModel)));
+ fragNormal = normalMatrix * vertexNormal;
+
+ gl_Position = matProjection * matView * worldPos;
+}
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs b/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs
index c5ee0da..7a6f069 100644
--- a/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs
@@ -7,28 +7,28 @@ in vec4 fragColor;
// Output fragment color
out vec4 finalColor;
-uniform vec2 screenDims; // Dimensions of the screen
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
uniform vec2 offset; // Offset of the scale.
uniform float zoom; // Zoom of the scale.
-const int MAX_ITERATIONS = 255; // Max iterations to do.
+const int maxIterations = 255; // Max iterations to do.
+const float colorCycles = 2.0f; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers.
// Square a complex number
vec2 ComplexSquare(vec2 z)
{
return vec2(
- z.x * z.x - z.y * z.y,
- z.x * z.y * 2.0
+ z.x*z.x - z.y*z.y,
+ z.x*z.y*2.0f
);
}
// Convert Hue Saturation Value (HSV) color into RGB
vec3 Hsv2rgb(vec3 c)
{
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+ vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f);
+ vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www);
+ return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y);
}
void main()
@@ -44,8 +44,8 @@ void main()
If the number is below 2, we keep iterating.
But when do we stop iterating if the number is always below 2 (it converges)?
- That is what MAX_ITERATIONS is for.
- Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
+ That is what maxIterations is for.
+ Then we can divide the iterations by the maxIterations value to get a normalized value that we can
then map to a color.
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
@@ -54,14 +54,16 @@ void main()
// The pixel coordinates are scaled so they are on the mandelbrot scale
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
- vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
+ vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom;
+ z.x += offset.x;
+ z.y += offset.y;
int iterations = 0;
- for (iterations = 0; iterations < MAX_ITERATIONS; iterations++)
+ for (iterations = 0; iterations < maxIterations; iterations++)
{
z = ComplexSquare(z) + c; // Iterate function
- if (dot(z, z) > 4.0) break;
+ if (dot(z, z) > 4.0f) break;
}
// Another few iterations decreases errors in the smoothing calculation.
@@ -70,12 +72,12 @@ void main()
z = ComplexSquare(z) + c;
// This last part smooths the color (again see link above).
- float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
+ float smoothVal = float(iterations) + 1.0f - (log(log(length(z)))/log(2.0f));
// Normalize the value so it is between 0 and 1.
- float norm = smoothVal/float(MAX_ITERATIONS);
+ float norm = smoothVal/float(maxIterations);
// If in set, color black. 0.999 allows for some float accuracy error.
- if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
- else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
+ if (norm > 0.999f) finalColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ else finalColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f);
}
diff --git a/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs
index 58845c8..d1f3140 100644
--- a/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs
+++ b/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs
@@ -19,12 +19,6 @@ out vec4 finalColor;
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
-struct MaterialProperty {
- vec3 color;
- int useSampler;
- sampler2D sampler;
-};
-
struct Light {
int enabled;
int type;
diff --git a/raylib/examples/shaders/shader_texture_tiling.c b/raylib/examples/shaders/shader_texture_tiling.c
deleted file mode 100644
index 868d6b8..0000000
--- a/raylib/examples/shaders/shader_texture_tiling.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*******************************************************************************************
-*
-* raylib [textures] example - Texture Tiling
-*
-* Example demonstrates how to tile a texture on a 3D model using raylib.
-*
-* Example contributed by Luís Almeida (https://github.com/luis605)
-*
-* 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 Luís Almeida (https://github.com/luis605)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-//------------------------------------------------------------------------------------
-// Program main entry point
-//------------------------------------------------------------------------------------
-
-int main(void)
-{
- const int screenWidth = 800;
- const int screenHeight = 600;
-
- // Initialization
- //--------------------------------------------------------------------------------------
- InitWindow(screenWidth, screenHeight, "Raylib Texture Tiling");
-
- SetTargetFPS(60);
-
- // Load a texture
- Texture2D texture = LoadTexture("resources/raylib_logo.png");
-
- // Create a cube mesh
- Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
-
- // Load the texture onto the GPU
- Model model = LoadModelFromMesh(cube);
- model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
-
- // Set the tiling of the texture
- float tiling[2] = {3.0f, 3.0f};
- Shader shader = LoadShader(0, "resources/shaders/glsl330/tiling.fs"); // Create a custom shader in a .glsl file
- SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
- model.materials[0].shader = shader;
-
- // Camera setup
- Camera camera = { 0 };
- camera.position = (Vector3){ 3.0f, 3.0f, 3.0f };
- camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
- camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
- camera.fovy = 45.0f;
- camera.projection = CAMERA_PERSPECTIVE;
-
- // Main game loop
- while (!WindowShouldClose())
- {
- // Update
- //----------------------------------------------------------------------------------
-
- BeginDrawing();
- ClearBackground(RAYWHITE);
- UpdateCamera(&camera, CAMERA_FREE);
-
- // Draw the model
- {
- BeginMode3D(camera);
- BeginShaderMode(shader);
-
- DrawModel(model, (Vector3){ 0.0f, 0.0f, 0.0f }, 5.0f, WHITE);
-
- EndShaderMode();
- EndMode3D();
- }
-
- DrawText("Use mouse to rotate the camera", 10, 10, 20, DARKGRAY);
-
- EndDrawing();
- }
-
- // De-Initialization
- //--------------------------------------------------------------------------------------
-
- UnloadTexture(texture); // Unload texture
- UnloadModel(model); // Unload model
- UnloadShader(shader); // Unload shader
-
-
- CloseWindow(); // Close window and OpenGL context
-
- return 0;
-}
diff --git a/raylib/examples/shaders/shaders_custom_uniform.c b/raylib/examples/shaders/shaders_custom_uniform.c
index 0a1a764..b3b8040 100644
--- a/raylib/examples/shaders/shaders_custom_uniform.c
+++ b/raylib/examples/shaders/shaders_custom_uniform.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Apply a postprocessing shader and connect a custom uniform variable
+* raylib [shaders] example - Postprocessing with custom uniform variable
*
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
diff --git a/raylib/examples/shaders/shaders_deferred_render.c b/raylib/examples/shaders/shaders_deferred_render.c
new file mode 100644
index 0000000..21d2af3
--- /dev/null
+++ b/raylib/examples/shaders/shaders_deferred_render.c
@@ -0,0 +1,336 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - deferred rendering
+*
+* NOTE: This example requires raylib OpenGL 3.3 or OpenGL ES 3.0
+*
+* Example originally created with raylib 4.5, last time updated with raylib 4.5
+*
+* Example contributed by Justin Andreas Lacoste (@27justin) 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 Justin Andreas Lacoste (@27justin)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "rlgl.h"
+#include "raymath.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
+
+#include <stdlib.h> // Required for: NULL
+
+#define MAX_CUBES 30
+
+typedef struct GBuffer {
+ unsigned int framebuffer;
+
+ unsigned int positionTexture;
+ unsigned int normalTexture;
+ unsigned int albedoSpecTexture;
+
+ unsigned int depthRenderbuffer;
+} GBuffer;
+
+typedef enum {
+ DEFERRED_POSITION,
+ DEFERRED_NORMAL,
+ DEFERRED_ALBEDO,
+ DEFERRED_SHADING
+} DeferredMode;
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ // -------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - deferred render");
+
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 5.0f, 4.0f, 5.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 60.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Load plane model from a generated mesh
+ Model model = LoadModelFromMesh(GenMeshPlane(10.0f, 10.0f, 3, 3));
+ Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 2.0f, 2.0f));
+
+ // Load geometry buffer (G-buffer) shader and deferred shader
+ Shader gbufferShader = LoadShader("resources/shaders/glsl330/gbuffer.vs",
+ "resources/shaders/glsl330/gbuffer.fs");
+
+ Shader deferredShader = LoadShader("resources/shaders/glsl330/deferred_shading.vs",
+ "resources/shaders/glsl330/deferred_shading.fs");
+ deferredShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(deferredShader, "viewPosition");
+
+ // Initialize the G-buffer
+ GBuffer gBuffer = { 0 };
+ gBuffer.framebuffer = rlLoadFramebuffer(screenWidth, screenHeight);
+
+ if (!gBuffer.framebuffer)
+ {
+ TraceLog(LOG_WARNING, "Failed to create framebuffer");
+ exit(1);
+ }
+
+ rlEnableFramebuffer(gBuffer.framebuffer);
+
+ // Since we are storing position and normal data in these textures,
+ // we need to use a floating point format.
+ gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1);
+
+ gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1);
+ // Albedo (diffuse color) and specular strength can be combined into one texture.
+ // The color in RGB, and the specular strength in the alpha channel.
+ gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
+
+ // Activate the draw buffers for our framebuffer
+ rlActiveDrawBuffers(3);
+
+ // Now we attach our textures to the framebuffer.
+ rlFramebufferAttach(gBuffer.framebuffer, gBuffer.positionTexture, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
+ rlFramebufferAttach(gBuffer.framebuffer, gBuffer.normalTexture, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0);
+ rlFramebufferAttach(gBuffer.framebuffer, gBuffer.albedoSpecTexture, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0);
+
+ // Finally we attach the depth buffer.
+ gBuffer.depthRenderbuffer = rlLoadTextureDepth(screenWidth, screenHeight, true);
+ rlFramebufferAttach(gBuffer.framebuffer, gBuffer.depthRenderbuffer, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
+
+ // Make sure our framebuffer is complete.
+ // NOTE: rlFramebufferComplete() automatically unbinds the framebuffer, so we don't have
+ // to rlDisableFramebuffer() here.
+ if (!rlFramebufferComplete(gBuffer.framebuffer))
+ {
+ TraceLog(LOG_WARNING, "Framebuffer is not complete");
+ exit(1);
+ }
+
+ // Now we initialize the sampler2D uniform's in the deferred shader.
+ // We do this by setting the uniform's value to the color channel slot we earlier
+ // bound our textures to.
+ rlEnableShader(deferredShader.id);
+
+ rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gPosition"), 0);
+ rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gNormal"), 1);
+ rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), 2);
+
+ rlDisableShader();
+
+ // Assign out lighting shader to model
+ model.materials[0].shader = gbufferShader;
+ cube.materials[0].shader = gbufferShader;
+
+ // Create lights
+ //--------------------------------------------------------------------------------------
+ Light lights[MAX_LIGHTS] = { 0 };
+ lights[0] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, -2 }, Vector3Zero(), YELLOW, deferredShader);
+ lights[1] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, 2 }, Vector3Zero(), RED, deferredShader);
+ lights[2] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, 2 }, Vector3Zero(), GREEN, deferredShader);
+ lights[3] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, -2 }, Vector3Zero(), BLUE, deferredShader);
+
+ const float CUBE_SCALE = 0.25;
+ Vector3 cubePositions[MAX_CUBES] = { 0 };
+ float cubeRotations[MAX_CUBES] = { 0 };
+
+ for (int i = 0; i < MAX_CUBES; i++)
+ {
+ cubePositions[i] = (Vector3){
+ .x = (float)(rand()%10) - 5,
+ .y = (float)(rand()%5),
+ .z = (float)(rand()%10) - 5,
+ };
+
+ cubeRotations[i] = (float)(rand()%360);
+ }
+
+ DeferredMode mode = DEFERRED_SHADING;
+
+ rlEnableDepthTest();
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //---------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose())
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+
+ // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
+ float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
+ SetShaderValue(deferredShader, deferredShader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
+
+ // Check key inputs to enable/disable lights
+ if (IsKeyPressed(KEY_Y)) { lights[0].enabled = !lights[0].enabled; }
+ if (IsKeyPressed(KEY_R)) { lights[1].enabled = !lights[1].enabled; }
+ if (IsKeyPressed(KEY_G)) { lights[2].enabled = !lights[2].enabled; }
+ if (IsKeyPressed(KEY_B)) { lights[3].enabled = !lights[3].enabled; }
+
+ // Check key inputs to switch between G-buffer textures
+ if (IsKeyPressed(KEY_ONE)) mode = DEFERRED_POSITION;
+ if (IsKeyPressed(KEY_TWO)) mode = DEFERRED_NORMAL;
+ if (IsKeyPressed(KEY_THREE)) mode = DEFERRED_ALBEDO;
+ if (IsKeyPressed(KEY_FOUR)) mode = DEFERRED_SHADING;
+
+ // Update light values (actually, only enable/disable them)
+ for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(deferredShader, lights[i]);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ // ---------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Draw to the geometry buffer by first activating it
+ rlEnableFramebuffer(gBuffer.framebuffer);
+ rlClearScreenBuffers(); // Clear color and depth buffer
+
+ rlDisableColorBlend();
+ BeginMode3D(camera);
+ // NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
+ // will not work, as they won't immediately load the shader program.
+ rlEnableShader(gbufferShader.id);
+ // When drawing a model here, make sure that the material's shaders
+ // are set to the gbuffer shader!
+ DrawModel(model, Vector3Zero(), 1.0f, WHITE);
+ DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE);
+
+ for (int i = 0; i < MAX_CUBES; i++)
+ {
+ Vector3 position = cubePositions[i];
+ DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE);
+ }
+
+ rlDisableShader();
+ EndMode3D();
+ rlEnableColorBlend();
+
+ // Go back to the default framebuffer (0) and draw our deferred shading.
+ rlDisableFramebuffer();
+ rlClearScreenBuffers(); // Clear color & depth buffer
+
+ switch (mode)
+ {
+ case DEFERRED_SHADING:
+ {
+ BeginMode3D(camera);
+ rlDisableColorBlend();
+ rlEnableShader(deferredShader.id);
+ // Activate our g-buffer textures
+ // These will now be bound to the sampler2D uniforms `gPosition`, `gNormal`,
+ // and `gAlbedoSpec`
+ rlActiveTextureSlot(0);
+ rlEnableTexture(gBuffer.positionTexture);
+ rlActiveTextureSlot(1);
+ rlEnableTexture(gBuffer.normalTexture);
+ rlActiveTextureSlot(2);
+ rlEnableTexture(gBuffer.albedoSpecTexture);
+
+ // Finally, we draw a fullscreen quad to our default framebuffer
+ // This will now be shaded using our deferred shader
+ rlLoadDrawQuad();
+ rlDisableShader();
+ rlEnableColorBlend();
+ EndMode3D();
+
+ // As a last step, we now copy over the depth buffer from our g-buffer to the default framebuffer.
+ rlEnableFramebuffer(gBuffer.framebuffer); //glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer.framebuffer);
+ rlEnableFramebuffer(0); //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT
+ rlDisableFramebuffer();
+
+ // Since our shader is now done and disabled, we can draw our lights in default
+ // forward rendering
+ BeginMode3D(camera);
+ rlEnableShader(rlGetShaderIdDefault());
+ for(int i = 0; i < MAX_LIGHTS; i++)
+ {
+ if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
+ else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
+ }
+ rlDisableShader();
+ EndMode3D();
+ DrawText("FINAL RESULT", 10, screenHeight - 30, 20, DARKGREEN);
+ } break;
+
+ case DEFERRED_POSITION:
+ {
+ DrawTextureRec((Texture2D){
+ .id = gBuffer.positionTexture,
+ .width = screenWidth,
+ .height = screenHeight,
+ }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE);
+ DrawText("POSITION TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
+ } break;
+
+ case DEFERRED_NORMAL:
+ {
+ DrawTextureRec((Texture2D){
+ .id = gBuffer.normalTexture,
+ .width = screenWidth,
+ .height = screenHeight,
+ }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE);
+ DrawText("NORMAL TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
+ } break;
+
+ case DEFERRED_ALBEDO:
+ {
+ DrawTextureRec((Texture2D){
+ .id = gBuffer.albedoSpecTexture,
+ .width = screenWidth,
+ .height = screenHeight,
+ }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE);
+ DrawText("ALBEDO TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
+ } break;
+ }
+
+ DrawText("Toggle lights keys: [Y][R][G][B]", 10, 40, 20, DARKGRAY);
+ DrawText("Switch G-buffer textures: [1][2][3][4]", 10, 70, 20, DARKGRAY);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ // -----------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadModel(model); // Unload the models
+ UnloadModel(cube);
+
+ UnloadShader(deferredShader); // Unload shaders
+ UnloadShader(gbufferShader);
+
+ // Unload geometry buffer and all attached textures
+ rlUnloadFramebuffer(gBuffer.framebuffer);
+ rlUnloadTexture(gBuffer.positionTexture);
+ rlUnloadTexture(gBuffer.normalTexture);
+ rlUnloadTexture(gBuffer.albedoSpecTexture);
+ rlUnloadTexture(gBuffer.depthRenderbuffer);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
diff --git a/raylib/examples/shaders/shaders_deferred_render.png b/raylib/examples/shaders/shaders_deferred_render.png
new file mode 100644
index 0000000..90fa012
--- /dev/null
+++ b/raylib/examples/shaders/shaders_deferred_render.png
Binary files differ
diff --git a/raylib/examples/shaders/shaders_hybrid_render.c b/raylib/examples/shaders/shaders_hybrid_render.c
index 53e14b8..6242b30 100644
--- a/raylib/examples/shaders/shaders_hybrid_render.c
+++ b/raylib/examples/shaders/shaders_hybrid_render.c
@@ -1,4 +1,4 @@
-/*******************************************************************************************
+/*******************************************************************************************
*
* raylib [shaders] example - Hybrid Rendering
*
@@ -68,7 +68,7 @@ int main(void)
marchLocs.screenCenter = GetShaderLocation(shdrRaymarch, "screenCenter");
// Transfer screenCenter position to shader. Which is used to calculate ray direction.
- Vector2 screenCenter = {.x = screenWidth/2.0, .y = screenHeight/2.0};
+ Vector2 screenCenter = {.x = screenWidth/2.0f, .y = screenHeight/2.0f};
SetShaderValue(shdrRaymarch, marchLocs.screenCenter , &screenCenter , SHADER_UNIFORM_VEC2);
// Use Customized function to create writable depth texture buffer
@@ -84,7 +84,7 @@ int main(void)
};
// Camera FOV is pre-calculated in the camera Distance.
- double camDist = 1.0/(tan(camera.fovy*0.5*DEG2RAD));
+ float camDist = 1.0f/(tanf(camera.fovy*0.5f*DEG2RAD));
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -113,7 +113,7 @@ int main(void)
// Raymarch Scene
rlEnableDepthTest(); //Manually enable Depth Test to handle multiple rendering methods.
BeginShaderMode(shdrRaymarch);
- DrawRectangleRec((Rectangle){0,0,screenWidth,screenHeight},WHITE);
+ DrawRectangleRec((Rectangle){0,0, (float)screenWidth, (float)screenHeight},WHITE);
EndShaderMode();
// Raserize Scene
@@ -132,7 +132,7 @@ int main(void)
BeginDrawing();
ClearBackground(RAYWHITE);
- DrawTextureRec(target.texture, (Rectangle) { 0, 0, screenWidth, -screenHeight }, (Vector2) { 0, 0 }, WHITE);
+ DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE);
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
diff --git a/raylib/examples/shaders/shaders_julia_set.c b/raylib/examples/shaders/shaders_julia_set.c
index aebb287..608d3b5 100644
--- a/raylib/examples/shaders/shaders_julia_set.c
+++ b/raylib/examples/shaders/shaders_julia_set.c
@@ -9,12 +9,12 @@
*
* Example originally created with raylib 2.5, last time updated with raylib 4.0
*
-* Example contributed by eggmund (@eggmund) and reviewed by Ramon Santamaria (@raysan5)
+* Example contributed by Josh Colclough (@joshcol9232) 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) 2019-2023 eggmund (@eggmund) and Ramon Santamaria (@raysan5)
+* Copyright (c) 2019-2023 Josh Colclough (@joshcol9232) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@@ -37,6 +37,13 @@ const float pointsOfInterest[6][2] =
{ -0.70176f, -0.3842f },
};
+const int screenWidth = 800;
+const int screenHeight = 450;
+const float zoomSpeed = 1.01f;
+const float offsetSpeedMul = 2.0f;
+
+const float startingZoom = 0.75f;
+
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@@ -44,10 +51,6 @@ int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- const int screenWidth = 800;
- const int screenHeight = 450;
-
- //SetConfigFlags(FLAG_WINDOW_HIGHDPI);
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");
// Load julia set shader
@@ -61,10 +64,8 @@ int main(void)
float c[2] = { pointsOfInterest[0][0], pointsOfInterest[0][1] };
// Offset and zoom to draw the julia set at. (centered on screen and default size)
- float offset[2] = { -(float)GetScreenWidth()/2, -(float)GetScreenHeight()/2 };
- float zoom = 1.0f;
-
- Vector2 offsetSpeed = { 0.0f, 0.0f };
+ float offset[2] = { 0.0f, 0.0f };
+ float zoom = startingZoom;
// Get variable (uniform) locations on the shader to connect with the program
// NOTE: If uniform variable could not be found in the shader, function returns -1
@@ -72,17 +73,13 @@ int main(void)
int zoomLoc = GetShaderLocation(shader, "zoom");
int offsetLoc = GetShaderLocation(shader, "offset");
- // Tell the shader what the screen dimensions, zoom, offset and c are
- float screenDims[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
- SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, SHADER_UNIFORM_VEC2);
-
+ // Upload the shader uniform values!
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
int incrementSpeed = 0; // Multiplier of speed to change c value
bool showControls = true; // Show controls
- bool pause = false; // Pause animation
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -110,42 +107,50 @@ int main(void)
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
}
- if (IsKeyPressed(KEY_SPACE)) pause = !pause; // Pause animation (c change)
- if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
-
- if (!pause)
+ // If "R" is pressed, reset zoom and offset.
+ if (IsKeyPressed(KEY_R))
{
- if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++;
- else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--;
-
- // TODO: The idea is to zoom and move around with mouse
- // Probably offset movement should be proportional to zoom level
- if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
- {
- if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) zoom += zoom*0.003f;
- if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) zoom -= zoom*0.003f;
-
- Vector2 mousePos = GetMousePosition();
+ zoom = startingZoom;
+ offset[0] = 0.0f;
+ offset[1] = 0.0f;
+ SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
+ SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
+ }
- offsetSpeed.x = mousePos.x -(float)screenWidth/2;
- offsetSpeed.y = mousePos.y -(float)screenHeight/2;
+ if (IsKeyPressed(KEY_SPACE)) incrementSpeed = 0; // Pause animation (c change)
+ if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
- // Slowly move camera to targetOffset
- offset[0] += GetFrameTime()*offsetSpeed.x*0.8f;
- offset[1] += GetFrameTime()*offsetSpeed.y*0.8f;
- }
- else offsetSpeed = (Vector2){ 0.0f, 0.0f };
+ if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++;
+ else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--;
+ // If either left or right button is pressed, zoom in/out.
+ if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
+ {
+ // Change zoom. If Mouse left -> zoom in. Mouse right -> zoom out.
+ zoom *= IsMouseButtonDown(MOUSE_BUTTON_LEFT)? zoomSpeed : 1.0f/zoomSpeed;
+
+ const Vector2 mousePos = GetMousePosition();
+ Vector2 offsetVelocity;
+ // Find the velocity at which to change the camera. Take the distance of the mouse
+ // from the center of the screen as the direction, and adjust magnitude based on
+ // the current zoom.
+ offsetVelocity.x = (mousePos.x/(float)screenWidth - 0.5f)*offsetSpeedMul/zoom;
+ offsetVelocity.y = (mousePos.y/(float)screenHeight - 0.5f)*offsetSpeedMul/zoom;
+
+ // Apply move velocity to camera
+ offset[0] += GetFrameTime()*offsetVelocity.x;
+ offset[1] += GetFrameTime()*offsetVelocity.y;
+
+ // Update the shader uniform values!
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
-
- // Increment c value with time
- float amount = GetFrameTime()*incrementSpeed*0.0005f;
- c[0] += amount;
- c[1] += amount;
-
- SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
}
+
+ // Increment c value with time
+ const float dc = GetFrameTime()*(float)incrementSpeed*0.0005f;
+ c[0] += dc;
+ c[1] += dc;
+ SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
//----------------------------------------------------------------------------------
// Draw
@@ -178,7 +183,8 @@ int main(void)
DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE);
DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
- DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
+ DrawText("Press KEY_SPACE to stop movement animation", 10, 75, 10, RAYWHITE);
+ DrawText("Press KEY_R to recenter the camera", 10, 90, 10, RAYWHITE);
}
EndDrawing();
//----------------------------------------------------------------------------------
diff --git a/raylib/examples/shaders/shaders_raymarching.c b/raylib/examples/shaders/shaders_raymarching.c
index e9b7755..ff403e6 100644
--- a/raylib/examples/shaders/shaders_raymarching.c
+++ b/raylib/examples/shaders/shaders_raymarching.c
@@ -82,7 +82,8 @@ int main(void)
// Check if screen is resized
if (IsWindowResized())
{
- float resolution[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
+ resolution[0] = (float)GetScreenWidth();
+ resolution[1] = (float)GetScreenHeight();
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
}
//----------------------------------------------------------------------------------
diff --git a/raylib/examples/shaders/shaders_texture_tiling.c b/raylib/examples/shaders/shaders_texture_tiling.c
new file mode 100644
index 0000000..0d07bdf
--- /dev/null
+++ b/raylib/examples/shaders/shaders_texture_tiling.c
@@ -0,0 +1,105 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - texture tiling
+*
+* Example demonstrates how to tile a texture on a 3D model using raylib.
+*
+* Example contributed by Luis Almeida (@luis605) 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 Luis Almeida (@luis605)
+*
+********************************************************************************************/
+
+#include "raylib.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 - texture tiling");
+
+ // Define the camera to look into our 3d world
+ Camera3D camera = { 0 };
+ camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Load a cube model
+ Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
+ Model model = LoadModelFromMesh(cube);
+
+ // Load a texture and assign to cube model
+ Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
+
+ // Set the texture tiling using a shader
+ float tiling[2] = { 3.0f, 3.0f };
+ Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION));
+ SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
+ model.materials[0].shader = shader;
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_FREE);
+
+ if (IsKeyPressed('Z')) camera.target = (Vector3){ 0.0f, 0.5f, 0.0f };
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ BeginShaderMode(shader);
+ DrawModel(model, (Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, WHITE);
+ EndShaderMode();
+
+ DrawGrid(10, 1.0f);
+
+ EndMode3D();
+
+ DrawText("Use mouse to rotate the camera", 10, 10, 20, DARKGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadModel(model); // Unload model
+ UnloadShader(shader); // Unload shader
+ UnloadTexture(texture); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/shaders/shaders_texture_tiling.png b/raylib/examples/shaders/shaders_texture_tiling.png
new file mode 100644
index 0000000..5dfe76e
--- /dev/null
+++ b/raylib/examples/shaders/shaders_texture_tiling.png
Binary files differ
diff --git a/raylib/examples/shaders/shaders_write_depth.c b/raylib/examples/shaders/shaders_write_depth.c
index d9e40d0..3169724 100644
--- a/raylib/examples/shaders/shaders_write_depth.c
+++ b/raylib/examples/shaders/shaders_write_depth.c
@@ -1,4 +1,4 @@
-/*******************************************************************************************
+/*******************************************************************************************
*
* raylib [shaders] example - Depth buffer writing
*
@@ -92,7 +92,7 @@ int main(void)
BeginDrawing();
ClearBackground(RAYWHITE);
- DrawTextureRec(target.texture, (Rectangle) { 0, 0, screenWidth, -screenHeight }, (Vector2) { 0, 0 }, WHITE);
+ DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE);
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------