oculus1

diff src/main.cc @ 16:f3672317e5c2

made teapots many sizes and more colorful, added phong shader
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Sep 2013 05:22:48 +0300
parents cceffea995a4
children 1b107de821c1 251bc9e2e4a1
line diff
     1.1 --- a/src/main.cc	Sat Sep 21 04:15:20 2013 +0300
     1.2 +++ b/src/main.cc	Sat Sep 21 05:22:48 2013 +0300
     1.3 @@ -5,14 +5,18 @@
     1.4  #include "opengl.h"
     1.5  #include "vr.h"
     1.6  #include "camera.h"
     1.7 +#include "sdr.h"
     1.8  
     1.9  static bool init();
    1.10  static void cleanup();
    1.11  static void disp();
    1.12 +static void disp_vr();
    1.13  static void draw_scene();
    1.14 -static void draw_teapot();
    1.15 +static void draw_teapot(float size);
    1.16  static void draw_squares();
    1.17  static void draw_grid(float size, float spacing);
    1.18 +static void toggle_mouselook();
    1.19 +static void toggle_fullscreen();
    1.20  static void idle();
    1.21  static void reshape(int x, int y);
    1.22  static void keyb(unsigned char key, int x, int y);
    1.23 @@ -26,13 +30,16 @@
    1.24  static VRFpsCamera cam;
    1.25  static int width, height;
    1.26  static bool use_vr = false;
    1.27 -static bool mouselook = false;
    1.28  
    1.29  static bool keystate[256];
    1.30  
    1.31  static int rtarg_width, rtarg_height;
    1.32  static unsigned int fbo, tex[2], zbuf;
    1.33  
    1.34 +static unsigned int teapot_sdr;
    1.35 +
    1.36 +static bool fullscreen_pending;
    1.37 +
    1.38  int main(int argc, char **argv)
    1.39  {
    1.40  	glutInitWindowSize(1280, 800);
    1.41 @@ -48,7 +55,7 @@
    1.42  	width = glutGet(GLUT_WINDOW_WIDTH);
    1.43  	height = glutGet(GLUT_WINDOW_HEIGHT);
    1.44  
    1.45 -	glutDisplayFunc(disp);
    1.46 +	glutDisplayFunc(use_vr ? disp_vr : disp);
    1.47  	glutIdleFunc(idle);
    1.48  	glutReshapeFunc(reshape);
    1.49  	glutKeyboardFunc(keyb);
    1.50 @@ -76,6 +83,7 @@
    1.51  
    1.52  	glEnable(GL_LIGHT0);
    1.53  	glEnable(GL_LIGHTING);
    1.54 +	glEnable(GL_NORMALIZE);
    1.55  
    1.56  	// y = height of neck
    1.57  	cam.input_move(0, 1.65, 0);
    1.58 @@ -93,39 +101,38 @@
    1.59  
    1.60  		rtarg_width = (xsz + xsz / 2) / 2;
    1.61  		rtarg_height = ysz + ysz / 2;
    1.62 -	} else {
    1.63 -		rtarg_width = width;
    1.64 -		rtarg_height = height;
    1.65 +
    1.66 +		printf("render target: %dx%d\n", rtarg_width, rtarg_height);
    1.67 +
    1.68 +		// create render targets for each eye
    1.69 +		GLenum wrap_mode = GL_CLAMP_TO_EDGE;
    1.70 +		if(!GLEW_SGIS_texture_edge_clamp) {
    1.71 +			wrap_mode = GL_CLAMP;
    1.72 +		}
    1.73 +
    1.74 +		glGenTextures(2, tex);
    1.75 +		for(int i=0; i<2; i++) {
    1.76 +			glBindTexture(GL_TEXTURE_2D, tex[i]);
    1.77 +			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1.78 +			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.79 +			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode);
    1.80 +			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode);
    1.81 +			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    1.82 +		}
    1.83 +
    1.84 +		// create the depth render buffer
    1.85 +		glGenRenderbuffers(1, &zbuf);
    1.86 +		glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
    1.87 +		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height);
    1.88 +
    1.89 +		// create the FBO
    1.90 +		glGenFramebuffers(1, &fbo);
    1.91 +		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    1.92 +		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
    1.93 +		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
    1.94  	}
    1.95  
    1.96 -	printf("render target: %dx%d\n", rtarg_width, rtarg_height);
    1.97 -
    1.98 -	// create render targets for each eye
    1.99 -	GLenum wrap_mode = GL_CLAMP_TO_EDGE;
   1.100 -	if(!GLEW_SGIS_texture_edge_clamp) {
   1.101 -		wrap_mode = GL_CLAMP;
   1.102 -	}
   1.103 -
   1.104 -	glGenTextures(2, tex);
   1.105 -	for(int i=0; i<2; i++) {
   1.106 -		glBindTexture(GL_TEXTURE_2D, tex[i]);
   1.107 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1.108 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.109 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode);
   1.110 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode);
   1.111 -		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
   1.112 -	}
   1.113 -
   1.114 -	// create the depth render buffer
   1.115 -	glGenRenderbuffers(1, &zbuf);
   1.116 -	glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
   1.117 -	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height);
   1.118 -
   1.119 -	// create the FBO
   1.120 -	glGenFramebuffers(1, &fbo);
   1.121 -	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
   1.122 -	glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
   1.123 -	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
   1.124 +	teapot_sdr = create_program_load("sdr/phong.v.glsl", "sdr/phong.p.glsl");
   1.125  
   1.126  	return true;
   1.127  }
   1.128 @@ -159,6 +166,7 @@
   1.129  	cam.input_move(inpv.x, inpv.y, inpv.z);
   1.130  }
   1.131  
   1.132 +// display function used in regular mode
   1.133  static void disp()
   1.134  {
   1.135  	static long prev_msec;
   1.136 @@ -167,12 +175,33 @@
   1.137  	prev_msec = msec;
   1.138  
   1.139  	handle_input(dt);
   1.140 +
   1.141 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   1.142 +
   1.143 +	glMatrixMode(GL_PROJECTION);
   1.144 +	glLoadIdentity();
   1.145 +	gluPerspective(45, (float)width / (float)height, 0.25, 500.0);
   1.146 +
   1.147 +	glMatrixMode(GL_MODELVIEW);
   1.148 +	glLoadIdentity();
   1.149 +	cam.use_inverse();
   1.150 +	draw_scene();
   1.151 +
   1.152 +	glutSwapBuffers();
   1.153 +	assert(glGetError() == GL_NO_ERROR);
   1.154 +}
   1.155 +
   1.156 +// display function used in VR mode
   1.157 +static void disp_vr()
   1.158 +{
   1.159 +	static long prev_msec;
   1.160 +	long msec = glutGet(GLUT_ELAPSED_TIME);
   1.161 +	float dt = (msec - prev_msec) / 1000.0;
   1.162 +	prev_msec = msec;
   1.163 +
   1.164 +	handle_input(dt);
   1.165  	cam.track_vr();
   1.166  
   1.167 -	/*glMatrixMode(GL_PROJECTION);
   1.168 -	glLoadIdentity();
   1.169 -	float fov = RAD_TO_DEG(vr_get_fov());
   1.170 -	gluPerspective(fov, (float)rtarg_width / (float)rtarg_height, 0.25, 500.0);*/
   1.171  	float proj_matrix[16];
   1.172  
   1.173  	float eye_dist = vr_get_eyedist();
   1.174 @@ -230,7 +259,6 @@
   1.175  	glFinish();
   1.176  }
   1.177  
   1.178 -
   1.179  static void draw_scene()
   1.180  {
   1.181  	float lpos[] = {0, 60, 0, 1};
   1.182 @@ -238,21 +266,33 @@
   1.183  
   1.184  	draw_grid(50.0, 2.5);
   1.185  
   1.186 -	static Vector2 teapos[] = {
   1.187 -		Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8)
   1.188 +	static const Vector2 teapos[] = {
   1.189 +		Vector2(-8, -8), Vector2(8, -8), Vector2(8, 8), Vector2(-8, 8)
   1.190  	};
   1.191 +	static const float teasize[] = { 1.0, 2.0, 1.7, 1.4 };
   1.192 +	static const float teacolor[][4] = {
   1.193 +		{1.0, 0.4, 0.2, 1.0}, {0.2, 0.35, 1.0, 1.0}, {1.0, 0.9, 0.3, 1.0}, {0.3, 1.0, 0.4, 1.0}
   1.194 +	};
   1.195 +	static const float spec[] = {0.8, 0.8, 0.8, 1.0};
   1.196 +
   1.197 +	glUseProgram(teapot_sdr);
   1.198  
   1.199  	for(int i=0; i<4; i++) {
   1.200 +		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, teacolor[i]);
   1.201 +		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
   1.202 +		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.0);
   1.203 +
   1.204  		glPushMatrix();
   1.205  		glTranslatef(teapos[i].x, 0, teapos[i].y);
   1.206 -		draw_teapot();
   1.207 +		draw_teapot(teasize[i]);
   1.208  		glPopMatrix();
   1.209  	}
   1.210 +	glUseProgram(0);
   1.211  
   1.212  	draw_squares();
   1.213  }
   1.214  
   1.215 -static void draw_teapot()
   1.216 +static void draw_teapot(float size)
   1.217  {
   1.218  	static int tealist;
   1.219  
   1.220 @@ -263,9 +303,16 @@
   1.221  		glEndList();
   1.222  	}
   1.223  
   1.224 +	glMatrixMode(GL_MODELVIEW);
   1.225 +	glPushMatrix();
   1.226 +	glScalef(size, size, size);
   1.227 +	glTranslatef(0, 0.73, 0);
   1.228 +
   1.229  	glFrontFace(GL_CW);
   1.230  	glCallList(tealist);
   1.231  	glFrontFace(GL_CCW);
   1.232 +
   1.233 +	glPopMatrix();
   1.234  }
   1.235  
   1.236  static void draw_squares()
   1.237 @@ -338,8 +385,82 @@
   1.238  	glPopAttrib();
   1.239  }
   1.240  
   1.241 +static bool mouselook;
   1.242 +
   1.243 +static void toggle_mouselook()
   1.244 +{
   1.245 +	mouselook = !mouselook;
   1.246 +	if(mouselook) {
   1.247 +		glutPassiveMotionFunc(passive);
   1.248 +		glutSetCursor(GLUT_CURSOR_NONE);
   1.249 +		glutWarpPointer(width / 2, height / 2);
   1.250 +	} else {
   1.251 +		glutPassiveMotionFunc(0);
   1.252 +		glutSetCursor(GLUT_CURSOR_INHERIT);
   1.253 +	}
   1.254 +}
   1.255 +
   1.256 +static void toggle_fullscreen()
   1.257 +{
   1.258 +	static bool fullscreen;
   1.259 +	static int prev_x, prev_y;
   1.260 +	static int prev_xsz, prev_ysz;
   1.261 +
   1.262 +	fullscreen = !fullscreen;
   1.263 +
   1.264 +	if(fullscreen) {
   1.265 +		prev_x = glutGet(GLUT_WINDOW_X);
   1.266 +		prev_y = glutGet(GLUT_WINDOW_Y);
   1.267 +		prev_xsz = width;
   1.268 +		prev_ysz = height;
   1.269 +
   1.270 +		if(use_vr) {
   1.271 +			// go fullscreen to the correct monitor
   1.272 +			int x, y;
   1.273 +			vr_get_display_pos(&x, &y);
   1.274 +			glutPositionWindow(x, y);
   1.275 +
   1.276 +			// also warp the mouse and enable mouselook
   1.277 +			glutWarpPointer(x + width / 2, y + height / 2);
   1.278 +
   1.279 +			/* Ok this next line needs some explanation:
   1.280 +			 * glutPositionWindow, doesn't necessarilly get executed directly.
   1.281 +			 * GLUT might defer it for the next round of event processing, just
   1.282 +			 * so that it may coalesce multiple positioning requests.
   1.283 +			 * However that means that if we just called glutFullScreen right
   1.284 +			 * here, the window manager would have no idea that the window will
   1.285 +			 * move to another monitor, thus making it the size of the monitor
   1.286 +			 * it occupied before the move.
   1.287 +			 * So I'm setting a flag here, and execute the glutFullScreen call
   1.288 +			 * at the next idle invocation. (would display be a safer place?).
   1.289 +			 */
   1.290 +			fullscreen_pending = true;
   1.291 +		} else {
   1.292 +			glutFullScreen();
   1.293 +			toggle_mouselook();
   1.294 +		}
   1.295 +	} else {
   1.296 +		glutReshapeWindow(prev_xsz, prev_ysz);
   1.297 +		glutPositionWindow(prev_x, prev_y);
   1.298 +
   1.299 +		if(mouselook) {
   1.300 +			toggle_mouselook();
   1.301 +		}
   1.302 +	}
   1.303 +	glutPostRedisplay();
   1.304 +}
   1.305 +
   1.306 +
   1.307  static void idle()
   1.308  {
   1.309 +	if(fullscreen_pending) {
   1.310 +		glutFullScreen();
   1.311 +
   1.312 +		if(!mouselook) {
   1.313 +			toggle_mouselook();
   1.314 +		}
   1.315 +		fullscreen_pending = false;
   1.316 +	}
   1.317  	glutPostRedisplay();
   1.318  }
   1.319  
   1.320 @@ -362,33 +483,11 @@
   1.321  		exit(0);
   1.322  
   1.323  	case 'm':
   1.324 -		mouselook = !mouselook;
   1.325 -		if(mouselook) {
   1.326 -			glutPassiveMotionFunc(passive);
   1.327 -			glutSetCursor(GLUT_CURSOR_NONE);
   1.328 -			glutWarpPointer(width / 2, height / 2);
   1.329 -		} else {
   1.330 -			glutPassiveMotionFunc(0);
   1.331 -			glutSetCursor(GLUT_CURSOR_INHERIT);
   1.332 -		}
   1.333 +		toggle_mouselook();
   1.334  		break;
   1.335  
   1.336  	case 'f':
   1.337 -		{
   1.338 -			static bool fullscreen;
   1.339 -			static int prev_xsz, prev_ysz;
   1.340 -
   1.341 -			fullscreen = !fullscreen;
   1.342 -
   1.343 -			if(fullscreen) {
   1.344 -				prev_xsz = width;
   1.345 -				prev_ysz = height;
   1.346 -				glutFullScreen();
   1.347 -			} else {
   1.348 -				glutReshapeWindow(prev_xsz, prev_ysz);
   1.349 -			}
   1.350 -			glutPostRedisplay();
   1.351 -		}
   1.352 +		toggle_fullscreen();
   1.353  		break;
   1.354  	}
   1.355