rayfract

diff src/rayfract.cc @ 8:dfe7c98cf373

added stereo rendering
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 03 Nov 2011 02:18:46 +0200
parents 8a9aa21b32cf
children 628e7084a482
line diff
     1.1 --- a/src/rayfract.cc	Wed Oct 05 02:26:46 2011 +0300
     1.2 +++ b/src/rayfract.cc	Thu Nov 03 02:18:46 2011 +0200
     1.3 @@ -1,5 +1,6 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6 +#include <string.h>
     1.7  #include <math.h>
     1.8  #include <assert.h>
     1.9  #include <GL/glew.h>
    1.10 @@ -11,6 +12,7 @@
    1.11  #define DEG_TO_RAD(x)	(M_PI * (x) / 180.0)
    1.12  
    1.13  void disp();
    1.14 +void render();
    1.15  void reshape(int x, int y);
    1.16  void keyb(unsigned char key, int x, int y);
    1.17  void keyb_up(unsigned char key, int x, int y);
    1.18 @@ -27,6 +29,9 @@
    1.19  static Vector3 get_primary_ray_dir(int x, int y, int w, int h, float vfov_deg);
    1.20  static int round_pow2(int x);
    1.21  
    1.22 +int parse_opt(int argc, char **argv);
    1.23 +
    1.24 +
    1.25  float cam_theta = 0, cam_phi = 0, cam_dist = 4.0;
    1.26  float cam_x, cam_y, cam_z;
    1.27  
    1.28 @@ -39,6 +44,9 @@
    1.29  float reflectivity = 0.2;
    1.30  Vector3 color(0.75, 0.75, 0.75);
    1.31  
    1.32 +int use_stereo;
    1.33 +float eye_sep = 0.5;
    1.34 +
    1.35  int main(int argc, char **argv)
    1.36  {
    1.37  	int xsz, ysz;
    1.38 @@ -47,7 +55,12 @@
    1.39  
    1.40  	glutInitWindowSize(640, 480);
    1.41  	glutInit(&argc, argv);
    1.42 -	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    1.43 +
    1.44 +	if(parse_opt(argc, argv) == -1) {
    1.45 +		return 1;
    1.46 +	}
    1.47 +
    1.48 +	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | (use_stereo ? GLUT_STEREO : 0));
    1.49  	glutCreateWindow("Raytraced Fractals");
    1.50  	xsz = glutGet(GLUT_WINDOW_WIDTH);
    1.51  	ysz = glutGet(GLUT_WINDOW_HEIGHT);
    1.52 @@ -63,13 +76,14 @@
    1.53  	glutSpaceballRotateFunc(sball_rot);
    1.54  	glutSpaceballButtonFunc(sball_button);
    1.55  
    1.56 -	glEnable(GL_DEPTH_TEST);
    1.57 -	glEnable(GL_LIGHTING);
    1.58 -	glEnable(GL_LIGHT0);
    1.59 -	glEnable(GL_CULL_FACE);
    1.60 +	if(getenv("STEREO_METHOD") && strcmp(getenv("STEREO_METHOD"), "sequential") == 0) {
    1.61 +		glutIdleFunc(glutPostRedisplay);
    1.62 +	}
    1.63  
    1.64  	glewInit();
    1.65  
    1.66 +	glEnable(GL_CULL_FACE);
    1.67 +
    1.68  	if(load_shader() == -1) {
    1.69  		return 1;
    1.70  	}
    1.71 @@ -102,8 +116,6 @@
    1.72  
    1.73  void disp()
    1.74  {
    1.75 -	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    1.76 -
    1.77  	glMatrixMode(GL_MODELVIEW);
    1.78  	glLoadIdentity();
    1.79  	glTranslatef(cam_x, cam_y, -cam_z);
    1.80 @@ -121,11 +133,35 @@
    1.81  	set_uniform_float(sdr, "err_thres", err_thres);
    1.82  	set_uniform_float3(sdr, "diffuse_color", color.x, color.y, color.z);
    1.83  
    1.84 +	glBindTexture(GL_TEXTURE_2D, ray_tex);
    1.85 +
    1.86 +
    1.87 +	if(use_stereo) {
    1.88 +		glDrawBuffer(GL_BACK_LEFT);
    1.89 +		set_uniform_float(sdr, "eye_offs", -eye_sep / 2.0);
    1.90 +	} else {
    1.91 +		set_uniform_float(sdr, "eye_offs", 0);
    1.92 +	}
    1.93 +
    1.94 +	render();
    1.95 +
    1.96 +	if(use_stereo) {
    1.97 +		glDrawBuffer(GL_BACK_RIGHT);
    1.98 +
    1.99 +		set_uniform_float(sdr, "eye_offs", eye_sep / 2.0);
   1.100 +		render();
   1.101 +	}
   1.102 +
   1.103 +	glutSwapBuffers();
   1.104 +	assert(glGetError() == GL_NO_ERROR);
   1.105 +}
   1.106 +
   1.107 +void render()
   1.108 +{
   1.109  	glMatrixMode(GL_TEXTURE);
   1.110  	glPushMatrix();
   1.111  	glScalef(tex_scale.x, tex_scale.y, 1.0);
   1.112  
   1.113 -	glBindTexture(GL_TEXTURE_2D, ray_tex);
   1.114  	glEnable(GL_TEXTURE_2D);
   1.115  	bind_program(sdr);
   1.116  
   1.117 @@ -144,9 +180,6 @@
   1.118  	glPopMatrix();
   1.119  
   1.120  	gui_draw();
   1.121 -
   1.122 -	glutSwapBuffers();
   1.123 -	assert(glGetError() == GL_NO_ERROR);
   1.124  }
   1.125  
   1.126  void reshape(int x, int y)
   1.127 @@ -206,6 +239,11 @@
   1.128  		glutPostRedisplay();
   1.129  		break;
   1.130  
   1.131 +	case 'S':
   1.132 +		use_stereo = !use_stereo;
   1.133 +		glutPostRedisplay();
   1.134 +		break;
   1.135 +
   1.136  	case 'r':
   1.137  		reflectivity = reflectivity > 0.0 ? 0.0 : 0.6;
   1.138  		set_uniform_float(sdr, "reflectivity", reflectivity);
   1.139 @@ -221,6 +259,19 @@
   1.140  		}
   1.141  		break;
   1.142  
   1.143 +	case '[':
   1.144 +		eye_sep -= 0.1;
   1.145 +		printf("eye separation: %f\n", eye_sep);
   1.146 +		glutPostRedisplay();
   1.147 +		break;
   1.148 +
   1.149 +	case ']':
   1.150 +		eye_sep += 0.1;
   1.151 +		printf("eye separation: %f\n", eye_sep);
   1.152 +		glutPostRedisplay();
   1.153 +		break;
   1.154 +
   1.155 +
   1.156  	case '\n':
   1.157  	case '\r':
   1.158  		printf("(%.3f %+.3fi %+.3fj %+.3fk) i:%d err: %.4f cam(theta: %.2f phi: %.2f rad: %.2f)\n", seed.w,
   1.159 @@ -411,3 +462,29 @@
   1.160  	x = (x >> 16) | x;
   1.161  	return x + 1;
   1.162  }
   1.163 +
   1.164 +int parse_opt(int argc, char **argv)
   1.165 +{
   1.166 +	int i;
   1.167 +
   1.168 +	for(i=1; i<argc; i++) {
   1.169 +		if(argv[i][0] == '-' && argv[i][2] == 0) {
   1.170 +			switch(argv[i][1]) {
   1.171 +			case 's':
   1.172 +				use_stereo = !use_stereo;
   1.173 +				break;
   1.174 +
   1.175 +			default:
   1.176 +				goto invalid;
   1.177 +			}
   1.178 +		} else {
   1.179 +			goto invalid;
   1.180 +		}
   1.181 +	}
   1.182 +
   1.183 +	return 0;
   1.184 +
   1.185 +invalid:
   1.186 +	fprintf(stderr, "invalid option: %s\n", argv[i]);
   1.187 +	return -1;
   1.188 +}