Commit: 1b8deec6bf2c702349076c5e40007722264f2822
Parent: 3d225942ba618ae0d420ba8de049a3d2e5c79095
Author: Randy Palamar
Date: Sat, 25 May 2024 18:10:45 -0600
use velocity for panning and do zoom on CPU
Diffstat:
M | frag.glsl | | | 3 | +-- |
M | main.c | | | 78 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
2 files changed, 58 insertions(+), 23 deletions(-)
diff --git a/frag.glsl b/frag.glsl
@@ -6,7 +6,6 @@ out vec4 colour;
uniform uvec2 u_screen_dim;
uniform vec2 u_top_left;
uniform vec2 u_bottom_right;
-uniform float u_zoom = 1.0;
vec3 wavelength2rgb(float lambda)
{
@@ -55,7 +54,7 @@ vec3 wavelength2rgb(float lambda)
vec2 map_mandelbrot(vec2 v)
{
- vec2 scale = abs((u_top_left - u_bottom_right) / u_zoom);
+ vec2 scale = abs(u_top_left - u_bottom_right);
v *= scale;
return vec2(u_top_left.x, u_bottom_right.y) + v;
}
diff --git a/main.c b/main.c
@@ -30,6 +30,8 @@ typedef struct { u8 *beg, *end; } Arena;
#define ABS(x) ((x) <= 0 ? -(x) : (x))
#define BETWEEN(x, l, h) ((x) >= (l) && (x) <= (h))
+#define EPS 0.00001f
+
#include "util.c"
#ifdef __unix__
@@ -48,9 +50,10 @@ static struct {
u32 vao, vbo;
i32 pid;
i32 height, width;
- i32 u_screen_dim, u_zoom, u_top_left, u_bottom_right;
- f32 zoom;
+ i32 u_screen_dim, u_top_left, u_bottom_right;
+ v2 dP;
Rect boundary;
+ f32 zoom;
Colour clear_colour;
} g_glctx;
@@ -70,6 +73,12 @@ move_rect(Rect r, v2 delta)
return r;
}
+static v2
+sub_v2(v2 a, v2 b)
+{
+ return (v2){ .x = a.x - b.x, .y = a.y - b.y };
+}
+
static void
debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, const void *data)
{
@@ -104,8 +113,11 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 action, i32 mod)
{
(void)sc;
- f32 delta = (mod & GLFW_MOD_SHIFT) ? 0.25 : 0.05;
- delta /= g_glctx.zoom;
+ f32 scale = (mod & GLFW_MOD_SHIFT) ? 1 : 0.5;
+
+ v2 dP = sub_v2(g_glctx.boundary.top_left, g_glctx.boundary.bottom_right);
+ dP.x *= -scale; //g_glctx.zoom;
+ dP.y *= scale; //g_glctx.zoom;
switch (key) {
case GLFW_KEY_ESCAPE:
@@ -114,19 +126,27 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 action, i32 mod)
break;
case GLFW_KEY_W:
if (action == GLFW_PRESS || action == GLFW_REPEAT)
- g_glctx.boundary = move_rect(g_glctx.boundary, (v2){.y = delta});
+ g_glctx.dP.y = dP.y;
+ else if (action == GLFW_RELEASE)
+ g_glctx.dP.y = 0;
break;
case GLFW_KEY_A:
if (action == GLFW_PRESS || action == GLFW_REPEAT)
- g_glctx.boundary = move_rect(g_glctx.boundary, (v2){.x = -delta});
+ g_glctx.dP.x = -dP.x;
+ else if (action == GLFW_RELEASE)
+ g_glctx.dP.x = 0;
break;
case GLFW_KEY_S:
if (action == GLFW_PRESS || action == GLFW_REPEAT)
- g_glctx.boundary = move_rect(g_glctx.boundary, (v2){.y = -delta});
+ g_glctx.dP.y = -dP.y;
+ else if (action == GLFW_RELEASE)
+ g_glctx.dP.y = 0;
break;
case GLFW_KEY_D:
if (action == GLFW_PRESS || action == GLFW_REPEAT)
- g_glctx.boundary = move_rect(g_glctx.boundary, (v2){.x = delta});
+ g_glctx.dP.x = dP.x;
+ else if (action == GLFW_RELEASE)
+ g_glctx.dP.x = 0;
break;
}
}
@@ -134,9 +154,19 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 action, i32 mod)
static void
scroll_callback(GLFWwindow *win, f64 xdelta, f64 ydelta)
{
- f32 scale = glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) ? 5 : 1;
- g_glctx.zoom += scale * ydelta;
- if (g_glctx.zoom < 1.0) g_glctx.zoom = 1.0;
+ v2 delta = sub_v2(g_glctx.boundary.top_left, g_glctx.boundary.bottom_right);
+
+ f32 scale = glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) ? 0.2 : 0.05;
+
+ g_glctx.zoom += ydelta * 1/scale;
+ if (g_glctx.zoom < 1) g_glctx.zoom = 1;
+
+ delta.x = ABS(delta.x) * scale * 0.5 * ydelta;
+ delta.y = ABS(delta.y) * scale * 0.5 * ydelta;
+ g_glctx.boundary.top_left.x += delta.x;
+ g_glctx.boundary.top_left.y -= delta.y;
+ g_glctx.boundary.bottom_right.x -= delta.x;
+ g_glctx.boundary.bottom_right.y += delta.y;
}
static void
@@ -155,8 +185,8 @@ mouse_button_callback(GLFWwindow *win, i32 btn, i32 act, i32 mod)
#endif
if (btn == GLFW_MOUSE_BUTTON_RIGHT && act == GLFW_PRESS) {
- g_glctx.zoom = 1;
g_glctx.boundary = default_boundary;
+ g_glctx.dP = (v2){0};
}
}
@@ -213,7 +243,7 @@ spawn_window(void)
glfwMakeContextCurrent(g_glctx.window);
/* disable vsync */
- glfwSwapInterval(0);
+ //glfwSwapInterval(0);
glfwSetFramebufferSizeCallback(g_glctx.window, fb_callback);
glfwSetKeyCallback(g_glctx.window, key_callback);
@@ -292,7 +322,6 @@ static void
validate_uniforms(void)
{
g_glctx.u_screen_dim = glGetUniformLocation(g_glctx.pid, "u_screen_dim");
- g_glctx.u_zoom = glGetUniformLocation(g_glctx.pid, "u_zoom");
g_glctx.u_top_left = glGetUniformLocation(g_glctx.pid, "u_top_left");
g_glctx.u_bottom_right = glGetUniformLocation(g_glctx.pid, "u_bottom_right");
}
@@ -302,6 +331,8 @@ main(void)
{
Arena memory = get_arena();
+ g_glctx.boundary = default_boundary;
+
if (!glfwInit())
return -1;
glfwSetErrorCallback(error_callback);
@@ -324,8 +355,6 @@ main(void)
}
glUseProgram(g_glctx.pid);
validate_uniforms();
- g_glctx.zoom = 1.0;
- g_glctx.boundary = default_boundary;
u32 fcount = 0;
f32 last_time = 0;
@@ -336,11 +365,13 @@ main(void)
f32 dt = current_time - last_time;
last_time = current_time;
if (++fcount > 1000) {
- printf("FPS: %0.03f | dt = %0.03f [ms] | zoom = %0.01f\n"
+ printf("FPS: %0.03f | dt = %0.03f [ms]\n"
"bounds = { { %0.04f, %0.04f }, { %0.04f, %0.04f } }\n",
- 1 / dt, dt * 1e3, g_glctx.boundary.top_left.x,
- g_glctx.boundary.top_left.y, g_glctx.boundary.bottom_right.x,
- g_glctx.boundary.bottom_right.y, g_glctx.zoom);
+ 1 / dt, dt * 1e3,
+ g_glctx.boundary.top_left.x,
+ g_glctx.boundary.top_left.y,
+ g_glctx.boundary.bottom_right.x,
+ g_glctx.boundary.bottom_right.y);
fcount = 0;
}
@@ -361,10 +392,15 @@ main(void)
}
}
+ v2 v = g_glctx.dP;
+ v2 delta;
+ delta.x = v.x * dt;
+ delta.y = v.y * dt;
+ g_glctx.boundary = move_rect(g_glctx.boundary, delta);
+
glUniform2fv(g_glctx.u_top_left, 1, (f32 *)&g_glctx.boundary.top_left);
glUniform2fv(g_glctx.u_bottom_right, 1, (f32 *)&g_glctx.boundary.bottom_right);
glUniform2ui(g_glctx.u_screen_dim, g_glctx.width, g_glctx.height);
- glUniform1f(g_glctx.u_zoom, g_glctx.zoom);
clear_colour(g_glctx.clear_colour);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glfwSwapBuffers(g_glctx.window);