From 2bbf92ad5ae7708bf18ac7ef333e9a979d8d1bde Mon Sep 17 00:00:00 2001 From: Uneven Prankster Date: Thu, 16 Nov 2023 21:12:27 -0300 Subject: Working so hard like a soldier Can't afford a thing on TV --- .../shaders/resources/shaders/glsl100/julia_set.fs | 32 +- .../shaders/resources/shaders/glsl100/lighting.fs | 6 - .../shaders/resources/shaders/glsl100/swirl.fs | 2 +- .../shaders/resources/shaders/glsl100/tiling.fs | 21 ++ .../shaders/resources/shaders/glsl120/lighting.fs | 6 - .../resources/shaders/glsl330/deferred_shading.fs | 55 ++++ .../resources/shaders/glsl330/deferred_shading.vs | 11 + .../shaders/resources/shaders/glsl330/gbuffer.fs | 22 ++ .../shaders/resources/shaders/glsl330/gbuffer.vs | 24 ++ .../shaders/resources/shaders/glsl330/julia_set.fs | 34 ++- .../shaders/resources/shaders/glsl330/lighting.fs | 6 - raylib/examples/shaders/shader_texture_tiling.c | 94 ------ raylib/examples/shaders/shaders_custom_uniform.c | 2 +- raylib/examples/shaders/shaders_deferred_render.c | 336 +++++++++++++++++++++ .../examples/shaders/shaders_deferred_render.png | Bin 0 -> 81327 bytes raylib/examples/shaders/shaders_hybrid_render.c | 10 +- raylib/examples/shaders/shaders_julia_set.c | 96 +++--- raylib/examples/shaders/shaders_raymarching.c | 3 +- raylib/examples/shaders/shaders_texture_tiling.c | 105 +++++++ raylib/examples/shaders/shaders_texture_tiling.png | Bin 0 -> 139191 bytes raylib/examples/shaders/shaders_write_depth.c | 4 +- 21 files changed, 671 insertions(+), 198 deletions(-) create mode 100644 raylib/examples/shaders/resources/shaders/glsl100/tiling.fs create mode 100644 raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs create mode 100644 raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs create mode 100644 raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs create mode 100644 raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs delete mode 100644 raylib/examples/shaders/shader_texture_tiling.c create mode 100644 raylib/examples/shaders/shaders_deferred_render.c create mode 100644 raylib/examples/shaders/shaders_deferred_render.png create mode 100644 raylib/examples/shaders/shaders_texture_tiling.c create mode 100644 raylib/examples/shaders/shaders_texture_tiling.png (limited to 'raylib/examples/shaders') 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 // 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 Binary files /dev/null and b/raylib/examples/shaders/shaders_deferred_render.png 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 Binary files /dev/null and b/raylib/examples/shaders/shaders_texture_tiling.png 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(); //---------------------------------------------------------------------------------- -- cgit v1.2.3