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 }
|