oculus1

annotate src/main.cc @ 9:b66b54a68dfd

tracking almost done
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 19 Sep 2013 06:36:48 +0300
parents 3265970a7315
children b2abb08c8f94
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@0 13 static void idle();
nuclear@0 14 static void reshape(int x, int y);
nuclear@0 15 static void keyb(unsigned char key, int x, int y);
nuclear@8 16 static void keyup(unsigned char key, int x, int y);
nuclear@8 17 static void mouse(int bn, int st, int x, int y);
nuclear@8 18 static void motion(int x, int y);
nuclear@8 19 static void passive(int x, int y);
nuclear@0 20 static void sball_rotate(int rx, int ry, int rz);
nuclear@1 21 static bool parse_args(int argc, char **argv);
nuclear@0 22
nuclear@9 23 static FpsCamera cam;
nuclear@0 24 static int width, height;
nuclear@1 25 static bool use_vr = false;
nuclear@8 26 static bool mouselook = false;
nuclear@8 27
nuclear@8 28 static bool keystate[256];
nuclear@8 29
nuclear@0 30
nuclear@0 31 int main(int argc, char **argv)
nuclear@0 32 {
nuclear@3 33 glutInitWindowSize(1280, 800);
nuclear@0 34 glutInit(&argc, argv);
nuclear@1 35
nuclear@1 36 if(!parse_args(argc, argv)) {
nuclear@1 37 return 1;
nuclear@1 38 }
nuclear@1 39
nuclear@9 40 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
nuclear@0 41 glutCreateWindow("oculus test 01");
nuclear@0 42
nuclear@0 43 glutDisplayFunc(disp);
nuclear@0 44 glutIdleFunc(idle);
nuclear@0 45 glutReshapeFunc(reshape);
nuclear@0 46 glutKeyboardFunc(keyb);
nuclear@8 47 glutKeyboardUpFunc(keyup);
nuclear@8 48 glutMouseFunc(mouse);
nuclear@8 49 glutMotionFunc(motion);
nuclear@0 50 glutSpaceballRotateFunc(sball_rotate);
nuclear@0 51
nuclear@0 52 if(!init()) {
nuclear@0 53 return 1;
nuclear@0 54 }
nuclear@0 55 atexit(cleanup);
nuclear@0 56
nuclear@0 57 glutMainLoop();
nuclear@0 58 return 0;
nuclear@0 59 }
nuclear@0 60
nuclear@0 61 static bool init()
nuclear@0 62 {
nuclear@9 63 glewInit(); // this must be first
nuclear@9 64
nuclear@9 65 if(GLEW_ARB_multisample) {
nuclear@9 66 glEnable(GL_MULTISAMPLE);
nuclear@9 67 }
nuclear@8 68
nuclear@0 69 glEnable(GL_DEPTH_TEST);
nuclear@0 70 glEnable(GL_LIGHTING);
nuclear@0 71 glEnable(GL_CULL_FACE);
nuclear@0 72
nuclear@0 73 glEnable(GL_LIGHT0);
nuclear@0 74 glEnable(GL_LIGHTING);
nuclear@0 75
nuclear@9 76 cam.input_move(0, 1.75, 0);
nuclear@9 77
nuclear@1 78 if(vr_init(VR_INIT_OCULUS) == -1) {
nuclear@5 79 return false;
nuclear@0 80 }
nuclear@0 81 return true;
nuclear@0 82 }
nuclear@0 83
nuclear@0 84 static void cleanup()
nuclear@0 85 {
nuclear@1 86 vr_shutdown();
nuclear@0 87 }
nuclear@0 88
nuclear@0 89 static void disp()
nuclear@0 90 {
nuclear@4 91 unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
nuclear@4 92
nuclear@3 93 // test rift sensor
nuclear@3 94 float quat[4], euler[3];
nuclear@3 95
nuclear@3 96 vr_get_rotation(quat);
nuclear@3 97 vr_get_rotation_euler(euler);
nuclear@3 98
nuclear@5 99 Quaternion qrot(quat[3], quat[0], quat[1], quat[2]);
nuclear@5 100
nuclear@4 101 static unsigned int prev_print;
nuclear@4 102 if(msec - prev_print > 1000) {
nuclear@9 103 printf("q(%.3f + %.3fi + %.3fj + %.3fk)", quat[3], quat[0], quat[1], quat[2]);
nuclear@4 104 printf(" - euler(%.3f %.3f %.3f)\n", euler[0], euler[1], euler[2]);
nuclear@4 105 prev_print = msec;
nuclear@4 106 }
nuclear@3 107
nuclear@0 108 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@0 109
nuclear@0 110 glMatrixMode(GL_PROJECTION);
nuclear@0 111 glLoadIdentity();
nuclear@0 112 gluPerspective(45.0, (float)width / (float)height, 0.5, 500.0);
nuclear@0 113
nuclear@0 114 glMatrixMode(GL_MODELVIEW);
nuclear@9 115 glLoadIdentity();
nuclear@0 116
nuclear@9 117 Matrix4x4 mat = qrot.inverse().get_rotation_matrix();
nuclear@9 118 load_matrix(mat);
nuclear@9 119
nuclear@9 120 cam.use_inverse();
nuclear@9 121
nuclear@9 122 draw_scene();
nuclear@9 123
nuclear@9 124 glutSwapBuffers();
nuclear@9 125 assert(glGetError() == GL_NO_ERROR);
nuclear@9 126 }
nuclear@9 127
nuclear@9 128 static void draw_teapot()
nuclear@9 129 {
nuclear@9 130 static int tealist;
nuclear@9 131
nuclear@9 132 if(!tealist) {
nuclear@9 133 tealist = glGenLists(1);
nuclear@9 134 glNewList(tealist, GL_COMPILE);
nuclear@9 135 glutSolidTeapot(1.0);
nuclear@9 136 glEndList();
nuclear@9 137 }
nuclear@9 138
nuclear@9 139 glFrontFace(GL_CW);
nuclear@9 140 glCallList(tealist);
nuclear@9 141 glFrontFace(GL_CCW);
nuclear@9 142 }
nuclear@9 143
nuclear@9 144 void draw_grid(float size, float spacing)
nuclear@9 145 {
nuclear@9 146 int num_lines = size / spacing;
nuclear@9 147 float dist = size / 2.0;
nuclear@9 148
nuclear@9 149 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
nuclear@9 150 glDisable(GL_LIGHTING);
nuclear@9 151
nuclear@9 152 glLineWidth(1.0);
nuclear@9 153
nuclear@9 154 glBegin(GL_LINES);
nuclear@9 155 glColor3f(0.4, 0.4, 0.4);
nuclear@9 156
nuclear@9 157 float x = -dist;
nuclear@9 158 for(int i=0; i<=num_lines; i++) {
nuclear@9 159 if(i != num_lines / 2) {
nuclear@9 160 glVertex3f(-dist, 0, x);
nuclear@9 161 glVertex3f(dist, 0, x);
nuclear@9 162 glVertex3f(x, 0, -dist);
nuclear@9 163 glVertex3f(x, 0, dist);
nuclear@9 164 }
nuclear@9 165 x += spacing;
nuclear@9 166 }
nuclear@9 167 glEnd();
nuclear@9 168
nuclear@9 169 glLineWidth(2.0);
nuclear@9 170
nuclear@9 171 glBegin(GL_LINES);
nuclear@9 172 glColor3f(1.0, 0, 0);
nuclear@9 173 glVertex3f(-dist, 0, 0);
nuclear@9 174 glVertex3f(dist, 0, 0);
nuclear@9 175 glColor3f(0, 1.0, 0);
nuclear@9 176 glVertex3f(0, 0, -dist);
nuclear@9 177 glVertex3f(0, 0, dist);
nuclear@9 178 glEnd();
nuclear@9 179
nuclear@9 180 glPopAttrib();
nuclear@9 181 }
nuclear@9 182
nuclear@9 183
nuclear@9 184 static void draw_scene()
nuclear@9 185 {
nuclear@0 186 float lpos[] = {0, 60, 0, 1};
nuclear@0 187 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
nuclear@0 188
nuclear@9 189 static Vector2 teapos[] = {
nuclear@9 190 Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8)
nuclear@9 191 };
nuclear@8 192
nuclear@9 193 for(int i=0; i<4; i++) {
nuclear@9 194 glPushMatrix();
nuclear@9 195 glTranslatef(teapos[i].x, 0, teapos[i].y);
nuclear@9 196 draw_teapot();
nuclear@9 197 glPopMatrix();
nuclear@9 198 }
nuclear@0 199
nuclear@9 200 draw_grid(100.0, 2.5);
nuclear@0 201 }
nuclear@0 202
nuclear@0 203 static void idle()
nuclear@0 204 {
nuclear@0 205 glutPostRedisplay();
nuclear@0 206 }
nuclear@0 207
nuclear@0 208
nuclear@0 209 static void reshape(int x, int y)
nuclear@0 210 {
nuclear@0 211 width = x;
nuclear@0 212 height = y;
nuclear@0 213 }
nuclear@0 214
nuclear@0 215 static void keyb(unsigned char key, int x, int y)
nuclear@0 216 {
nuclear@0 217 switch(key) {
nuclear@0 218 case 27:
nuclear@0 219 exit(0);
nuclear@8 220
nuclear@8 221 case 'm':
nuclear@8 222 mouselook = !mouselook;
nuclear@8 223 if(mouselook) {
nuclear@8 224 glutPassiveMotionFunc(passive);
nuclear@8 225 glutSetCursor(GLUT_CURSOR_NONE);
nuclear@8 226 glutWarpPointer(width / 2, height / 2);
nuclear@8 227 } else {
nuclear@8 228 glutPassiveMotionFunc(0);
nuclear@8 229 glutSetCursor(GLUT_CURSOR_INHERIT);
nuclear@8 230 }
nuclear@8 231 break;
nuclear@0 232 }
nuclear@8 233
nuclear@8 234 keystate[key] = true;
nuclear@8 235 glutPostRedisplay();
nuclear@8 236 }
nuclear@8 237
nuclear@8 238 static void keyup(unsigned char key, int x, int y)
nuclear@8 239 {
nuclear@8 240 keystate[key] = false;
nuclear@8 241 glutPostRedisplay();
nuclear@8 242 }
nuclear@8 243
nuclear@8 244 static bool bnstate[32];
nuclear@8 245 static int prev_x, prev_y;
nuclear@8 246
nuclear@8 247 static void mouse(int bn, int st, int x, int y)
nuclear@8 248 {
nuclear@8 249 prev_x = x;
nuclear@8 250 prev_y = y;
nuclear@8 251 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
nuclear@8 252 }
nuclear@8 253
nuclear@8 254 static void motion(int x, int y)
nuclear@8 255 {
nuclear@8 256 if(mouselook) {
nuclear@8 257 // just call passive, it does what we need
nuclear@8 258 passive(x, y);
nuclear@8 259 }
nuclear@8 260 }
nuclear@8 261
nuclear@8 262 static void passive(int x, int y)
nuclear@8 263 {
nuclear@8 264 // no need to test mouselook; this callback is only set when mouselook is enabled
nuclear@8 265 int center_x = width / 2;
nuclear@8 266 int center_y = height / 2;
nuclear@8 267
nuclear@8 268 int dx = x - center_x;
nuclear@8 269 int dy = y - center_y;
nuclear@8 270
nuclear@8 271 if(!dx && !dy) {
nuclear@8 272 return;
nuclear@8 273 }
nuclear@8 274
nuclear@9 275 float dtheta_deg = dy * 0.1;
nuclear@9 276 float dphi_deg = dx * 0.1;
nuclear@9 277
nuclear@9 278 cam.input_rotate(DEG_TO_RAD(dtheta_deg), DEG_TO_RAD(dphi_deg), 0);
nuclear@9 279
nuclear@8 280 glutPostRedisplay();
nuclear@8 281 glutWarpPointer(center_x, center_y);
nuclear@0 282 }
nuclear@0 283
nuclear@0 284 static void sball_rotate(int rx, int ry, int rz)
nuclear@0 285 {
nuclear@0 286 }
nuclear@1 287
nuclear@1 288 static bool parse_args(int argc, char **argv)
nuclear@1 289 {
nuclear@1 290 for(int i=1; i<argc; i++) {
nuclear@1 291 if(argv[i][0] == '-') {
nuclear@1 292 if(strcmp(argv[i], "-vr") == 0) {
nuclear@1 293 use_vr = true;
nuclear@1 294 } else if(strcmp(argv[i], "-novr") == 0) {
nuclear@1 295 use_vr = false;
nuclear@1 296 } else {
nuclear@1 297 fprintf(stderr, "invalid option: %s\n", argv[i]);
nuclear@1 298 return false;
nuclear@1 299 }
nuclear@1 300 } else {
nuclear@1 301 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
nuclear@1 302 return false;
nuclear@1 303 }
nuclear@1 304 }
nuclear@1 305 return true;
nuclear@1 306 }