view3d

view src/main.c @ 4:0aee5df08cfc

fixed some shit
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 19 Jan 2012 07:03:47 +0200
parents 7e982a61852a
children 58ddd42848f9
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
5 #include <GL/glew.h>
6 #ifndef __APPLE__
7 #include <GL/glut.h>
8 #else
9 #include <GLUT/glut.h>
10 #endif
12 #include "scene.h"
14 void disp(void);
15 void render(unsigned int msec);
16 void proj_matrix(float eye);
17 void view_matrix(float eye);
19 void reshape(int x, int y);
20 void keyb(unsigned char key, int x, int y);
21 void keyb_up(unsigned char key, int x, int y);
22 void mouse(int bn, int state, int x, int y);
23 void motion(int x, int y);
24 void sball_motion(int x, int y, int z);
25 void sball_rotate(int x, int y, int z);
26 void sball_button(int bn, int state);
27 int parse_args(int argc, char **argv);
29 char *scene_fname;
30 int win_width, win_height;
31 int stereo;
32 int flip_winding;
33 int auto_rot;
34 float cam_theta, cam_phi, cam_dist = 10;
35 float near_clip = 0.5;
36 float far_clip = 1000.0;
37 float fov = M_PI / 4.0;
38 float stereo_focus_dist = 1.0;
39 float stereo_eye_sep = 1.0 / 30.0;
41 int verbose = 0;
43 struct scene scn;
45 int main(int argc, char **argv)
46 {
47 float amb[] = {0.01, 0.01, 0.01, 1};
48 float ldir[] = {-1, 1, 1, 0};
49 float dx, dy, dz, diag;
51 glutInitWindowSize(800, 600);
52 glutInit(&argc, argv);
54 if(parse_args(argc, argv) == -1) {
55 return 1;
56 }
58 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0));
59 glutCreateWindow("OpenGL 3D viewer");
61 glutDisplayFunc(disp);
62 glutReshapeFunc(reshape);
63 glutKeyboardFunc(keyb);
64 glutKeyboardUpFunc(keyb_up);
65 glutMouseFunc(mouse);
66 glutMotionFunc(motion);
67 glutSpaceballMotionFunc(sball_motion);
68 glutSpaceballRotateFunc(sball_rotate);
69 glutSpaceballButtonFunc(sball_button);
70 if(auto_rot) {
71 glutIdleFunc(glutPostRedisplay);
72 }
74 glewInit();
76 glEnable(GL_NORMALIZE);
77 glEnable(GL_DEPTH_TEST);
78 glEnable(GL_CULL_FACE);
79 glEnable(GL_LIGHTING);
80 glEnable(GL_LIGHT0);
81 glLightfv(GL_LIGHT0, GL_POSITION, ldir);
83 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
85 if((load_scene(&scn, scene_fname)) == -1) {
86 fprintf(stderr, "failed to load: %s\n", scene_fname);
87 return 1;
88 }
89 dx = scn.bbox.max[0] - scn.bbox.min[0];
90 dy = scn.bbox.max[1] - scn.bbox.min[1];
91 dz = scn.bbox.max[2] - scn.bbox.min[2];
92 diag = sqrt(dx * dx + dy * dy + dz * dz);
93 cam_dist = diag / fov;
94 printf("camera distance: %f\n", cam_dist);
96 glutMainLoop();
97 return 0;
98 }
101 void disp(void)
102 {
103 unsigned int tm = glutGet(GLUT_ELAPSED_TIME);
105 if(stereo) {
106 glDrawBuffer(GL_BACK_LEFT);
107 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
109 glMatrixMode(GL_PROJECTION);
110 glLoadIdentity();
111 proj_matrix(-1);
112 glMatrixMode(GL_MODELVIEW);
113 glLoadIdentity();
114 view_matrix(-1);
116 render(tm);
118 glDrawBuffer(GL_BACK_RIGHT);
119 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
121 glMatrixMode(GL_PROJECTION);
122 glLoadIdentity();
123 proj_matrix(1);
124 glMatrixMode(GL_MODELVIEW);
125 glLoadIdentity();
126 view_matrix(1);
128 render(tm);
129 } else {
130 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
132 glMatrixMode(GL_PROJECTION);
133 glLoadIdentity();
134 proj_matrix(0);
135 glMatrixMode(GL_MODELVIEW);
136 glLoadIdentity();
137 view_matrix(0);
139 render(tm);
140 }
142 glutSwapBuffers();
143 }
145 void render(unsigned int msec)
146 {
147 if(auto_rot) {
148 glRotatef(msec / 10, 0, 1, 0);
149 }
150 render_scene(&scn);
151 }
153 void proj_matrix(float eye)
154 {
155 float vfov_rad = fov;
156 float top = near_clip * tan(vfov_rad * 0.5);
157 float right = top * (float)win_width / (float)win_height;
159 float frust_shift = eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist);
161 glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip);
162 }
164 void view_matrix(float eye)
165 {
166 float offs = stereo_eye_sep * eye * 0.5;
167 glTranslatef(offs, 0, 0);
169 glTranslatef(0, 0, -cam_dist);
170 glRotatef(cam_phi, 1, 0, 0);
171 glRotatef(cam_theta, 0, 1, 0);
172 }
174 void reshape(int x, int y)
175 {
176 glViewport(0, 0, x, y);
177 win_width = x;
178 win_height = y;
179 }
181 static int stereo_shift_key;
183 void keyb(unsigned char key, int x, int y)
184 {
185 switch(key) {
186 case 'q':
187 case 27:
188 exit(0);
190 case 's':
191 stereo_shift_key = 1;
192 break;
194 case 'c':
195 {
196 static int flip;
197 glFrontFace((++flip & 1) ? GL_CW : GL_CCW);
198 glutPostRedisplay();
199 }
200 break;
202 case 'C':
203 {
204 static int cull = 1;
205 if(++cull & 1) {
206 glEnable(GL_CULL_FACE);
207 } else {
208 glDisable(GL_CULL_FACE);
209 }
210 glutPostRedisplay();
211 }
212 break;
214 case 'w':
215 {
216 static int wire;
217 glPolygonMode(GL_FRONT_AND_BACK, (++wire & 1) ? GL_LINE : GL_FILL);
218 glutPostRedisplay();
219 }
220 break;
222 case 'l':
223 {
224 static int lit = 1;
225 if(++lit & 1) {
226 glEnable(GL_LIGHTING);
227 } else {
228 glDisable(GL_LIGHTING);
229 }
230 glutPostRedisplay();
231 }
232 break;
234 case ' ':
235 auto_rot = !auto_rot;
236 if(auto_rot) {
237 glutIdleFunc(glutPostRedisplay);
238 } else {
239 glutIdleFunc(0);
240 }
241 glutPostRedisplay();
242 break;
244 default:
245 break;
246 }
247 }
249 void keyb_up(unsigned char key, int x, int y)
250 {
251 switch(key) {
252 case 's':
253 stereo_shift_key = 0;
254 break;
256 default:
257 break;
258 }
259 }
262 static int bnstate[32];
263 static int prev_x, prev_y;
264 void mouse(int bn, int state, int x, int y)
265 {
266 prev_x = x;
267 prev_y = y;
268 bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN ? 1 : 0;
269 }
271 void motion(int x, int y)
272 {
273 int dx = x - prev_x;
274 int dy = y - prev_y;
275 prev_x = x;
276 prev_y = y;
278 if(stereo_shift_key && dy != 0) {
279 stereo_focus_dist += dy * 0.1;
280 stereo_eye_sep = stereo_focus_dist / 30.0;
281 glutPostRedisplay();
282 return;
283 }
285 if(bnstate[0]) {
286 cam_theta += dx * 0.5;
287 cam_phi += dy * 0.5;
289 if(cam_phi < -90)
290 cam_phi = -90;
291 if(cam_phi > 90)
292 cam_phi = 90;
294 glutPostRedisplay();
295 }
296 if(bnstate[2]) {
297 cam_dist += dy * 0.1;
298 glutPostRedisplay();
299 }
300 }
302 void sball_motion(int x, int y, int z)
303 {
304 }
306 void sball_rotate(int x, int y, int z)
307 {
308 cam_theta += y * 0.05;
309 cam_phi += x * 0.05;
311 if(cam_phi < -90)
312 cam_phi = -90;
313 if(cam_phi > 90)
314 cam_phi = 90;
316 glutPostRedisplay();
317 }
319 void sball_button(int bn, int state)
320 {
321 }
323 int parse_args(int argc, char **argv)
324 {
325 int i;
327 for(i=1; i<argc; i++) {
328 if(argv[i][0] == '-') {
329 if(argv[i][2] != 0)
330 goto inval;
331 switch(argv[i][1]) {
332 case 's':
333 stereo = 1;
334 break;
336 case 'c':
337 flip_winding = 1;
338 break;
340 case 'v':
341 verbose = !verbose;
342 break;
344 default:
345 goto inval;
346 }
347 } else {
348 if(scene_fname) {
349 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
350 return -1;
351 }
352 scene_fname = argv[i];
353 }
354 }
356 if(!scene_fname) {
357 fprintf(stderr, "you must pass the filename of a scene to open\n");
358 return -1;
359 }
361 return 0;
363 inval:
364 fprintf(stderr, "invalid argument: %s\n", argv[i]);
365 return -1;
366 }