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  }