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