scenefile

view scnviewgl/scnviewgl.c @ 3:b30f83409769

foo
author John Tsiombikas <nuclear@mutantstargoat.com>
date Sat, 21 Jan 2012 04:14:24 +0200
parents
children
line source
1 #include <stdio.h>
2 #include <assert.h>
4 #ifndef __APPLE__
5 #include <GL/glut.h>
6 #else
7 #include <GLUT/glut.h>
8 #endif
10 #include "scene.h"
12 void disp(void);
13 void render_scene(struct scenefile *scn);
14 void render_mesh(struct mesh *m);
15 void reshape(int x, int y);
16 void keyb(unsigned char key, int x, int y);
17 void mouse(int bn, int state, int x, int y);
18 void motion(int x, int y);
19 void sball_motion(int x, int y, int z);
20 void sball_rotate(int x, int y, int z);
21 void sball_button(int bn, int state);
22 int parse_args(int argc, char **argv);
24 struct scenefile *scn;
25 float cam_theta, cam_phi, cam_dist = 10;
27 int main(int argc, char **argv)
28 {
29 float ldir[] = {-1, 1, 1, 0};
31 glutInitWindowSize(800, 600);
32 glutInit(&argc, argv);
34 if(parse_args(argc, argv) == -1) {
35 return 1;
36 }
38 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
39 glutCreateWindow("OpenGL Scene Viewer");
41 glutDisplayFunc(disp);
42 glutReshapeFunc(reshape);
43 glutKeyboardFunc(keyb);
44 glutMouseFunc(mouse);
45 glutMotionFunc(motion);
46 glutSpaceballMotionFunc(sball_motion);
47 glutSpaceballRotateFunc(sball_rotate);
48 glutSpaceballButtonFunc(sball_button);
50 glEnable(GL_DEPTH_TEST);
51 glEnable(GL_CULL_FACE);
52 glEnable(GL_LIGHTING);
53 glEnable(GL_LIGHT0);
54 glLightfv(GL_LIGHT0, GL_POSITION, ldir);
56 glutMainLoop();
57 return 0;
58 }
61 void disp(void)
62 {
63 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
65 glMatrixMode(GL_MODELVIEW);
66 glLoadIdentity();
67 glRotatef(cam_theta, 0, 1, 0);
68 glRotatef(cam_phi, 1, 0, 0);
69 glTranslatef(0, 0, -cam_dist);
71 render_scene(scn);
73 glutSwapBuffers();
74 }
76 void render_scene(struct scenefile *scn)
77 {
78 int i, num = scnfile_count(scn);
80 for(i=0; i<num; i++) {
81 struct mesh *m = scnfile_mesh(scn, i);
82 render_mesh(m);
83 }
84 }
86 void render_mesh(struct mesh *m)
87 {
88 int i, j, poly_verts, npoly;
89 int vloc, nloc, tloc;
90 int *vidx, *nidx, *tidx;
92 npoly = mesh_poly_count(m);
93 poly_verts = mesh_poly_type(m);
95 if((vloc = mesh_find_attrib(m, "vertex")) == -1) {
96 return;
97 }
98 vidx = mesh_poly_data(m, vloc);
100 if((nloc = mesh_find_attrib(m, "normal")) != -1) {
101 nidx = mesh_poly_data(m, nloc);
102 }
104 if((tloc = mesh_find_attrib(m, "texture")) != -1) {
105 tidx = mesh_poly_data(m, tloc);
106 }
108 glBegin(poly_verts == 3 ? GL_TRIANGLES : GL_QUADS);
109 for(i=0; i<npoly; i++) {
110 for(j=0; j<poly_verts; j++) {
111 void *ptr;
112 if(nloc >= 0) {
113 ptr = mesh_attrib_elem(m, nloc, *nidx++);
114 assert(ptr);
115 glNormal3fv(ptr);
116 }
117 if(tloc >= 0) {
118 ptr = mesh_attrib_elem(m, tloc, *tidx++);
119 assert(ptr);
120 glTexCoord2fv(ptr);
121 }
122 ptr = mesh_attrib_elem(m, vloc, *vidx++);
123 assert(ptr);
124 glVertex3fv(ptr);
125 }
126 }
127 glEnd();
128 }
131 void reshape(int x, int y)
132 {
133 glViewport(0, 0, x, y);
135 glMatrixMode(GL_PROJECTION);
136 glLoadIdentity();
137 gluPerspective(45.0, (float)x / (float)y, 0.5, 1000.0);
138 }
140 void keyb(unsigned char key, int x, int y)
141 {
142 switch(key) {
143 case 27:
144 case 'q':
145 exit(0);
147 case 'c':
148 {
149 static int flip;
150 if(++flip & 1) {
151 glFrontFace(GL_CW);
152 } else {
153 glFrontFace(GL_CCW);
154 }
155 }
156 break;
158 case 'l':
159 {
160 static int lton = 1;
161 if(++lton & 1) {
162 glEnable(GL_LIGHTING);
163 } else {
164 glDisable(GL_LIGHTING);
165 }
166 }
167 break;
169 case 'w':
170 {
171 static int wire;
172 if(++wire & 1) {
173 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
174 } else {
175 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
176 }
177 }
178 break;
180 default:
181 break;
182 }
183 }
185 int prev_x, prev_y;
186 int bnstate[32];
188 void mouse(int bn, int state, int x, int y)
189 {
190 bnstate[bn] = state == GLUT_DOWN ? 1 : 0;
191 prev_x = x;
192 prev_y = y;
193 }
195 void motion(int x, int y)
196 {
197 int dx = x - prev_x;
198 int dy = y - prev_y;
199 prev_x = x;
200 prev_y = y;
202 if(bnstate[1]) {
203 cam_theta += (float)dx;
204 cam_phi += (float)dy;
206 if(cam_phi < -90)
207 cam_phi = -90;
208 if(cam_phi > 90)
209 cam_phi = 90;
210 }
211 if(bnstate[3]) {
212 cam_dist += (float)dy * 0.1;
214 if(cam_dist < 0)
215 cam_dist = 0;
216 }
217 }
219 void sball_motion(int x, int y, int z)
220 {
221 }
223 void sball_rotate(int x, int y, int z)
224 {
225 }
227 void sball_button(int bn, int state)
228 {
229 }
231 int parse_args(int argc, char **argv)
232 {
233 int i, loaded_something = 0;
235 for(i=0; i<argc; i++) {
236 if(argv[i][0] == '-') {
237 if(argv[i][2] != 0) {
238 goto inval;
239 }
240 switch(argv[i][1]) {
241 default:
242 goto inval;
243 }
244 } else {
245 if(scnfile_load(scn, argv[i])) {
246 fprintf(stderr, "failed to load %s\n", argv[i]);
247 return -1;
248 }
249 loaded_something = 1;
250 }
251 }
253 if(!loaded_something) {
254 fprintf(stderr, "pass the filename(s) of the scene(s) you wish to view\n");
255 return -1;
256 }
257 return 0;
259 inval:
260 fprintf(stderr, "invalid argument: %s\n", argv[i]);
261 return -1;
262 }