You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
5.4 KiB

  1. /*******************************************************************************************
  2. *
  3. * raylib [shaders] example - Hot reloading
  4. *
  5. * NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
  6. * is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
  7. *
  8. * This example has been created using raylib 3.0 (www.raylib.com)
  9. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  10. *
  11. * Copyright (c) 2020 Ramon Santamaria (@raysan5)
  12. *
  13. ********************************************************************************************/
  14. #include "raylib.h"
  15. #include <time.h> // Required for: localtime(), asctime()
  16. #if defined(PLATFORM_DESKTOP)
  17. #define GLSL_VERSION 330
  18. #else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
  19. #define GLSL_VERSION 100
  20. #endif
  21. int main(void)
  22. {
  23. // Initialization
  24. //--------------------------------------------------------------------------------------
  25. int screenWidth = 800;
  26. int screenHeight = 450;
  27. InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hot reloading");
  28. const char *fragShaderFileName = "resources/shaders/glsl%i/reload.fs";
  29. long fragShaderFileModTime = GetFileModTime(TextFormat(fragShaderFileName, GLSL_VERSION));
  30. // Load raymarching shader
  31. // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
  32. Shader shader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION));
  33. // Get shader locations for required uniforms
  34. int resolutionLoc = GetShaderLocation(shader, "resolution");
  35. int mouseLoc = GetShaderLocation(shader, "mouse");
  36. int timeLoc = GetShaderLocation(shader, "time");
  37. float resolution[2] = { (float)screenWidth, (float)screenHeight };
  38. SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2);
  39. float totalTime = 0.0f;
  40. bool shaderAutoReloading = false;
  41. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  42. //--------------------------------------------------------------------------------------
  43. // Main game loop
  44. while (!WindowShouldClose()) // Detect window close button or ESC key
  45. {
  46. // Update
  47. //----------------------------------------------------------------------------------
  48. totalTime += GetFrameTime();
  49. Vector2 mouse = GetMousePosition();
  50. float mousePos[2] = { mouse.x, mouse.y };
  51. // Set shader required uniform values
  52. SetShaderValue(shader, timeLoc, &totalTime, UNIFORM_FLOAT);
  53. SetShaderValue(shader, mouseLoc, mousePos, UNIFORM_VEC2);
  54. // Hot shader reloading
  55. if (shaderAutoReloading || (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
  56. {
  57. long currentFragShaderModTime = GetFileModTime(TextFormat(fragShaderFileName, GLSL_VERSION));
  58. // Check if shader file has been modified
  59. if (currentFragShaderModTime != fragShaderFileModTime)
  60. {
  61. // Try reloading updated shader
  62. Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION));
  63. if (updatedShader.id != GetShaderDefault().id) // It was correctly loaded
  64. {
  65. UnloadShader(shader);
  66. shader = updatedShader;
  67. // Get shader locations for required uniforms
  68. resolutionLoc = GetShaderLocation(shader, "resolution");
  69. mouseLoc = GetShaderLocation(shader, "mouse");
  70. timeLoc = GetShaderLocation(shader, "time");
  71. // Reset required uniforms
  72. SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2);
  73. }
  74. fragShaderFileModTime = currentFragShaderModTime;
  75. }
  76. }
  77. if (IsKeyPressed(KEY_A)) shaderAutoReloading = !shaderAutoReloading;
  78. //----------------------------------------------------------------------------------
  79. // Draw
  80. //----------------------------------------------------------------------------------
  81. BeginDrawing();
  82. ClearBackground(RAYWHITE);
  83. // We only draw a white full-screen rectangle, frame is generated in shader
  84. BeginShaderMode(shader);
  85. DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
  86. EndShaderMode();
  87. DrawText(TextFormat("PRESS [A] to TOGGLE SHADER AUTOLOADING: %s",
  88. shaderAutoReloading? "AUTO" : "MANUAL"), 10, 10, 10, shaderAutoReloading? RED : BLACK);
  89. if (!shaderAutoReloading) DrawText("MOUSE CLICK to SHADER RE-LOADING", 10, 30, 10, BLACK);
  90. DrawText(TextFormat("Shader last modification: %s", asctime(localtime(&fragShaderFileModTime))), 10, 430, 10, BLACK);
  91. EndDrawing();
  92. //----------------------------------------------------------------------------------
  93. }
  94. // De-Initialization
  95. //--------------------------------------------------------------------------------------
  96. UnloadShader(shader); // Unload shader
  97. CloseWindow(); // Close window and OpenGL context
  98. //--------------------------------------------------------------------------------------
  99. return 0;
  100. }