goat3d

view goatview/src/main.c @ 19:b35427826b60

- added XML format reading support - wrote a rudimentary version of goatview
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Sep 2013 06:58:37 +0300
parents
children f5fdefbb7a1d
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #ifndef __APPLE__
5 #include <GL/glut.h>
6 #else
7 #include <GLUT/glut.h>
8 #endif
9 #include "goat3d.h"
11 static void cleanup(void);
12 static void disp(void);
13 static void draw_scene(struct goat3d *g);
14 static void draw_mesh(struct goat3d_mesh *mesh);
15 static void reshape(int x, int y);
16 static void keyb(unsigned char key, int x, int y);
17 static void mouse(int bn, int st, int x, int y);
18 static void motion(int x, int y);
20 static struct goat3d *goat;
21 static float cam_theta, cam_phi, cam_dist = 10;
23 int main(int argc, char **argv)
24 {
25 glutInitWindowSize(800, 600);
26 glutInit(&argc, argv);
28 if(!argv[1]) {
29 fprintf(stderr, "you must specify a goat3d scene file to open\n");
30 return 1;
31 }
33 if(!(goat = goat3d_create())) {
34 fprintf(stderr, "failed to create goat3d\n");
35 return 1;
36 }
37 if(goat3d_load(goat, argv[1]) == -1) {
38 fprintf(stderr, "failed to load goat3d scene: %s\n", argv[1]);
39 goat3d_free(goat);
40 return 1;
41 }
43 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
44 glutCreateWindow(argv[1]);
46 glutDisplayFunc(disp);
47 glutReshapeFunc(reshape);
48 glutKeyboardFunc(keyb);
49 glutMouseFunc(mouse);
50 glutMotionFunc(motion);
52 glEnable(GL_DEPTH_TEST);
53 glEnable(GL_CULL_FACE);
54 glEnable(GL_LIGHTING);
55 glEnable(GL_LIGHT0);
57 glClearColor(0.1, 0.1, 0.1, 1.0);
59 atexit(cleanup);
61 glutMainLoop();
62 return 0;
63 }
65 static void cleanup(void)
66 {
67 goat3d_free(goat);
68 }
70 static void disp(void)
71 {
72 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
74 glMatrixMode(GL_MODELVIEW);
75 glLoadIdentity();
76 glTranslatef(0, 0, -cam_dist);
77 glRotatef(cam_phi, 1, 0, 0);
78 glRotatef(cam_theta, 0, 1, 0);
80 draw_scene(goat);
82 glutSwapBuffers();
83 assert(glGetError() == GL_NO_ERROR);
84 }
86 static void draw_scene(struct goat3d *g)
87 {
88 int i, num_meshes;
90 num_meshes = goat3d_get_mesh_count(g);
91 for(i=0; i<num_meshes; i++) {
92 struct goat3d_mesh *mesh = goat3d_get_mesh(g, i);
93 draw_mesh(mesh);
94 }
95 }
97 static void draw_mesh(struct goat3d_mesh *mesh)
98 {
99 int vnum, fnum;
100 struct goat3d_material *mtl;
101 float *verts, *normals, *texcoords;
102 int *vidx;
104 if((mtl = goat3d_get_mesh_mtl(mesh))) {
105 /* TODO */
106 }
108 vnum = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX);
109 fnum = goat3d_get_mesh_face_count(mesh);
111 if(!vnum || !fnum) {
112 return;
113 }
115 verts = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
116 normals = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
117 texcoords = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
118 vidx = goat3d_get_mesh_faces(mesh);
120 glEnableClientState(GL_VERTEX_ARRAY);
121 glVertexPointer(3, GL_FLOAT, 0, verts);
123 if(normals) {
124 glEnableClientState(GL_NORMAL_ARRAY);
125 glNormalPointer(GL_FLOAT, 0, normals);
126 }
127 if(texcoords) {
128 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
129 glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
130 }
132 glDrawElements(GL_TRIANGLES, fnum * 3, GL_UNSIGNED_INT, vidx);
134 glDisableClientState(GL_VERTEX_ARRAY);
135 if(normals) {
136 glDisableClientState(GL_NORMAL_ARRAY);
137 }
138 if(texcoords) {
139 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
140 }
141 }
143 static void reshape(int x, int y)
144 {
145 glViewport(0, 0, x, y);
147 glMatrixMode(GL_PROJECTION);
148 glLoadIdentity();
149 gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0);
150 }
152 static void keyb(unsigned char key, int x, int y)
153 {
154 switch(key) {
155 case 27:
156 exit(0);
157 }
158 }
160 static int bnstate[32];
161 static int prev_x, prev_y;
163 static void mouse(int bn, int st, int x, int y)
164 {
165 bnstate[bn - GLUT_LEFT_BUTTON] = (st == GLUT_DOWN);
166 prev_x = x;
167 prev_y = y;
168 }
170 static void motion(int x, int y)
171 {
172 int dx = x - prev_x;
173 int dy = y - prev_y;
174 prev_x = x;
175 prev_y = y;
177 if(bnstate[0]) {
178 cam_theta += dx * 0.5;
179 cam_phi += dy * 0.5;
181 if(cam_phi < -90) cam_phi = -90;
182 if(cam_phi > 90) cam_phi = 90;
183 glutPostRedisplay();
184 }
185 if(bnstate[2]) {
186 cam_dist += dy * 0.1;
188 if(cam_dist < 0) cam_dist = 0;
189 glutPostRedisplay();
190 }
191 }