rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@1
|
3 #include <string.h>
|
nuclear@0
|
4 #include <assert.h>
|
nuclear@8
|
5 #include "opengl.h"
|
nuclear@1
|
6 #include "vr.h"
|
nuclear@0
|
7 #include "camera.h"
|
nuclear@0
|
8
|
nuclear@0
|
9 static bool init();
|
nuclear@0
|
10 static void cleanup();
|
nuclear@0
|
11 static void disp();
|
nuclear@9
|
12 static void draw_scene();
|
nuclear@12
|
13 static void draw_teapot();
|
nuclear@13
|
14 static void draw_squares();
|
nuclear@12
|
15 static void draw_grid(float size, float spacing);
|
nuclear@0
|
16 static void idle();
|
nuclear@0
|
17 static void reshape(int x, int y);
|
nuclear@0
|
18 static void keyb(unsigned char key, int x, int y);
|
nuclear@8
|
19 static void keyup(unsigned char key, int x, int y);
|
nuclear@8
|
20 static void mouse(int bn, int st, int x, int y);
|
nuclear@8
|
21 static void motion(int x, int y);
|
nuclear@8
|
22 static void passive(int x, int y);
|
nuclear@0
|
23 static void sball_rotate(int rx, int ry, int rz);
|
nuclear@1
|
24 static bool parse_args(int argc, char **argv);
|
nuclear@0
|
25
|
nuclear@10
|
26 static VRFpsCamera cam;
|
nuclear@0
|
27 static int width, height;
|
nuclear@1
|
28 static bool use_vr = false;
|
nuclear@8
|
29 static bool mouselook = false;
|
nuclear@8
|
30
|
nuclear@8
|
31 static bool keystate[256];
|
nuclear@8
|
32
|
nuclear@12
|
33 static int rtarg_width, rtarg_height;
|
nuclear@12
|
34 static unsigned int fbo, tex[2], zbuf;
|
nuclear@12
|
35
|
nuclear@0
|
36 int main(int argc, char **argv)
|
nuclear@0
|
37 {
|
nuclear@3
|
38 glutInitWindowSize(1280, 800);
|
nuclear@0
|
39 glutInit(&argc, argv);
|
nuclear@1
|
40
|
nuclear@1
|
41 if(!parse_args(argc, argv)) {
|
nuclear@1
|
42 return 1;
|
nuclear@1
|
43 }
|
nuclear@1
|
44
|
nuclear@12
|
45 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
|
nuclear@12
|
46 glutCreateWindow("oculus vr test 01");
|
nuclear@12
|
47
|
nuclear@12
|
48 width = glutGet(GLUT_WINDOW_WIDTH);
|
nuclear@12
|
49 height = glutGet(GLUT_WINDOW_HEIGHT);
|
nuclear@0
|
50
|
nuclear@0
|
51 glutDisplayFunc(disp);
|
nuclear@0
|
52 glutIdleFunc(idle);
|
nuclear@0
|
53 glutReshapeFunc(reshape);
|
nuclear@0
|
54 glutKeyboardFunc(keyb);
|
nuclear@8
|
55 glutKeyboardUpFunc(keyup);
|
nuclear@8
|
56 glutMouseFunc(mouse);
|
nuclear@8
|
57 glutMotionFunc(motion);
|
nuclear@0
|
58 glutSpaceballRotateFunc(sball_rotate);
|
nuclear@0
|
59
|
nuclear@0
|
60 if(!init()) {
|
nuclear@0
|
61 return 1;
|
nuclear@0
|
62 }
|
nuclear@0
|
63 atexit(cleanup);
|
nuclear@0
|
64
|
nuclear@0
|
65 glutMainLoop();
|
nuclear@0
|
66 return 0;
|
nuclear@0
|
67 }
|
nuclear@0
|
68
|
nuclear@0
|
69 static bool init()
|
nuclear@0
|
70 {
|
nuclear@9
|
71 glewInit(); // this must be first
|
nuclear@9
|
72
|
nuclear@0
|
73 glEnable(GL_DEPTH_TEST);
|
nuclear@0
|
74 glEnable(GL_LIGHTING);
|
nuclear@0
|
75 glEnable(GL_CULL_FACE);
|
nuclear@0
|
76
|
nuclear@0
|
77 glEnable(GL_LIGHT0);
|
nuclear@0
|
78 glEnable(GL_LIGHTING);
|
nuclear@0
|
79
|
nuclear@11
|
80 // y = height of neck
|
nuclear@11
|
81 cam.input_move(0, 1.65, 0);
|
nuclear@9
|
82
|
nuclear@12
|
83 if(use_vr) {
|
nuclear@12
|
84 if(vr_init(VR_INIT_OCULUS) == -1) {
|
nuclear@12
|
85 return false;
|
nuclear@12
|
86 }
|
nuclear@12
|
87
|
nuclear@12
|
88 // reshape to the size of the VR display
|
nuclear@12
|
89 int xsz = vr_get_width();
|
nuclear@12
|
90 int ysz = vr_get_height();
|
nuclear@12
|
91
|
nuclear@12
|
92 glutReshapeWindow(xsz, ysz);
|
nuclear@12
|
93
|
nuclear@12
|
94 rtarg_width = (xsz + xsz / 2) / 2;
|
nuclear@12
|
95 rtarg_height = ysz + ysz / 2;
|
nuclear@12
|
96 } else {
|
nuclear@12
|
97 rtarg_width = width;
|
nuclear@12
|
98 rtarg_height = height;
|
nuclear@0
|
99 }
|
nuclear@12
|
100
|
nuclear@13
|
101 printf("render target: %dx%d\n", rtarg_width, rtarg_height);
|
nuclear@13
|
102
|
nuclear@12
|
103 // create render targets for each eye
|
nuclear@12
|
104 GLenum wrap_mode = GL_CLAMP_TO_EDGE;
|
nuclear@12
|
105 if(!GLEW_SGIS_texture_edge_clamp) {
|
nuclear@12
|
106 wrap_mode = GL_CLAMP;
|
nuclear@12
|
107 }
|
nuclear@12
|
108
|
nuclear@12
|
109 glGenTextures(2, tex);
|
nuclear@12
|
110 for(int i=0; i<2; i++) {
|
nuclear@12
|
111 glBindTexture(GL_TEXTURE_2D, tex[i]);
|
nuclear@12
|
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@12
|
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@12
|
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode);
|
nuclear@12
|
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode);
|
nuclear@12
|
116 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
nuclear@12
|
117 }
|
nuclear@12
|
118
|
nuclear@12
|
119 // create the depth render buffer
|
nuclear@12
|
120 glGenRenderbuffers(1, &zbuf);
|
nuclear@12
|
121 glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
|
nuclear@12
|
122 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height);
|
nuclear@12
|
123
|
nuclear@12
|
124 // create the FBO
|
nuclear@12
|
125 glGenFramebuffers(1, &fbo);
|
nuclear@12
|
126 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@12
|
127 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
|
nuclear@12
|
128 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
|
nuclear@12
|
129
|
nuclear@0
|
130 return true;
|
nuclear@0
|
131 }
|
nuclear@0
|
132
|
nuclear@0
|
133 static void cleanup()
|
nuclear@0
|
134 {
|
nuclear@12
|
135 glDeleteTextures(2, tex);
|
nuclear@12
|
136 glDeleteRenderbuffers(1, &zbuf);
|
nuclear@12
|
137 glDeleteFramebuffers(1, &fbo);
|
nuclear@1
|
138 vr_shutdown();
|
nuclear@0
|
139 }
|
nuclear@0
|
140
|
nuclear@14
|
141 static void handle_input(float dt)
|
nuclear@14
|
142 {
|
nuclear@14
|
143 Vector3 inpv;
|
nuclear@14
|
144 float offs = dt * 2.0;
|
nuclear@14
|
145
|
nuclear@14
|
146 if(keystate['w'] || keystate['W']) {
|
nuclear@14
|
147 inpv.z -= offs;
|
nuclear@14
|
148 }
|
nuclear@14
|
149 if(keystate['s'] || keystate['S']) {
|
nuclear@14
|
150 inpv.z += offs;
|
nuclear@14
|
151 }
|
nuclear@14
|
152 if(keystate['d'] || keystate['D']) {
|
nuclear@14
|
153 inpv.x += offs;
|
nuclear@14
|
154 }
|
nuclear@14
|
155 if(keystate['a'] || keystate['A']) {
|
nuclear@14
|
156 inpv.x -= offs;
|
nuclear@14
|
157 }
|
nuclear@14
|
158
|
nuclear@14
|
159 cam.input_move(inpv.x, inpv.y, inpv.z);
|
nuclear@14
|
160 }
|
nuclear@14
|
161
|
nuclear@0
|
162 static void disp()
|
nuclear@0
|
163 {
|
nuclear@14
|
164 static long prev_msec;
|
nuclear@14
|
165 long msec = glutGet(GLUT_ELAPSED_TIME);
|
nuclear@14
|
166 float dt = (msec - prev_msec) / 1000.0;
|
nuclear@14
|
167 prev_msec = msec;
|
nuclear@4
|
168
|
nuclear@14
|
169 handle_input(dt);
|
nuclear@12
|
170 cam.track_vr();
|
nuclear@0
|
171
|
nuclear@13
|
172 /*glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
173 glLoadIdentity();
|
nuclear@13
|
174 float fov = RAD_TO_DEG(vr_get_fov());
|
nuclear@13
|
175 gluPerspective(fov, (float)rtarg_width / (float)rtarg_height, 0.25, 500.0);*/
|
nuclear@13
|
176 float proj_matrix[16];
|
nuclear@13
|
177
|
nuclear@13
|
178 float eye_dist = vr_get_eyedist();
|
nuclear@12
|
179
|
nuclear@12
|
180 glViewport(0, 0, rtarg_width, rtarg_height);
|
nuclear@12
|
181
|
nuclear@12
|
182 glClearColor(0.1, 0.1, 0.1, 1.0);
|
nuclear@12
|
183
|
nuclear@12
|
184 // draw left view
|
nuclear@12
|
185 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@12
|
186 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0);
|
nuclear@12
|
187
|
nuclear@12
|
188 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@0
|
189
|
nuclear@13
|
190 glMatrixMode(GL_PROJECTION);
|
nuclear@13
|
191 vr_get_proj_matrix(proj_matrix, VR_EYE_LEFT);
|
nuclear@13
|
192 glLoadTransposeMatrixf(proj_matrix);
|
nuclear@13
|
193
|
nuclear@0
|
194 glMatrixMode(GL_MODELVIEW);
|
nuclear@9
|
195 glLoadIdentity();
|
nuclear@13
|
196 glTranslatef(eye_dist / 2.0, 0, 0);
|
nuclear@12
|
197 cam.use_inverse();
|
nuclear@12
|
198 draw_scene();
|
nuclear@0
|
199
|
nuclear@12
|
200
|
nuclear@12
|
201 // draw right view
|
nuclear@12
|
202 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@12
|
203 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[1], 0);
|
nuclear@12
|
204
|
nuclear@12
|
205 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@12
|
206
|
nuclear@13
|
207 glMatrixMode(GL_PROJECTION);
|
nuclear@13
|
208 vr_get_proj_matrix(proj_matrix, VR_EYE_RIGHT);
|
nuclear@13
|
209 glLoadTransposeMatrixf(proj_matrix);
|
nuclear@13
|
210
|
nuclear@12
|
211 glMatrixMode(GL_MODELVIEW);
|
nuclear@12
|
212 glLoadIdentity();
|
nuclear@13
|
213 glTranslatef(-eye_dist / 2.0, 0, 0);
|
nuclear@9
|
214 cam.use_inverse();
|
nuclear@12
|
215 draw_scene();
|
nuclear@9
|
216
|
nuclear@12
|
217 // return to the regular window framebuffer
|
nuclear@12
|
218 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@12
|
219 glViewport(0, 0, width, height);
|
nuclear@12
|
220
|
nuclear@12
|
221 glClearColor(0, 0, 0, 0);
|
nuclear@12
|
222 glClear(GL_COLOR_BUFFER_BIT);
|
nuclear@12
|
223
|
nuclear@12
|
224 vr_draw_eye(tex[0], VR_EYE_LEFT);
|
nuclear@12
|
225 vr_draw_eye(tex[1], VR_EYE_RIGHT);
|
nuclear@9
|
226
|
nuclear@9
|
227 glutSwapBuffers();
|
nuclear@9
|
228 assert(glGetError() == GL_NO_ERROR);
|
nuclear@13
|
229
|
nuclear@13
|
230 glFinish();
|
nuclear@9
|
231 }
|
nuclear@9
|
232
|
nuclear@12
|
233
|
nuclear@12
|
234 static void draw_scene()
|
nuclear@12
|
235 {
|
nuclear@12
|
236 float lpos[] = {0, 60, 0, 1};
|
nuclear@12
|
237 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
|
nuclear@12
|
238
|
nuclear@14
|
239 draw_grid(50.0, 2.5);
|
nuclear@13
|
240
|
nuclear@12
|
241 static Vector2 teapos[] = {
|
nuclear@12
|
242 Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8)
|
nuclear@12
|
243 };
|
nuclear@12
|
244
|
nuclear@12
|
245 for(int i=0; i<4; i++) {
|
nuclear@12
|
246 glPushMatrix();
|
nuclear@12
|
247 glTranslatef(teapos[i].x, 0, teapos[i].y);
|
nuclear@12
|
248 draw_teapot();
|
nuclear@12
|
249 glPopMatrix();
|
nuclear@12
|
250 }
|
nuclear@12
|
251
|
nuclear@13
|
252 draw_squares();
|
nuclear@12
|
253 }
|
nuclear@12
|
254
|
nuclear@9
|
255 static void draw_teapot()
|
nuclear@9
|
256 {
|
nuclear@9
|
257 static int tealist;
|
nuclear@9
|
258
|
nuclear@9
|
259 if(!tealist) {
|
nuclear@9
|
260 tealist = glGenLists(1);
|
nuclear@9
|
261 glNewList(tealist, GL_COMPILE);
|
nuclear@9
|
262 glutSolidTeapot(1.0);
|
nuclear@9
|
263 glEndList();
|
nuclear@9
|
264 }
|
nuclear@9
|
265
|
nuclear@9
|
266 glFrontFace(GL_CW);
|
nuclear@9
|
267 glCallList(tealist);
|
nuclear@9
|
268 glFrontFace(GL_CCW);
|
nuclear@9
|
269 }
|
nuclear@9
|
270
|
nuclear@13
|
271 static void draw_squares()
|
nuclear@13
|
272 {
|
nuclear@14
|
273 static const int num_sq = 8;
|
nuclear@13
|
274
|
nuclear@13
|
275 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
|
nuclear@13
|
276 glDisable(GL_LIGHTING);
|
nuclear@13
|
277
|
nuclear@13
|
278 glMatrixMode(GL_MODELVIEW);
|
nuclear@13
|
279 glPushMatrix();
|
nuclear@13
|
280 glTranslatef(0, 1, 0);
|
nuclear@13
|
281
|
nuclear@13
|
282
|
nuclear@14
|
283 glLineWidth(2.0);
|
nuclear@13
|
284 glColor3f(1.0, 0.7, 0.2);
|
nuclear@13
|
285
|
nuclear@13
|
286 float zdist = 2.0;
|
nuclear@13
|
287 for(int i=0; i<num_sq; i++) {
|
nuclear@13
|
288 glBegin(GL_LINE_LOOP);
|
nuclear@13
|
289 glVertex3f(-1, -1, -zdist);
|
nuclear@13
|
290 glVertex3f(1, -1, -zdist);
|
nuclear@13
|
291 glVertex3f(1, 1, -zdist);
|
nuclear@13
|
292 glVertex3f(-1, 1, -zdist);
|
nuclear@13
|
293 glEnd();
|
nuclear@13
|
294
|
nuclear@14
|
295 zdist += 2.0;
|
nuclear@13
|
296 }
|
nuclear@13
|
297
|
nuclear@13
|
298 glPopMatrix();
|
nuclear@13
|
299 glPopAttrib();
|
nuclear@13
|
300 }
|
nuclear@13
|
301
|
nuclear@12
|
302 static void draw_grid(float size, float spacing)
|
nuclear@9
|
303 {
|
nuclear@9
|
304 int num_lines = size / spacing;
|
nuclear@9
|
305 float dist = size / 2.0;
|
nuclear@9
|
306
|
nuclear@9
|
307 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
|
nuclear@9
|
308 glDisable(GL_LIGHTING);
|
nuclear@9
|
309
|
nuclear@9
|
310 glLineWidth(1.0);
|
nuclear@9
|
311
|
nuclear@9
|
312 glBegin(GL_LINES);
|
nuclear@9
|
313 glColor3f(0.4, 0.4, 0.4);
|
nuclear@9
|
314
|
nuclear@9
|
315 float x = -dist;
|
nuclear@9
|
316 for(int i=0; i<=num_lines; i++) {
|
nuclear@9
|
317 if(i != num_lines / 2) {
|
nuclear@9
|
318 glVertex3f(-dist, 0, x);
|
nuclear@9
|
319 glVertex3f(dist, 0, x);
|
nuclear@9
|
320 glVertex3f(x, 0, -dist);
|
nuclear@9
|
321 glVertex3f(x, 0, dist);
|
nuclear@9
|
322 }
|
nuclear@9
|
323 x += spacing;
|
nuclear@9
|
324 }
|
nuclear@9
|
325 glEnd();
|
nuclear@9
|
326
|
nuclear@9
|
327 glLineWidth(2.0);
|
nuclear@9
|
328
|
nuclear@9
|
329 glBegin(GL_LINES);
|
nuclear@9
|
330 glColor3f(1.0, 0, 0);
|
nuclear@9
|
331 glVertex3f(-dist, 0, 0);
|
nuclear@9
|
332 glVertex3f(dist, 0, 0);
|
nuclear@9
|
333 glColor3f(0, 1.0, 0);
|
nuclear@9
|
334 glVertex3f(0, 0, -dist);
|
nuclear@9
|
335 glVertex3f(0, 0, dist);
|
nuclear@9
|
336 glEnd();
|
nuclear@9
|
337
|
nuclear@9
|
338 glPopAttrib();
|
nuclear@9
|
339 }
|
nuclear@9
|
340
|
nuclear@0
|
341 static void idle()
|
nuclear@0
|
342 {
|
nuclear@0
|
343 glutPostRedisplay();
|
nuclear@0
|
344 }
|
nuclear@0
|
345
|
nuclear@0
|
346
|
nuclear@0
|
347 static void reshape(int x, int y)
|
nuclear@0
|
348 {
|
nuclear@0
|
349 width = x;
|
nuclear@0
|
350 height = y;
|
nuclear@12
|
351
|
nuclear@12
|
352 if(!use_vr) {
|
nuclear@12
|
353 rtarg_width = width;
|
nuclear@12
|
354 rtarg_height = height;
|
nuclear@12
|
355 }
|
nuclear@0
|
356 }
|
nuclear@0
|
357
|
nuclear@0
|
358 static void keyb(unsigned char key, int x, int y)
|
nuclear@0
|
359 {
|
nuclear@0
|
360 switch(key) {
|
nuclear@0
|
361 case 27:
|
nuclear@0
|
362 exit(0);
|
nuclear@8
|
363
|
nuclear@8
|
364 case 'm':
|
nuclear@8
|
365 mouselook = !mouselook;
|
nuclear@8
|
366 if(mouselook) {
|
nuclear@8
|
367 glutPassiveMotionFunc(passive);
|
nuclear@8
|
368 glutSetCursor(GLUT_CURSOR_NONE);
|
nuclear@8
|
369 glutWarpPointer(width / 2, height / 2);
|
nuclear@8
|
370 } else {
|
nuclear@8
|
371 glutPassiveMotionFunc(0);
|
nuclear@8
|
372 glutSetCursor(GLUT_CURSOR_INHERIT);
|
nuclear@8
|
373 }
|
nuclear@8
|
374 break;
|
nuclear@12
|
375
|
nuclear@12
|
376 case 'f':
|
nuclear@12
|
377 {
|
nuclear@12
|
378 static bool fullscreen;
|
nuclear@12
|
379 static int prev_xsz, prev_ysz;
|
nuclear@12
|
380
|
nuclear@12
|
381 fullscreen = !fullscreen;
|
nuclear@12
|
382
|
nuclear@12
|
383 if(fullscreen) {
|
nuclear@12
|
384 prev_xsz = width;
|
nuclear@12
|
385 prev_ysz = height;
|
nuclear@12
|
386 glutFullScreen();
|
nuclear@12
|
387 } else {
|
nuclear@12
|
388 glutReshapeWindow(prev_xsz, prev_ysz);
|
nuclear@12
|
389 }
|
nuclear@12
|
390 glutPostRedisplay();
|
nuclear@12
|
391 }
|
nuclear@12
|
392 break;
|
nuclear@0
|
393 }
|
nuclear@8
|
394
|
nuclear@8
|
395 keystate[key] = true;
|
nuclear@8
|
396 glutPostRedisplay();
|
nuclear@8
|
397 }
|
nuclear@8
|
398
|
nuclear@8
|
399 static void keyup(unsigned char key, int x, int y)
|
nuclear@8
|
400 {
|
nuclear@8
|
401 keystate[key] = false;
|
nuclear@8
|
402 glutPostRedisplay();
|
nuclear@8
|
403 }
|
nuclear@8
|
404
|
nuclear@8
|
405 static bool bnstate[32];
|
nuclear@8
|
406 static int prev_x, prev_y;
|
nuclear@8
|
407
|
nuclear@8
|
408 static void mouse(int bn, int st, int x, int y)
|
nuclear@8
|
409 {
|
nuclear@8
|
410 prev_x = x;
|
nuclear@8
|
411 prev_y = y;
|
nuclear@8
|
412 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
|
nuclear@8
|
413 }
|
nuclear@8
|
414
|
nuclear@8
|
415 static void motion(int x, int y)
|
nuclear@8
|
416 {
|
nuclear@8
|
417 if(mouselook) {
|
nuclear@8
|
418 // just call passive, it does what we need
|
nuclear@8
|
419 passive(x, y);
|
nuclear@8
|
420 }
|
nuclear@8
|
421 }
|
nuclear@8
|
422
|
nuclear@8
|
423 static void passive(int x, int y)
|
nuclear@8
|
424 {
|
nuclear@8
|
425 // no need to test mouselook; this callback is only set when mouselook is enabled
|
nuclear@8
|
426 int center_x = width / 2;
|
nuclear@8
|
427 int center_y = height / 2;
|
nuclear@8
|
428
|
nuclear@8
|
429 int dx = x - center_x;
|
nuclear@8
|
430 int dy = y - center_y;
|
nuclear@8
|
431
|
nuclear@8
|
432 if(!dx && !dy) {
|
nuclear@8
|
433 return;
|
nuclear@8
|
434 }
|
nuclear@8
|
435
|
nuclear@9
|
436 float dtheta_deg = dy * 0.1;
|
nuclear@9
|
437 float dphi_deg = dx * 0.1;
|
nuclear@9
|
438
|
nuclear@9
|
439 cam.input_rotate(DEG_TO_RAD(dtheta_deg), DEG_TO_RAD(dphi_deg), 0);
|
nuclear@9
|
440
|
nuclear@8
|
441 glutPostRedisplay();
|
nuclear@8
|
442 glutWarpPointer(center_x, center_y);
|
nuclear@0
|
443 }
|
nuclear@0
|
444
|
nuclear@0
|
445 static void sball_rotate(int rx, int ry, int rz)
|
nuclear@0
|
446 {
|
nuclear@0
|
447 }
|
nuclear@1
|
448
|
nuclear@1
|
449 static bool parse_args(int argc, char **argv)
|
nuclear@1
|
450 {
|
nuclear@1
|
451 for(int i=1; i<argc; i++) {
|
nuclear@1
|
452 if(argv[i][0] == '-') {
|
nuclear@1
|
453 if(strcmp(argv[i], "-vr") == 0) {
|
nuclear@1
|
454 use_vr = true;
|
nuclear@1
|
455 } else if(strcmp(argv[i], "-novr") == 0) {
|
nuclear@1
|
456 use_vr = false;
|
nuclear@1
|
457 } else {
|
nuclear@1
|
458 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@1
|
459 return false;
|
nuclear@1
|
460 }
|
nuclear@1
|
461 } else {
|
nuclear@1
|
462 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
|
nuclear@1
|
463 return false;
|
nuclear@1
|
464 }
|
nuclear@1
|
465 }
|
nuclear@1
|
466 return true;
|
nuclear@1
|
467 }
|