diff --git a/Examples/Shaders/JuliaSet.cs b/Examples/Shaders/JuliaSet.cs index b74f75d..06c2c0d 100644 --- a/Examples/Shaders/JuliaSet.cs +++ b/Examples/Shaders/JuliaSet.cs @@ -41,6 +41,10 @@ public class JuliaSet //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; + const float zoomSpeed = 1.01f; + const float offsetSpeedMul = 2.0f; + + const float startingZoom = 0.75f; InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets"); @@ -48,14 +52,15 @@ public class JuliaSet // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader Shader shader = LoadShader(null, $"resources/shaders/glsl{GlslVersion}/julia_set.fs"); + // Create a RenderTexture2D to be used for render to texture + RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); + // c constant to use in z^2 + c float[] c = { PointsOfInterest[0][0], PointsOfInterest[0][1] }; // Offset and zoom to draw the julia set at. (centered on screen and default size) - float[] offset = { -(float)screenWidth / 2, -(float)screenHeight / 2 }; - float zoom = 1.0f; - - Vector2 offsetSpeed = new(0.0f, 0.0f); + float[] offset = { 0, 0 }; + 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 @@ -63,22 +68,11 @@ public class JuliaSet int zoomLoc = GetShaderLocation(shader, "zoom"); int offsetLoc = GetShaderLocation(shader, "offset"); - // Tell the shader what the screen dimensions, zoom, offset and c are - float[] screenDims = { (float)screenWidth, (float)screenHeight }; - Raylib.SetShaderValue( - shader, - GetShaderLocation(shader, "screenDims"), - screenDims, - ShaderUniformDataType.Vec2 - ); - + // Upload the shader uniform values! Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); - Raylib.SetShaderValue(shader, zoomLoc, zoomLoc, ShaderUniformDataType.Float); + Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float); Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2); - // Create a RenderTexture2D to be used for render to texture - RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); - // Multiplier of speed to change c value int incrementSpeed = 0; // Show controls @@ -136,10 +130,19 @@ public class JuliaSet Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); } + if (IsKeyPressed(KeyboardKey.R)) + { + zoom = startingZoom; + offset[0] = 1f; + offset[1] = 1f; + Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float); + Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2); + } + // Pause animation (c change) if (IsKeyPressed(KeyboardKey.Space)) { - pause = !pause; + incrementSpeed = 0; } // Toggle whether or not to show controls @@ -148,61 +151,48 @@ public class JuliaSet showControls = !showControls; } - if (!pause) + if (IsKeyPressed(KeyboardKey.Right)) { - if (IsKeyPressed(KeyboardKey.Right)) + incrementSpeed++; + } + else if (IsKeyPressed(KeyboardKey.Left)) + { + incrementSpeed--; + } + + // If either left or right button is pressed, zoom in/out + if (IsMouseButtonDown(MouseButton.Left) || IsMouseButtonDown(MouseButton.Right)) + { + if (IsMouseButtonDown(MouseButton.Left)) { - incrementSpeed++; - } - else if (IsKeyPressed(KeyboardKey.Left)) - { - incrementSpeed--; + zoom *= zoomSpeed; } - // TODO: The idea is to zoom and move around with mouse - // Probably offset movement should be proportional to zoom level - if (IsMouseButtonDown(MouseButton.Left) || IsMouseButtonDown(MouseButton.Right)) + if (IsMouseButtonDown(MouseButton.Right)) { - if (IsMouseButtonDown(MouseButton.Left)) - { - zoom += zoom * 0.003f; - } - - if (IsMouseButtonDown(MouseButton.Right)) - { - zoom -= zoom * 0.003f; - } - - Vector2 mousePos = GetMousePosition(); - - offsetSpeed.X = mousePos.X - (float)screenWidth / 2; - offsetSpeed.Y = mousePos.Y - (float)screenHeight / 2; - - // Slowly move camera to targetOffset - offset[0] += GetFrameTime() * offsetSpeed.X * 0.8f; - offset[1] += GetFrameTime() * offsetSpeed.Y * 0.8f; - } - else - { - offsetSpeed = new Vector2(0.0f, 0.0f); + zoom *= 1.0f / zoomSpeed; } + Vector2 mousePos = GetMousePosition(); + Vector2 offsetVelocity = Vector2.Zero; + + offsetVelocity.X = (mousePos.X / screenWidth - 0.5f) * offsetSpeedMul / zoom; + offsetVelocity.Y = (mousePos.Y / screenHeight - 0.5f) * offsetSpeedMul / zoom; + + // Apply move velocity to camera + offset[0] += GetFrameTime() * offsetVelocity.X; + offset[1] += GetFrameTime() * offsetVelocity.Y; + Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float); Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2); - - // Increment c value with time - float amount = GetFrameTime() * incrementSpeed * 0.0005f; - c[0] += amount; - c[1] += amount; - - Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); } - //---------------------------------------------------------------------------------- - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - ClearBackground(Color.Black); + // Increment c value with time + float amount = GetFrameTime() * incrementSpeed * 0.0005f; + c[0] += amount; + c[1] += amount; + + Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); // Using a render texture to draw Julia set // Enable drawing to texture @@ -216,6 +206,11 @@ public class JuliaSet DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Color.Black); EndTextureMode(); + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(Color.Black); + // Draw the saved texture and rendered julia set with shader // NOTE: We do not invert texture on Y, already considered inside shader BeginShaderMode(shader); @@ -229,6 +224,7 @@ public class JuliaSet DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, Color.RayWhite); DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, Color.RayWhite); DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, Color.RayWhite); + DrawText("Press KEY_R to recenter the camera", 10, 90, 10, Color.RayWhite); } EndDrawing();