goat3d

view goatview/src/main.c @ 64:99715321ad6d

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Apr 2014 08:53:42 +0300
parents f5fdefbb7a1d
children
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 int i, nmeshes;
27 glutInitWindowSize(800, 600);
28 glutInit(&argc, argv);
30 if(!argv[1]) {
31 fprintf(stderr, "you must specify a goat3d scene file to open\n");
32 return 1;
33 }
35 if(!(goat = goat3d_create())) {
36 fprintf(stderr, "failed to create goat3d\n");
37 return 1;
38 }
39 if(goat3d_load(goat, argv[1]) == -1) {
40 fprintf(stderr, "failed to load goat3d scene: %s\n", argv[1]);
41 goat3d_free(goat);
42 return 1;
43 }
45 nmeshes = goat3d_get_mesh_count(goat);
46 printf("loaded %d meshes\n", nmeshes);
47 for(i=0; i<nmeshes; i++) {
48 struct goat3d_mesh *m = goat3d_get_mesh(goat, i);
50 printf("- mesh[%d]: %s (%d verts, %d faces)\n", i, goat3d_get_mesh_name(m),
51 goat3d_get_mesh_attrib_count(m, GOAT3D_MESH_ATTR_VERTEX),
52 goat3d_get_mesh_face_count(m));
53 }
55 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
56 glutCreateWindow(argv[1]);
58 glutDisplayFunc(disp);
59 glutReshapeFunc(reshape);
60 glutKeyboardFunc(keyb);
61 glutMouseFunc(mouse);
62 glutMotionFunc(motion);
64 glEnable(GL_DEPTH_TEST);
65 glEnable(GL_CULL_FACE);
66 glEnable(GL_LIGHTING);
67 glEnable(GL_LIGHT0);
69 glClearColor(0.1, 0.1, 0.1, 1.0);
71 atexit(cleanup);
73 glutMainLoop();
74 return 0;
75 }
77 static void cleanup(void)
78 {
79 goat3d_free(goat);
80 }
82 static void disp(void)
83 {
84 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
86 glMatrixMode(GL_MODELVIEW);
87 glLoadIdentity();
88 glTranslatef(0, 0, -cam_dist);
89 glRotatef(cam_phi, 1, 0, 0);
90 glRotatef(cam_theta, 0, 1, 0);
92 draw_scene(goat);
94 glutSwapBuffers();
95 assert(glGetError() == GL_NO_ERROR);
96 }
98 static void draw_scene(struct goat3d *g)
99 {
100 int i, num_meshes;
102 num_meshes = goat3d_get_mesh_count(g);
103 for(i=0; i<num_meshes; i++) {
104 struct goat3d_mesh *mesh = goat3d_get_mesh(g, i);
105 draw_mesh(mesh);
106 }
107 }
109 static void draw_mesh(struct goat3d_mesh *mesh)
110 {
111 int vnum, fnum;
112 struct goat3d_material *mtl;
113 float *verts, *normals, *texcoords;
114 int *vidx;
116 if((mtl = goat3d_get_mesh_mtl(mesh))) {
117 float white[] = {1, 1, 1, 1};
118 float black[] = {0, 0, 0, 0};
119 float zero = 0.0;
120 const float *diffuse, *specular, *shininess;
122 if(!(diffuse = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) {
123 diffuse = white;
124 }
125 if(!(specular = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) {
126 specular = black;
127 }
128 if(!(shininess = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SHININESS))) {
129 shininess = &zero;
130 }
132 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
133 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
134 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, *shininess);
135 }
137 vnum = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX);
138 fnum = goat3d_get_mesh_face_count(mesh);
140 if(!vnum || !fnum) {
141 return;
142 }
144 verts = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
145 normals = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
146 texcoords = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
147 vidx = goat3d_get_mesh_faces(mesh);
149 glEnableClientState(GL_VERTEX_ARRAY);
150 glVertexPointer(3, GL_FLOAT, 0, verts);
152 if(normals) {
153 glEnableClientState(GL_NORMAL_ARRAY);
154 glNormalPointer(GL_FLOAT, 0, normals);
155 }
156 if(texcoords) {
157 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
158 glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
159 }
161 glDrawElements(GL_TRIANGLES, fnum * 3, GL_UNSIGNED_INT, vidx);
163 glDisableClientState(GL_VERTEX_ARRAY);
164 if(normals) {
165 glDisableClientState(GL_NORMAL_ARRAY);
166 }
167 if(texcoords) {
168 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
169 }
170 }
172 static void reshape(int x, int y)
173 {
174 glViewport(0, 0, x, y);
176 glMatrixMode(GL_PROJECTION);
177 glLoadIdentity();
178 gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0);
179 }
181 static void keyb(unsigned char key, int x, int y)
182 {
183 switch(key) {
184 case 27:
185 exit(0);
186 }
187 }
189 static int bnstate[32];
190 static int prev_x, prev_y;
192 static void mouse(int bn, int st, int x, int y)
193 {
194 bnstate[bn - GLUT_LEFT_BUTTON] = (st == GLUT_DOWN);
195 prev_x = x;
196 prev_y = y;
197 }
199 static void motion(int x, int y)
200 {
201 int dx = x - prev_x;
202 int dy = y - prev_y;
203 prev_x = x;
204 prev_y = y;
206 if(bnstate[0]) {
207 cam_theta += dx * 0.5;
208 cam_phi += dy * 0.5;
210 if(cam_phi < -90) cam_phi = -90;
211 if(cam_phi > 90) cam_phi = 90;
212 glutPostRedisplay();
213 }
214 if(bnstate[2]) {
215 cam_dist += dy * 0.1;
217 if(cam_dist < 0) cam_dist = 0;
218 glutPostRedisplay();
219 }
220 }