fractorb
changeset 1:436f82447c44
pan/scale and min orbit distance from point drawing
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 19 Nov 2017 00:57:39 +0200 |
parents | 6e849d7377ff |
children | 03e8b9a5031d |
files | mbrot.glsl src/main.c |
diffstat | 2 files changed, 99 insertions(+), 17 deletions(-) [+] |
line diff
1.1 --- a/mbrot.glsl Sat Nov 18 20:04:16 2017 +0200 1.2 +++ b/mbrot.glsl Sun Nov 19 00:57:39 2017 +0200 1.3 @@ -3,6 +3,7 @@ 1.4 1.5 uniform float view_scale; 1.6 uniform vec2 view_center; 1.7 +uniform vec2 seed; 1.8 1.9 float mbrot_dist_point(in vec2 c, in vec2 p) 1.10 { 1.11 @@ -14,7 +15,8 @@ 1.12 float y = (z.x * z.y + z.x * z.y) + c.y; 1.13 1.14 z = vec2(x, y); 1.15 - mindist_sq = min(mindist_sq, dot(z, z)); 1.16 + vec2 dir = z - seed; 1.17 + mindist_sq = min(mindist_sq, dot(dir, dir)); 1.18 } 1.19 1.20 return sqrt(mindist_sq); 1.21 @@ -22,7 +24,7 @@ 1.22 1.23 void main() 1.24 { 1.25 - vec2 c = gl_TexCoord[0].xy * view_scale - view_center; 1.26 + vec2 c = gl_TexCoord[0].xy; 1.27 float m = 1.0 - mbrot_dist_point(c, vec2(0.0, 0.0)); 1.28 1.29 gl_FragColor.rgb = vec3(m, m, m);
2.1 --- a/src/main.c Sat Nov 18 20:04:16 2017 +0200 2.2 +++ b/src/main.c Sun Nov 19 00:57:39 2017 +0200 2.3 @@ -1,5 +1,6 @@ 2.4 #include <stdio.h> 2.5 #include <stdlib.h> 2.6 +#include <math.h> 2.7 #include <GL/glew.h> 2.8 #include <GL/glut.h> 2.9 #include "sdr.h" 2.10 @@ -8,14 +9,20 @@ 2.11 void cleanup(void); 2.12 void disp(void); 2.13 void reshape(int x, int y); 2.14 -void keyb(unsigned char key, int x, int y); 2.15 +void keydown(unsigned char key, int x, int y); 2.16 +void keyup(unsigned char key, int x, int y); 2.17 void mouse(int bn, int st, int x, int y); 2.18 void motion(int x, int y); 2.19 2.20 -static float aspect; 2.21 -static int mouse_x, mouse_y; 2.22 +static int win_width = 1280, win_height = 800; 2.23 +static float win_aspect; 2.24 +static int mouse_x = 640, mouse_y = 400; 2.25 static unsigned int prog_mbrot; 2.26 2.27 +static float view_center[2] = {0.7, 0.0}; 2.28 +static float view_scale = 1.2; 2.29 + 2.30 + 2.31 int main(int argc, char **argv) 2.32 { 2.33 glutInit(&argc, argv); 2.34 @@ -25,7 +32,8 @@ 2.35 2.36 glutDisplayFunc(disp); 2.37 glutReshapeFunc(reshape); 2.38 - glutKeyboardFunc(keyb); 2.39 + glutKeyboardFunc(keydown); 2.40 + glutKeyboardUpFunc(keyup); 2.41 glutMouseFunc(mouse); 2.42 glutMotionFunc(motion); 2.43 2.44 @@ -46,8 +54,6 @@ 2.45 if(!(prog_mbrot = create_program_load("vertex.glsl", "mbrot.glsl"))) { 2.46 return -1; 2.47 } 2.48 - set_uniform_float(prog_mbrot, "view_scale", 1.1); 2.49 - set_uniform_float2(prog_mbrot, "view_center", 0.7, 0); 2.50 return 0; 2.51 } 2.52 2.53 @@ -56,15 +62,35 @@ 2.54 free_program(prog_mbrot); 2.55 } 2.56 2.57 +void pixel_to_complex(float *res, float px, float py) 2.58 +{ 2.59 + float u = (2.0 * px / win_width - 1.0) * win_aspect; 2.60 + float v = 2.0 * py / win_height - 1.0; 2.61 + res[0] = u * view_scale - view_center[0]; 2.62 + res[1] = v * view_scale - view_center[1]; 2.63 +} 2.64 + 2.65 void disp(void) 2.66 { 2.67 + int i; 2.68 + float seed[2]; 2.69 + static const float verts[][2] = {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}; 2.70 + static const float corners[][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}}; 2.71 + 2.72 + pixel_to_complex(seed, mouse_x, mouse_y); 2.73 + 2.74 + set_uniform_float2(prog_mbrot, "seed", seed[0], seed[1]); 2.75 + set_uniform_float(prog_mbrot, "view_scale", view_scale); 2.76 + set_uniform_float2(prog_mbrot, "view_center", view_center[0], view_center[1]); 2.77 glUseProgram(prog_mbrot); 2.78 2.79 glBegin(GL_QUADS); 2.80 - glTexCoord2f(-aspect, 1); glVertex2f(-1, -1); 2.81 - glTexCoord2f(aspect, 1); glVertex2f(1, -1); 2.82 - glTexCoord2f(aspect, -1); glVertex2f(1, 1); 2.83 - glTexCoord2f(-aspect, -1); glVertex2f(-1, 1); 2.84 + for(i=0; i<4; i++) { 2.85 + float bv[2]; 2.86 + pixel_to_complex(bv, (win_width - 1) * corners[i][0], (win_height - 1) * corners[i][1]); 2.87 + glTexCoord2f(bv[0], bv[1]); 2.88 + glVertex2f(verts[i][0], verts[i][1]); 2.89 + } 2.90 glEnd(); 2.91 2.92 glutSwapBuffers(); 2.93 @@ -74,22 +100,76 @@ 2.94 { 2.95 glViewport(0, 0, x, y); 2.96 2.97 - aspect = (float)x / (float)y; 2.98 + win_aspect = (float)x / (float)y; 2.99 + win_width = x; 2.100 + win_height = y; 2.101 } 2.102 2.103 -void keyb(unsigned char key, int x, int y) 2.104 +static int keystate[256]; 2.105 + 2.106 +void keydown(unsigned char key, int x, int y) 2.107 { 2.108 - if(key == 27) { 2.109 + static int fullscreen; 2.110 + static int prev_width, prev_height; 2.111 + 2.112 + switch(key) { 2.113 + case 27: 2.114 exit(0); 2.115 + 2.116 + case 'f': 2.117 + fullscreen = !fullscreen; 2.118 + if(fullscreen) { 2.119 + prev_width = win_width; 2.120 + prev_height = win_height; 2.121 + glutFullScreen(); 2.122 + } else { 2.123 + glutReshapeWindow(prev_width, prev_height); 2.124 + } 2.125 + break; 2.126 + 2.127 + default: 2.128 + break; 2.129 } 2.130 + keystate[key] = 1; 2.131 } 2.132 2.133 +void keyup(unsigned char key, int x, int y) 2.134 +{ 2.135 + keystate[key] = 0; 2.136 +} 2.137 + 2.138 +static int prev_x, prev_y; 2.139 +static int bnstate[8]; 2.140 + 2.141 void mouse(int bn, int st, int x, int y) 2.142 { 2.143 + prev_x = x; 2.144 + prev_y = y; 2.145 + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN ? 1 : 0; 2.146 } 2.147 2.148 void motion(int x, int y) 2.149 { 2.150 - mouse_x = x; 2.151 - mouse_y = y; 2.152 + int dx = x - prev_x; 2.153 + int dy = y - prev_y; 2.154 + prev_x = x; 2.155 + prev_y = y; 2.156 + 2.157 + if(!(dx | dy)) return; 2.158 + 2.159 + if(bnstate[0]) { 2.160 + if(keystate['s']) { 2.161 + mouse_x = x; 2.162 + mouse_y = y; 2.163 + } else if(keystate['z']) { 2.164 + float s = sqrt(view_scale); 2.165 + view_scale += dy * 0.01 * s; 2.166 + if(view_scale < 1e-8) view_scale = 1e-8; 2.167 + } else { 2.168 + float s = sqrt(view_scale); 2.169 + view_center[0] += 0.01 * dx * s; 2.170 + view_center[1] += 0.01 * dy * s; 2.171 + } 2.172 + glutPostRedisplay(); 2.173 + } 2.174 }