oculus1

view src/main.cc @ 12:d797639e0234

moving on to the distortion... not correct yet
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 20 Sep 2013 10:14:29 +0300
parents 39ec672a5158
children 464e1d135d68
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "opengl.h"
6 #include "vr.h"
7 #include "camera.h"
9 static bool init();
10 static void cleanup();
11 static void disp();
12 static void draw_scene();
13 static void draw_teapot();
14 static void draw_grid(float size, float spacing);
15 static void idle();
16 static void reshape(int x, int y);
17 static void keyb(unsigned char key, int x, int y);
18 static void keyup(unsigned char key, int x, int y);
19 static void mouse(int bn, int st, int x, int y);
20 static void motion(int x, int y);
21 static void passive(int x, int y);
22 static void sball_rotate(int rx, int ry, int rz);
23 static bool parse_args(int argc, char **argv);
25 static VRFpsCamera cam;
26 static int width, height;
27 static bool use_vr = false;
28 static bool mouselook = false;
30 static bool keystate[256];
32 static int rtarg_width, rtarg_height;
33 static unsigned int fbo, tex[2], zbuf;
36 int main(int argc, char **argv)
37 {
38 glutInitWindowSize(1280, 800);
39 glutInit(&argc, argv);
41 if(!parse_args(argc, argv)) {
42 return 1;
43 }
45 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
46 glutCreateWindow("oculus vr test 01");
48 width = glutGet(GLUT_WINDOW_WIDTH);
49 height = glutGet(GLUT_WINDOW_HEIGHT);
51 glutDisplayFunc(disp);
52 glutIdleFunc(idle);
53 glutReshapeFunc(reshape);
54 glutKeyboardFunc(keyb);
55 glutKeyboardUpFunc(keyup);
56 glutMouseFunc(mouse);
57 glutMotionFunc(motion);
58 glutSpaceballRotateFunc(sball_rotate);
60 if(!init()) {
61 return 1;
62 }
63 atexit(cleanup);
65 glutMainLoop();
66 return 0;
67 }
69 static bool init()
70 {
71 glewInit(); // this must be first
73 glEnable(GL_DEPTH_TEST);
74 glEnable(GL_LIGHTING);
75 glEnable(GL_CULL_FACE);
77 glEnable(GL_LIGHT0);
78 glEnable(GL_LIGHTING);
80 // y = height of neck
81 cam.input_move(0, 1.65, 0);
83 if(use_vr) {
84 if(vr_init(VR_INIT_OCULUS) == -1) {
85 return false;
86 }
88 // reshape to the size of the VR display
89 int xsz = vr_get_width();
90 int ysz = vr_get_height();
92 glutReshapeWindow(xsz, ysz);
94 rtarg_width = (xsz + xsz / 2) / 2;
95 rtarg_height = ysz + ysz / 2;
96 } else {
97 rtarg_width = width;
98 rtarg_height = height;
99 }
101 // create render targets for each eye
102 GLenum wrap_mode = GL_CLAMP_TO_EDGE;
103 if(!GLEW_SGIS_texture_edge_clamp) {
104 wrap_mode = GL_CLAMP;
105 }
107 glGenTextures(2, tex);
108 for(int i=0; i<2; i++) {
109 glBindTexture(GL_TEXTURE_2D, tex[i]);
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode);
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode);
114 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
115 }
117 // create the depth render buffer
118 glGenRenderbuffers(1, &zbuf);
119 glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
120 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height);
122 // create the FBO
123 glGenFramebuffers(1, &fbo);
124 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
125 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
126 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
128 return true;
129 }
131 static void cleanup()
132 {
133 glDeleteTextures(2, tex);
134 glDeleteRenderbuffers(1, &zbuf);
135 glDeleteFramebuffers(1, &fbo);
136 vr_shutdown();
137 }
139 static void disp()
140 {
141 unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
143 cam.track_vr();
145 glMatrixMode(GL_PROJECTION);
146 glLoadIdentity();
147 gluPerspective(RAD_TO_DEG(vr_get_fov()), (float)rtarg_width / (float)rtarg_height, 0.5, 500.0);
149 glViewport(0, 0, rtarg_width, rtarg_height);
151 glClearColor(0.1, 0.1, 0.1, 1.0);
153 // draw left view
154 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
155 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
157 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
159 glMatrixMode(GL_MODELVIEW);
160 glLoadIdentity();
161 cam.use_inverse();
162 glTranslatef(0.32, 0, 0);
163 draw_scene();
166 // draw right view
167 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
168 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[1], 0);
170 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172 glMatrixMode(GL_MODELVIEW);
173 glLoadIdentity();
174 cam.use_inverse();
175 glTranslatef(-0.32, 0, 0);
176 draw_scene();
178 // return to the regular window framebuffer
179 glBindFramebuffer(GL_FRAMEBUFFER, 0);
180 glViewport(0, 0, width, height);
182 glClearColor(0, 0, 0, 0);
183 glClear(GL_COLOR_BUFFER_BIT);
185 vr_draw_eye(tex[0], VR_EYE_LEFT);
186 vr_draw_eye(tex[1], VR_EYE_RIGHT);
188 glutSwapBuffers();
189 assert(glGetError() == GL_NO_ERROR);
190 }
193 static void draw_scene()
194 {
195 float lpos[] = {0, 60, 0, 1};
196 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
198 static Vector2 teapos[] = {
199 Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8)
200 };
202 for(int i=0; i<4; i++) {
203 glPushMatrix();
204 glTranslatef(teapos[i].x, 0, teapos[i].y);
205 draw_teapot();
206 glPopMatrix();
207 }
209 draw_grid(100.0, 2.5);
210 }
212 static void draw_teapot()
213 {
214 static int tealist;
216 if(!tealist) {
217 tealist = glGenLists(1);
218 glNewList(tealist, GL_COMPILE);
219 glutSolidTeapot(1.0);
220 glEndList();
221 }
223 glFrontFace(GL_CW);
224 glCallList(tealist);
225 glFrontFace(GL_CCW);
226 }
228 static void draw_grid(float size, float spacing)
229 {
230 int num_lines = size / spacing;
231 float dist = size / 2.0;
233 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
234 glDisable(GL_LIGHTING);
236 glLineWidth(1.0);
238 glBegin(GL_LINES);
239 glColor3f(0.4, 0.4, 0.4);
241 float x = -dist;
242 for(int i=0; i<=num_lines; i++) {
243 if(i != num_lines / 2) {
244 glVertex3f(-dist, 0, x);
245 glVertex3f(dist, 0, x);
246 glVertex3f(x, 0, -dist);
247 glVertex3f(x, 0, dist);
248 }
249 x += spacing;
250 }
251 glEnd();
253 glLineWidth(2.0);
255 glBegin(GL_LINES);
256 glColor3f(1.0, 0, 0);
257 glVertex3f(-dist, 0, 0);
258 glVertex3f(dist, 0, 0);
259 glColor3f(0, 1.0, 0);
260 glVertex3f(0, 0, -dist);
261 glVertex3f(0, 0, dist);
262 glEnd();
264 glPopAttrib();
265 }
267 static void idle()
268 {
269 glutPostRedisplay();
270 }
273 static void reshape(int x, int y)
274 {
275 width = x;
276 height = y;
278 if(!use_vr) {
279 rtarg_width = width;
280 rtarg_height = height;
281 }
282 }
284 static void keyb(unsigned char key, int x, int y)
285 {
286 switch(key) {
287 case 27:
288 exit(0);
290 case 'm':
291 mouselook = !mouselook;
292 if(mouselook) {
293 glutPassiveMotionFunc(passive);
294 glutSetCursor(GLUT_CURSOR_NONE);
295 glutWarpPointer(width / 2, height / 2);
296 } else {
297 glutPassiveMotionFunc(0);
298 glutSetCursor(GLUT_CURSOR_INHERIT);
299 }
300 break;
302 case 'f':
303 {
304 static bool fullscreen;
305 static int prev_xsz, prev_ysz;
307 fullscreen = !fullscreen;
309 if(fullscreen) {
310 prev_xsz = width;
311 prev_ysz = height;
312 glutFullScreen();
313 } else {
314 glutReshapeWindow(prev_xsz, prev_ysz);
315 }
316 glutPostRedisplay();
317 }
318 break;
319 }
321 keystate[key] = true;
322 glutPostRedisplay();
323 }
325 static void keyup(unsigned char key, int x, int y)
326 {
327 keystate[key] = false;
328 glutPostRedisplay();
329 }
331 static bool bnstate[32];
332 static int prev_x, prev_y;
334 static void mouse(int bn, int st, int x, int y)
335 {
336 prev_x = x;
337 prev_y = y;
338 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
339 }
341 static void motion(int x, int y)
342 {
343 if(mouselook) {
344 // just call passive, it does what we need
345 passive(x, y);
346 }
347 }
349 static void passive(int x, int y)
350 {
351 // no need to test mouselook; this callback is only set when mouselook is enabled
352 int center_x = width / 2;
353 int center_y = height / 2;
355 int dx = x - center_x;
356 int dy = y - center_y;
358 if(!dx && !dy) {
359 return;
360 }
362 float dtheta_deg = dy * 0.1;
363 float dphi_deg = dx * 0.1;
365 cam.input_rotate(DEG_TO_RAD(dtheta_deg), DEG_TO_RAD(dphi_deg), 0);
367 glutPostRedisplay();
368 glutWarpPointer(center_x, center_y);
369 }
371 static void sball_rotate(int rx, int ry, int rz)
372 {
373 }
375 static bool parse_args(int argc, char **argv)
376 {
377 for(int i=1; i<argc; i++) {
378 if(argv[i][0] == '-') {
379 if(strcmp(argv[i], "-vr") == 0) {
380 use_vr = true;
381 } else if(strcmp(argv[i], "-novr") == 0) {
382 use_vr = false;
383 } else {
384 fprintf(stderr, "invalid option: %s\n", argv[i]);
385 return false;
386 }
387 } else {
388 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
389 return false;
390 }
391 }
392 return true;
393 }