# HG changeset patch # User John Tsiombikas # Date 1511045859 -7200 # Node ID 436f82447c44b5168919148c3aa7f23aeb6ed075 # Parent 6e849d7377ffcd7a60474014e12099b1bf4098e9 pan/scale and min orbit distance from point drawing diff -r 6e849d7377ff -r 436f82447c44 mbrot.glsl --- a/mbrot.glsl Sat Nov 18 20:04:16 2017 +0200 +++ b/mbrot.glsl Sun Nov 19 00:57:39 2017 +0200 @@ -3,6 +3,7 @@ uniform float view_scale; uniform vec2 view_center; +uniform vec2 seed; float mbrot_dist_point(in vec2 c, in vec2 p) { @@ -14,7 +15,8 @@ float y = (z.x * z.y + z.x * z.y) + c.y; z = vec2(x, y); - mindist_sq = min(mindist_sq, dot(z, z)); + vec2 dir = z - seed; + mindist_sq = min(mindist_sq, dot(dir, dir)); } return sqrt(mindist_sq); @@ -22,7 +24,7 @@ void main() { - vec2 c = gl_TexCoord[0].xy * view_scale - view_center; + vec2 c = gl_TexCoord[0].xy; float m = 1.0 - mbrot_dist_point(c, vec2(0.0, 0.0)); gl_FragColor.rgb = vec3(m, m, m); diff -r 6e849d7377ff -r 436f82447c44 src/main.c --- a/src/main.c Sat Nov 18 20:04:16 2017 +0200 +++ b/src/main.c Sun Nov 19 00:57:39 2017 +0200 @@ -1,5 +1,6 @@ #include #include +#include #include #include #include "sdr.h" @@ -8,14 +9,20 @@ void cleanup(void); void disp(void); void reshape(int x, int y); -void keyb(unsigned char key, int x, int y); +void keydown(unsigned char key, int x, int y); +void keyup(unsigned char key, int x, int y); void mouse(int bn, int st, int x, int y); void motion(int x, int y); -static float aspect; -static int mouse_x, mouse_y; +static int win_width = 1280, win_height = 800; +static float win_aspect; +static int mouse_x = 640, mouse_y = 400; static unsigned int prog_mbrot; +static float view_center[2] = {0.7, 0.0}; +static float view_scale = 1.2; + + int main(int argc, char **argv) { glutInit(&argc, argv); @@ -25,7 +32,8 @@ glutDisplayFunc(disp); glutReshapeFunc(reshape); - glutKeyboardFunc(keyb); + glutKeyboardFunc(keydown); + glutKeyboardUpFunc(keyup); glutMouseFunc(mouse); glutMotionFunc(motion); @@ -46,8 +54,6 @@ if(!(prog_mbrot = create_program_load("vertex.glsl", "mbrot.glsl"))) { return -1; } - set_uniform_float(prog_mbrot, "view_scale", 1.1); - set_uniform_float2(prog_mbrot, "view_center", 0.7, 0); return 0; } @@ -56,15 +62,35 @@ free_program(prog_mbrot); } +void pixel_to_complex(float *res, float px, float py) +{ + float u = (2.0 * px / win_width - 1.0) * win_aspect; + float v = 2.0 * py / win_height - 1.0; + res[0] = u * view_scale - view_center[0]; + res[1] = v * view_scale - view_center[1]; +} + void disp(void) { + int i; + float seed[2]; + static const float verts[][2] = {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}; + static const float corners[][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}}; + + pixel_to_complex(seed, mouse_x, mouse_y); + + set_uniform_float2(prog_mbrot, "seed", seed[0], seed[1]); + set_uniform_float(prog_mbrot, "view_scale", view_scale); + set_uniform_float2(prog_mbrot, "view_center", view_center[0], view_center[1]); glUseProgram(prog_mbrot); glBegin(GL_QUADS); - glTexCoord2f(-aspect, 1); glVertex2f(-1, -1); - glTexCoord2f(aspect, 1); glVertex2f(1, -1); - glTexCoord2f(aspect, -1); glVertex2f(1, 1); - glTexCoord2f(-aspect, -1); glVertex2f(-1, 1); + for(i=0; i<4; i++) { + float bv[2]; + pixel_to_complex(bv, (win_width - 1) * corners[i][0], (win_height - 1) * corners[i][1]); + glTexCoord2f(bv[0], bv[1]); + glVertex2f(verts[i][0], verts[i][1]); + } glEnd(); glutSwapBuffers(); @@ -74,22 +100,76 @@ { glViewport(0, 0, x, y); - aspect = (float)x / (float)y; + win_aspect = (float)x / (float)y; + win_width = x; + win_height = y; } -void keyb(unsigned char key, int x, int y) +static int keystate[256]; + +void keydown(unsigned char key, int x, int y) { - if(key == 27) { + static int fullscreen; + static int prev_width, prev_height; + + switch(key) { + case 27: exit(0); + + case 'f': + fullscreen = !fullscreen; + if(fullscreen) { + prev_width = win_width; + prev_height = win_height; + glutFullScreen(); + } else { + glutReshapeWindow(prev_width, prev_height); + } + break; + + default: + break; } + keystate[key] = 1; } +void keyup(unsigned char key, int x, int y) +{ + keystate[key] = 0; +} + +static int prev_x, prev_y; +static int bnstate[8]; + void mouse(int bn, int st, int x, int y) { + prev_x = x; + prev_y = y; + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN ? 1 : 0; } void motion(int x, int y) { - mouse_x = x; - mouse_y = y; + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(!(dx | dy)) return; + + if(bnstate[0]) { + if(keystate['s']) { + mouse_x = x; + mouse_y = y; + } else if(keystate['z']) { + float s = sqrt(view_scale); + view_scale += dy * 0.01 * s; + if(view_scale < 1e-8) view_scale = 1e-8; + } else { + float s = sqrt(view_scale); + view_center[0] += 0.01 * dx * s; + view_center[1] += 0.01 * dy * s; + } + glutPostRedisplay(); + } }