Răsfoiți Sursa

NEW EXAMPLE: shaders_hot_reloading #1198

raysan5 5 ani în urmă
părinte
comite
26f6a64a39

+ 40 - 0
examples/shaders/resources/shaders/glsl330/reload.fs

@@ -0,0 +1,40 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;           // Texture coordinates (sampler2D)
+in vec4 fragColor;              // Tint color
+
+// Output fragment color
+out vec4 finalColor;            // Output fragment color
+
+// Uniform inputs
+uniform vec2 resolution;        // Viewport resolution (in pixels)
+uniform vec2 mouse;             // Mouse pixel xy coordinates
+uniform float time;             // Total run time (in secods)
+
+// Draw circle
+vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color)
+{
+	float d = length(position - fragCoord) - radius;
+	float t = clamp(d, 0.0, 1.0);
+	return vec4(color, 1.0 - t);
+}
+
+void main()
+{
+	vec2 fragCoord = gl_FragCoord.xy;
+	vec2 position = vec2(mouse.x, resolution.y - mouse.y);
+	float radius = 40.0;
+
+    // Draw background layer
+    vec4 colorA = vec4(0.2,0.2,0.8, 1.0);
+    vec4 colorB = vec4(1.0,0.7,0.2, 1.0);
+	vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1)));
+
+	// Draw circle layer
+	vec3 color = vec3(0.9, 0.16, 0.21);
+	vec4 layer2 = DrawCircle(fragCoord, position, radius, color);
+	
+	// Blend the two layers
+	finalColor = mix(layer1, layer2, layer2.a);
+}

+ 129 - 0
examples/shaders/shaders_hot_reloading.c

@@ -0,0 +1,129 @@
+/*******************************************************************************************
+*
+*   raylib [shaders] example - Hot reloading
+*
+*   NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
+*         is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
+*
+*   This example has been created using raylib 3.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2020 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include <time.h>       // Required for: localtime(), asctime()
+
+#if defined(PLATFORM_DESKTOP)
+    #define GLSL_VERSION            330
+#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+    #define GLSL_VERSION            100
+#endif
+
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+
+    InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hot reloading");
+
+    const char *fragShaderFileName = "resources/shaders/glsl%i/reload.fs";
+    long fragShaderFileModTime = GetFileModTime(FormatText(fragShaderFileName, GLSL_VERSION));
+
+    // Load raymarching shader
+    // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+    Shader shader = LoadShader(0, FormatText(fragShaderFileName, GLSL_VERSION));
+
+    // Get shader locations for required uniforms
+    int resolutionLoc = GetShaderLocation(shader, "resolution");
+    int mouseLoc = GetShaderLocation(shader, "mouse");
+    int timeLoc = GetShaderLocation(shader, "time");
+
+    float resolution[2] = { (float)screenWidth, (float)screenHeight };
+    SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2);
+
+    float totalTime = 0.0f;
+    bool shaderAutoReloading = false;
+
+    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
+        //----------------------------------------------------------------------------------
+        totalTime += GetFrameTime();
+        Vector2 mouse = GetMousePosition();
+        float mousePos[2] = { mouse.x, mouse.y };
+
+        // Set shader required uniform values
+        SetShaderValue(shader, timeLoc, &totalTime, UNIFORM_FLOAT);
+        SetShaderValue(shader, mouseLoc, mousePos, UNIFORM_VEC2);
+        
+        // Hot shader reloading
+        if (shaderAutoReloading || (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
+        {
+            long currentFragShaderModTime = GetFileModTime(FormatText(fragShaderFileName, GLSL_VERSION));
+            
+            // Check if shader file has been modified
+            if (currentFragShaderModTime != fragShaderFileModTime)
+            {
+                // Try reloading updated shader
+                Shader updatedShader = LoadShader(0, FormatText(fragShaderFileName, GLSL_VERSION));
+                
+                if (updatedShader.id != GetShaderDefault().id)      // It was correctly loaded
+                {
+                    UnloadShader(shader);
+                    shader = updatedShader;
+                    
+                    // Get shader locations for required uniforms
+                    resolutionLoc = GetShaderLocation(shader, "resolution");
+                    mouseLoc = GetShaderLocation(shader, "mouse");
+                    timeLoc = GetShaderLocation(shader, "time");
+                    
+                    // Reset required uniforms
+                    SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2);
+                }
+                
+                fragShaderFileModTime = currentFragShaderModTime;
+            }
+        }
+        
+        if (IsKeyPressed(KEY_A)) shaderAutoReloading = !shaderAutoReloading;
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(RAYWHITE);
+
+            // We only draw a white full-screen rectangle, frame is generated in shader
+            BeginShaderMode(shader);
+                DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
+            EndShaderMode();
+
+            DrawText(FormatText("PRESS [A] to TOGGLE SHADER AUTOLOADING: %s", 
+                     shaderAutoReloading? "AUTO" : "MANUAL"), 10, 10, 10, shaderAutoReloading? RED : BLACK);
+            if (!shaderAutoReloading) DrawText("MOUSE CLICK to SHADER RE-LOADING", 10, 30, 10, BLACK);
+            
+            DrawText(TextFormat("Shader last modification: %s", asctime(localtime(&fragShaderFileModTime))), 10, 430, 10, BLACK);
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadShader(shader);           // Unload shader
+
+    CloseWindow();                  // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}

BIN
examples/shaders/shaders_hot_reloading.png