fractorb

changeset 3:f440ecffc45a tip

trying to draw the orbit in the shader
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 26 Nov 2017 14:49:34 +0200
parents 03e8b9a5031d
children
files mbrot.glsl src/main.c
diffstat 2 files changed, 115 insertions(+), 11 deletions(-) [+]
line diff
     1.1 --- a/mbrot.glsl	Mon Nov 20 03:53:02 2017 +0200
     1.2 +++ b/mbrot.glsl	Sun Nov 26 14:49:34 2017 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  // vi:ft=glsl:
     1.5 -#define ITER	96
     1.6 +#define ITER	128
     1.7  
     1.8  uniform float view_scale;
     1.9  uniform vec2 view_center;
    1.10 @@ -7,6 +7,7 @@
    1.11  
    1.12  float mbrot_dist_point(in vec2 c, in vec2 p)
    1.13  {
    1.14 +	vec2 pixpos = c;
    1.15  	vec2 z = c;
    1.16  	float mindist_sq = 8192.0;
    1.17  
    1.18 @@ -15,18 +16,59 @@
    1.19  		float y = (z.x * z.y + z.x * z.y) + c.y;
    1.20  
    1.21  		z = vec2(x, y);
    1.22 -		vec2 dir = z - seed;
    1.23 +		vec2 dir = z - p;
    1.24  		mindist_sq = min(mindist_sq, dot(dir, dir)); 
    1.25  	}
    1.26  
    1.27 -	return sqrt(mindist_sq);
    1.28 +	return mindist_sq;
    1.29 +}
    1.30 +
    1.31 +float line_dist_sq(in vec2 a, in vec2 b, in vec2 p)
    1.32 +{
    1.33 +	vec2 dir = b - a;
    1.34 +	vec2 pvec = p - a;
    1.35 +	float t = dot(dir, pvec);
    1.36 +
    1.37 +	if(t < 0.0) return dot(pvec, pvec);
    1.38 +	if(t > 1.0) return dot(p - b, p - b);
    1.39 +
    1.40 +	vec2 ppt = a + dir * t;
    1.41 +	vec2 lpvec = p - ppt;
    1.42 +	return dot(lpvec, lpvec);
    1.43 +}
    1.44 +
    1.45 +float mbrot_orbit_dist(in vec2 c, in vec2 p)
    1.46 +{
    1.47 +	vec2 pixpos = c;
    1.48 +	vec2 z = c;
    1.49 +	float mindist_sq = 8192.0;
    1.50 +
    1.51 +	for(int i=0; i<ITER; i++) {
    1.52 +		float x = (z.x * z.x - z.y * z.y) + c.x;
    1.53 +		float y = (z.x * z.y + z.x * z.y) + c.y;
    1.54 +		vec2 next = vec2(x, y);
    1.55 +
    1.56 +		float dist_sq = line_dist_sq(z, next, p);
    1.57 +		mindist_sq = min(mindist_sq, dist_sq); 
    1.58 +
    1.59 +		z = next;
    1.60 +	}
    1.61 +
    1.62 +	return mindist_sq;
    1.63  }
    1.64  
    1.65  void main()
    1.66  {
    1.67  	vec2 c = gl_TexCoord[0].xy;
    1.68 -	float m = 1.0 - mbrot_dist_point(c, vec2(0.0, 0.0));
    1.69 +	float pdist_sq;
    1.70 +	float m = 1.0 - min(sqrt(mbrot_dist_point(c, seed)), 1.0);
    1.71  
    1.72 +#ifdef PLOT_ORBIT
    1.73 +	float orb_dist = sqrt(mbrot_orbit_dist(seed, c));
    1.74 +	vec3 orbcol = vec3(0.001 / orb_dist, 0.0, 0.0);
    1.75 +	gl_FragColor.rgb = vec3(m, m, m) / 2.0 + orbcol;
    1.76 +#else
    1.77  	gl_FragColor.rgb = vec3(m, m, m);
    1.78 +#endif
    1.79  	gl_FragColor.a = 1.0;
    1.80  }
     2.1 --- a/src/main.c	Mon Nov 20 03:53:02 2017 +0200
     2.2 +++ b/src/main.c	Sun Nov 26 14:49:34 2017 +0200
     2.3 @@ -8,6 +8,17 @@
     2.4  #include <GL/glut.h>
     2.5  #include "sdr.h"
     2.6  
     2.7 +enum {
     2.8 +	SDR_LINE_DIST_BIT = 1,
     2.9 +	SDR_PLOT_ORBIT_BIT = 2
    2.10 +};
    2.11 +const char *sdrdef[] = {
    2.12 +	"#define LINE_DIST\n",
    2.13 +	"#define PLOT_ORBIT\n"
    2.14 +};
    2.15 +#define NUM_SDR_BITS	(sizeof sdrdef / sizeof *sdrdef)
    2.16 +#define NUM_SHADERS		(1 << NUM_SDR_BITS)
    2.17 +
    2.18  int init(void);
    2.19  void cleanup(void);
    2.20  void disp(void);
    2.21 @@ -21,11 +32,12 @@
    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 +static unsigned int prog_mbrot[NUM_SHADERS];
    2.27  
    2.28  static float view_center[2] = {0.7, 0.0};
    2.29  static float view_scale = 1.2;
    2.30  
    2.31 +static unsigned int sdrflags;
    2.32  
    2.33  int main(int argc, char **argv)
    2.34  {
    2.35 @@ -53,17 +65,57 @@
    2.36  
    2.37  int init(void)
    2.38  {
    2.39 +	int i, j;
    2.40 +	unsigned int vs = 0, ps[NUM_SHADERS] = {0};
    2.41 +
    2.42  	glewInit();
    2.43  
    2.44 -	if(!(prog_mbrot = create_program_load("vertex.glsl", "mbrot.glsl"))) {
    2.45 +	if(!(vs = load_vertex_shader("vertex.glsl"))) {
    2.46  		return -1;
    2.47  	}
    2.48 +
    2.49 +	for(i=0; i<NUM_SHADERS; i++) {
    2.50 +		clear_shader_header(GL_FRAGMENT_SHADER);
    2.51 +		for(j=0; j<NUM_SDR_BITS; j++) {
    2.52 +			if(i & (1 << j)) {
    2.53 +				add_shader_header(GL_FRAGMENT_SHADER, sdrdef[j]);
    2.54 +			}
    2.55 +		}
    2.56 +
    2.57 +		if(!(ps[i] = load_pixel_shader("mbrot.glsl"))) {
    2.58 +			goto err;
    2.59 +		}
    2.60 +
    2.61 +		if(!(prog_mbrot[i] = create_program_link(vs, ps[i], 0))) {
    2.62 +			goto err;
    2.63 +		}
    2.64 +	}
    2.65  	return 0;
    2.66 +
    2.67 +err:
    2.68 +	for(i=0; i<NUM_SHADERS; i++) {
    2.69 +		if(prog_mbrot[i]) {
    2.70 +			free_program(prog_mbrot[i]);
    2.71 +			prog_mbrot[i] = 0;
    2.72 +		}
    2.73 +		if(ps[i]) {
    2.74 +			free_shader(ps[i]);
    2.75 +		}
    2.76 +	}
    2.77 +	if(vs) {
    2.78 +		free_shader(vs);
    2.79 +	}
    2.80 +	return -1;
    2.81  }
    2.82  
    2.83  void cleanup(void)
    2.84  {
    2.85 -	free_program(prog_mbrot);
    2.86 +	int i;
    2.87 +
    2.88 +	for(i=0; i<NUM_SHADERS; i++) {
    2.89 +		free_program(prog_mbrot[i]);
    2.90 +		prog_mbrot[i] = 0;
    2.91 +	}
    2.92  }
    2.93  
    2.94  void pixel_to_complex(float *res, float px, float py)
    2.95 @@ -83,10 +135,10 @@
    2.96  
    2.97  	pixel_to_complex(seed, mouse_x, mouse_y);
    2.98  
    2.99 -	set_uniform_float2(prog_mbrot, "seed", seed[0], seed[1]);
   2.100 -	set_uniform_float(prog_mbrot, "view_scale", view_scale);
   2.101 -	set_uniform_float2(prog_mbrot, "view_center", view_center[0], view_center[1]);
   2.102 -	glUseProgram(prog_mbrot);
   2.103 +	set_uniform_float2(prog_mbrot[sdrflags], "seed", seed[0], seed[1]);
   2.104 +	set_uniform_float(prog_mbrot[sdrflags], "view_scale", view_scale);
   2.105 +	set_uniform_float2(prog_mbrot[sdrflags], "view_center", view_center[0], view_center[1]);
   2.106 +	glUseProgram(prog_mbrot[sdrflags]);
   2.107  
   2.108  	glBegin(GL_QUADS);
   2.109  	for(i=0; i<4; i++) {
   2.110 @@ -131,6 +183,16 @@
   2.111  		}
   2.112  		break;
   2.113  
   2.114 +	case ' ':
   2.115 +		sdrflags ^= SDR_LINE_DIST_BIT;
   2.116 +		glutPostRedisplay();
   2.117 +		break;
   2.118 +
   2.119 +	case 'o':
   2.120 +		sdrflags ^= SDR_PLOT_ORBIT_BIT;
   2.121 +		glutPostRedisplay();
   2.122 +		break;
   2.123 +
   2.124  	case '`':
   2.125  		screenshot();
   2.126  		break;