|  | /******************************************************************************************* | 
						
						
							|  | * | 
						
						
							|  | *   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. | 
						
						
							|  | * | 
						
						
							|  | *   Example originally created with raylib 3.0, last time updated with raylib 3.5 | 
						
						
							|  | * | 
						
						
							|  | *   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) 2020-2023 Ramon Santamaria (@raysan5) | 
						
						
							|  | * | 
						
						
							|  | ********************************************************************************************/ | 
						
						
							|  | 
 | 
						
						
							|  | #include "raylib.h" | 
						
						
							|  | #include "rlgl.h" | 
						
						
							|  |  | 
						
						
							|  | #include <time.h>       // Required for: localtime(), asctime() | 
						
						
							|  |  | 
						
						
							|  | #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 - hot reloading"); | 
						
						
							|  | 
 | 
						
						
							|  |     const char *fragShaderFileName = "resources/shaders/glsl%i/reload.fs"; | 
						
						
							|  |     time_t fragShaderFileModTime = GetFileModTime(TextFormat(fragShaderFileName, GLSL_VERSION)); | 
						
						
							|  | 
 | 
						
						
							|  |     // Load raymarching shader | 
						
						
							|  |     // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader | 
						
						
							|  |     Shader shader = LoadShader(0, TextFormat(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, SHADER_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, SHADER_UNIFORM_FLOAT); | 
						
						
							|  |         SetShaderValue(shader, mouseLoc, mousePos, SHADER_UNIFORM_VEC2); | 
						
						
							|  | 
 | 
						
						
							|  |         // Hot shader reloading | 
						
						
							|  |         if (shaderAutoReloading || (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))) | 
						
						
							|  |         { | 
						
						
							|  |             long currentFragShaderModTime = GetFileModTime(TextFormat(fragShaderFileName, GLSL_VERSION)); | 
						
						
							|  | 
 | 
						
						
							|  |             // Check if shader file has been modified | 
						
						
							|  |             if (currentFragShaderModTime != fragShaderFileModTime) | 
						
						
							|  |             { | 
						
						
							|  |                 // Try reloading updated shader | 
						
						
							|  |                 Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION)); | 
						
						
							|  | 
 | 
						
						
							|  |                 if (updatedShader.id != rlGetShaderIdDefault())      // 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, SHADER_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(TextFormat("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; | 
						
						
							|  | }
 |