From 6d171ca2df1416e532b3953215d782e9a2c43ee2 Mon Sep 17 00:00:00 2001 From: arceryz Date: Sun, 2 Jun 2024 14:13:10 +0200 Subject: [PATCH] Ray2 origin+zooming. GUI Upgrades, Code cohesion and structure. --- .vscode/launch.json | 2 +- Shaders/ray2.vert | 11 +++--- Source/Ray2/Ray2.h | 78 ++++++++++++++++++++++++------------- Source/Ray2/Ray2Program.cpp | 27 ++++++++++++- Source/Ray2/Ray2Program.h | 7 +++- Source/Ray3/Ray3.h | 63 +++++++++++++++++------------- Source/Ray3/XCamera.cpp | 5 +-- Source/Ray3/XCamera.h | 2 +- 8 files changed, 127 insertions(+), 68 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c3fff35..e2abe3b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "preLaunchTask": "CMake: build", "cwd": "${workspaceRoot}", - "program": "${workspaceRoot}/build/Debug/Mirai.exe", + "program": "${workspaceRoot}/build/Release/Mirai.exe", "console": "integratedTerminal" } ] diff --git a/Shaders/ray2.vert b/Shaders/ray2.vert index 2521e6d..f12ddc1 100644 --- a/Shaders/ray2.vert +++ b/Shaders/ray2.vert @@ -12,6 +12,8 @@ layout(location=1) uniform int numBounces; layout(location=2) uniform vec3 color; layout(location=3) uniform float falloff; layout(location=4) uniform float pointSize; +layout(location=5) uniform float zoom; +layout(location=6) uniform vec2 rayOrigin; // We will only output color. out vec4 fragColor; @@ -30,18 +32,17 @@ void main() // Ray originate from (0, 0). vec2 ray; - ray.x = cos(2*PI*prog); - ray.y = sin(2*PI*prog); - ray *= 0.1*dist; + ray.x = dist*cos(2*PI*prog); + ray.y = dist*sin(2*PI*prog); vec2 pos = vertexPosition; pos *= 0.01 * pointSize; - pos += ray; + pos += (ray + rayOrigin)*0.1*zoom; gl_Position = vec4(pos.xy, 0, 1); localPos = vertexPosition; - float fade = pow(falloff, depth); + float fade = pow(1.0-falloff, depth); //fade *= 0.3+0.7*float(dmin<0.1); fragColor = vec4(color*fade, 1); } \ No newline at end of file diff --git a/Source/Ray2/Ray2.h b/Source/Ray2/Ray2.h index 4ddec52..488aed1 100644 --- a/Source/Ray2/Ray2.h +++ b/Source/Ray2/Ray2.h @@ -9,6 +9,11 @@ class Ray2 { public: + float originAngle = 0.0f; + float originRadius = 0.0f; + bool drawInterface = true; + bool hideGui = false; + Ray2(): program(scene) { scene.GenerateRegularPolygon(5); @@ -20,39 +25,56 @@ class Ray2 }; void Draw() { - program.numRays = (int)(pow(numRaysFact, 8) * MAX_RAYS); - program.color = ColorFromHSV(color.x, color.y, color.z); - program.arcFocus = (hyperbolic ? -1 : 1) * (pow(focusFact, 5) * (ARC_FOCUS_INF-1)); + { // Update Pass + float delta = GetFrameTime(); + program.numRays = (int)(pow(numRaysFact, 8) * MAX_RAYS); + program.color = ColorFromHSV(color.x, color.y, color.z); + program.arcFocus = (hyperbolic ? -1 : 1) * (pow(focusFact, 5) * (ARC_FOCUS_INF-1)); - BeginMode2D(camera); - program.ComputePass(); - program.RenderPass(); - EndMode2D(); + if (currentShape != shape) { + currentShape = shape; + scene.GenerateRegularPolygon(shape); + } + if (IsKeyPressed(KEY_R)) { + scene.GenerateRandomCirclePolygon(5, 20); + } + if (IsKeyPressed(KEY_H)) hideGui = !hideGui; - DrawText(TextFormat("N=%d", program.numRays), 10, 30, 20, DARKGRAY); - DrawFPS(10, 10); + originAngle += 45.0*delta*(IsKeyDown(KEY_D) ? -1.0: (IsKeyDown(KEY_A) ? +1.0: 0.0)); + originRadius = Clamp(originRadius+0.5*delta*(IsKeyDown(KEY_W) ? 1.0: (IsKeyDown(KEY_S) ? -1.0: 0.0)), 0, 1); + program.origin = { originRadius*cosf(DEG2RAD*originAngle), originRadius*sinf(DEG2RAD*originAngle) }; - float ox = 170; - float oy = 15; - GuiSlider({ ox, oy, 200, 10 }, "Rays%", TextFormat("%3.1f", 100*numRaysFact), &numRaysFact, 0, 1); - GuiSlider({ ox, oy+20, 200, 10 }, "Focus", TextFormat("%.2f (r=%.3f)", -program.arcFocus, program.GetArcRadius()), &focusFact, 0.001, 1); - GuiSlider({ ox+270, oy, 100, 10 }, "Zoom", TextFormat("%.1f", camera.zoom), &camera.zoom, 0.1, 2); - GuiCheckBox({ ox+315, oy+15, 20, 20 }, "Hyperbolic", &hyperbolic); - GuiSpinner({ ox, oy+40, 80, 15 }, "Num Bounces ", &program.numBounces, 1, MAX_BOUNCES, false); - GuiSpinner({ ox+130, oy+40, 80, 15 }, "Shape ", &shape, 3, 10, false); - - ox = 660; - oy = 13; - GuiColorPickerHSV({ ox, oy, 100, 70 }, "Color", &color); - GuiSlider({ ox, oy+80, 100, 10 }, "Falloff", TextFormat("%.2f", program.falloff), &program.falloff, 0.001, 1); - GuiSlider({ ox, oy+100, 100, 10 }, "Point Size", TextFormat("%.2f", program.pointSize), &program.pointSize, 0.3, 3); + float scroll = GetMouseWheelMove(); + program.zoom = Clamp(program.zoom * (1.0 + scroll*0.2), 0.25, 4.0); + } - if (currentShape != shape) { - currentShape = shape; - scene.GenerateRegularPolygon(shape); + { // Render pass. + BeginMode2D(camera); + program.ComputePass(); + program.RenderPass(); + if (drawInterface) program.InterfacePass(); + EndMode2D(); } - if (IsKeyPressed(KEY_R)) { - scene.GenerateRandomCirclePolygon(5, 20); + + if (!hideGui) + { // Gui Pass. + DrawText(TextFormat("N=%d", program.numRays), 10, 30, 20, DARKGRAY); + DrawFPS(10, 10); + + float ox = 170; + float oy = 15; + GuiSlider({ ox, oy, 200, 10 }, "Rays%", TextFormat("%3.1f", 100*numRaysFact), &numRaysFact, 0, 1); + GuiSlider({ ox, oy+20, 200, 10 }, "Focus", TextFormat("%.2f (r=%.3f)", -program.arcFocus, program.GetArcRadius()), &focusFact, 0.001, 1); + GuiSlider({ ox+270, oy, 100, 10 }, "Zoom", TextFormat("%.1f", program.zoom), &program.zoom, 0.25, 4); + GuiCheckBox({ ox+315, oy+15, 20, 20 }, "Hyperbolic", &hyperbolic); + GuiCheckBox({ ox+315, oy+40, 20, 20 }, "Draw Lines", &drawInterface); + GuiSpinner({ ox, oy+40, 80, 15 }, "Num Bounces ", &program.numBounces, 1, MAX_BOUNCES, false); + GuiSpinner({ ox+130, oy+40, 80, 15 }, "Shape ", &shape, 3, 10, false); + + ox = 660; + oy = 13; + GuiSlider({ ox, oy, 100, 10 }, "Falloff", TextFormat("%.2f", program.falloff), &program.falloff, 0.001, 1); + GuiSlider({ ox, oy+20, 100, 10 }, "Point Size", TextFormat("%.2f", program.pointSize), &program.pointSize, 0.3, 3); } } diff --git a/Source/Ray2/Ray2Program.cpp b/Source/Ray2/Ray2Program.cpp index 7c613ce..21eb0ad 100644 --- a/Source/Ray2/Ray2Program.cpp +++ b/Source/Ray2/Ray2Program.cpp @@ -87,7 +87,8 @@ void Ray2Program::RenderPass() rlSetUniform(2, &colvec, SHADER_UNIFORM_VEC3, 1); rlSetUniform(3, &falloff, SHADER_UNIFORM_FLOAT, 1); rlSetUniform(4, &pointSize, SHADER_UNIFORM_FLOAT, 1); - + rlSetUniform(5, &zoom, SHADER_UNIFORM_FLOAT, 1); + rlSetUniform(6, &origin, SHADER_UNIFORM_VEC2, 1); rlBindShaderBuffer(distanceSSBO, 0); // Draw the particles. Instancing will duplicate the vertices. @@ -97,6 +98,30 @@ void Ray2Program::RenderPass() rlDisableShader(); } +void Ray2Program::InterfacePass() +{ + Vector2 originWorld = Transform(origin); + Vector2 centerWorld = Transform({ 0, 0 }); + Vector2 radiusWorld = Transform({ 0, 1 }); + DrawCircleLinesV(centerWorld, Vector2Length(Vector2Subtract(radiusWorld, centerWorld)), Fade(RED, 0.5)); + DrawCircleV(originWorld, 1.0*zoom, RED); + + float r = 0.3; + for (int i = 0; i < 10; i++) { + float angle = ((float)i)/10.0 * 2*PI; + Vector2 world = Transform(Vector2Add(origin, { r*cosf(angle), r*sinf(angle) })); + DrawLineV(originWorld, world, Fade(RED, 0.5)); + } +} + +Vector2 Ray2Program::Transform(Vector2 local) +{ + return { + (float)((local.x*zoom*0.1+1)/2.0*GetScreenWidth()), + (float)((-local.y*zoom*0.1+1)/2.0*GetScreenHeight()) + }; +} + float Ray2Program::GetArcRadius() { // Take the first point and compute arc radius like in the shader. diff --git a/Source/Ray2/Ray2Program.h b/Source/Ray2/Ray2Program.h index 7f7fb3f..6a9061f 100644 --- a/Source/Ray2/Ray2Program.h +++ b/Source/Ray2/Ray2Program.h @@ -24,8 +24,10 @@ class Ray2Program int numRays = 0; int numBounces = 0; Color color = GREEN; - float falloff = 0.7f; + float falloff = 0.3f; float pointSize = 1.0; + float zoom = 1.0f; + Vector2 origin = { 0, 0 }; // If the focus is +-INF, then we have the straight edges. // If the focus is positive, we enter spherical space. @@ -38,7 +40,9 @@ class Ray2Program void UpdateScene(bool center=true); void ComputePass(); void RenderPass(); + void InterfacePass(); float GetArcRadius(); + Vector2 Transform(Vector2 local); private: ShaderBuffer mirrorSSBO = 0; @@ -47,7 +51,6 @@ class Ray2Program ComputeShader computeProgram = 0; Shader renderProgram = {}; int numWorkGroups = 0; - Vector2 origin = {}; Ray2Scene &scene; }; diff --git a/Source/Ray3/Ray3.h b/Source/Ray3/Ray3.h index 3167616..dbf22a4 100644 --- a/Source/Ray3/Ray3.h +++ b/Source/Ray3/Ray3.h @@ -53,37 +53,46 @@ class Ray3 } void Draw() { - float dt = GetFrameTime(); - program.sphereFocus = (sphereFocusPercent > 0 ? 1: -1) * powf(1-abs(sphereFocusPercent), 8) * (SPHERE_FOCUS_INF); - program.numBounces = (int)numBouncesFl; - Ray3Scene *activeScene = &scenes[sceneIndex]; - if (program.GetScene() != activeScene) { program.SetScene(activeScene); }; - if (IsKeyPressed(KEY_H)) hideGui = !hideGui; + { // Update Pass. + float dt = GetFrameTime(); + program.sphereFocus = (sphereFocusPercent > 0 ? 1: -1) * powf(1-abs(sphereFocusPercent), 8) * (SPHERE_FOCUS_INF); + program.numBounces = (int)numBouncesFl; + Ray3Scene *activeScene = &scenes[sceneIndex]; + if (program.GetScene() != activeScene) { program.SetScene(activeScene); }; + if (IsKeyPressed(KEY_H)) hideGui = !hideGui; - float scroll = GetMouseWheelMove(); - float radialSpeed = 10.0f; - float hspeed = 35.0f; - float vspeed = 20.0f; - camera->AddRadius(scroll*dt*radialSpeed); - if (!camera->perspective) camera->orthoSize += scroll*dt*radialSpeed; - if (IsKeyDown(KEY_LEFT)) camera->RotateH(-hspeed*dt); - if (IsKeyDown(KEY_RIGHT)) camera->RotateH(+hspeed*dt); - if (IsKeyDown(KEY_UP)) camera->RotateV(vspeed*dt); - if (IsKeyDown(KEY_DOWN)) camera->RotateV(-vspeed*dt); - if (IsKeyPressed(KEY_A)) { - // Align to the first polygon of the scene. - Ray3Scene &scene = *program.GetScene(); - Polygon &poly = scene.mirrors[0]; - Vector3 normalvec = Vector3Scale(poly.normal, camera->GetRadius()); - camera->internal.position = normalvec; + float scroll = -GetMouseWheelMove(); + float radialSpeed = 10.0f; + float hspeed = 35.0f; + float vspeed = 20.0f; + camera->SetRadius(camera->GetRadius()*(1.0+scroll*dt*radialSpeed)); + if (!camera->perspective) camera->orthoSize = camera->orthoSize*(1.0+scroll*dt*radialSpeed); + if (IsKeyDown(KEY_A)) camera->RotateH(-hspeed*dt); + if (IsKeyDown(KEY_D)) camera->RotateH(+hspeed*dt); + if (IsKeyDown(KEY_W)) camera->RotateV(vspeed*dt); + if (IsKeyDown(KEY_S)) camera->RotateV(-vspeed*dt); + if (IsKeyPressed(KEY_E)) { + // Align to the first polygon of the scene. + Ray3Scene &scene = *program.GetScene(); + Polygon &poly = scene.mirrors[0]; + Vector3 normalvec = Vector3Scale(poly.normal, camera->GetRadius()); + camera->internal.position = normalvec; + } + if (IsKeyPressed(KEY_R)) { + camera->SetRadius(0); + camera->orthoSize = 2; + } + if (IsKeyPressed(KEY_F)) sphereFocusPercent = 0; } - if (IsKeyPressed(KEY_S)) sphereFocusPercent = 0; - camera->Begin(); - program.Draw(camera->internal); - if (showMesh) program.GetScene()->DrawMirrors(0.99, 0.95); - EndMode3D(); + { // Render Pass. + camera->Begin(); + program.Draw(camera->internal); + if (showMesh) program.GetScene()->DrawMirrors(0.99, 0.95); + EndMode3D(); + } + // GUI Pass. if (!hideGui) { DrawFPS(10, 10); if (GuiButton({ 700, 10, 80, 20 }, TextFormat(showMesh ? "Mesh Visible": "Mesh Hidden"))) showMesh = !showMesh; diff --git a/Source/Ray3/XCamera.cpp b/Source/Ray3/XCamera.cpp index d52a1c1..3913d5b 100644 --- a/Source/Ray3/XCamera.cpp +++ b/Source/Ray3/XCamera.cpp @@ -37,12 +37,11 @@ void XCamera::RotateV(float deg) internal.position = Vector3RotateByAxisAngle(internal.position, left, DEG2RAD*deg); } -void XCamera::AddRadius(float f) +void XCamera::SetRadius(float rad) { Vector3 targetToPos = Vector3Subtract(internal.position, internal.target); - float currentRadius = Vector3Length(targetToPos); internal.position = Vector3Add(internal.target, - Vector3Scale(Vector3Normalize(targetToPos), Clamp(f+currentRadius, 0.01f, 100.0f))); + Vector3Scale(Vector3Normalize(targetToPos), Clamp(rad, 0.01f, 100.0f))); } float XCamera::GetRadius() diff --git a/Source/Ray3/XCamera.h b/Source/Ray3/XCamera.h index b7fe2f6..04100ee 100644 --- a/Source/Ray3/XCamera.h +++ b/Source/Ray3/XCamera.h @@ -19,7 +19,7 @@ class XCamera { void Begin(); void RotateH(float deg); void RotateV(float deg); - void AddRadius(float f); + void SetRadius(float rad); float GetRadius(); };