goat3d

view goatview/src/main.c @ 20:f5fdefbb7a1d

added materials loading to goatview
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Sep 2013 07:06:07 +0300
parents b35427826b60
children 9d911100935b
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 float white[] = {1, 1, 1, 1};
106 float black[] = {0, 0, 0, 0};
107 float zero = 0.0;
108 const float *diffuse, *specular, *shininess;
110 if(!(diffuse = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) {
111 diffuse = white;
112 }
113 if(!(specular = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) {
114 specular = black;
115 }
116 if(!(shininess = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SHININESS))) {
117 shininess = &zero;
118 }
120 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
121 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
122 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, *shininess);
123 }
125 vnum = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX);
126 fnum = goat3d_get_mesh_face_count(mesh);
128 if(!vnum || !fnum) {
129 return;
130 }
132 verts = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
133 normals = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
134 texcoords = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
135 vidx = goat3d_get_mesh_faces(mesh);
137 glEnableClientState(GL_VERTEX_ARRAY);
138 glVertexPointer(3, GL_FLOAT, 0, verts);
140 if(normals) {
141 glEnableClientState(GL_NORMAL_ARRAY);
142 glNormalPointer(GL_FLOAT, 0, normals);
143 }
144 if(texcoords) {
145 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
146 glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
147 }
149 glDrawElements(GL_TRIANGLES, fnum * 3, GL_UNSIGNED_INT, vidx);
151 glDisableClientState(GL_VERTEX_ARRAY);
152 if(normals) {
153 glDisableClientState(GL_NORMAL_ARRAY);
154 }
155 if(texcoords) {
156 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
157 }
158 }
160 static void reshape(int x, int y)
161 {
162 glViewport(0, 0, x, y);
164 glMatrixMode(GL_PROJECTION);
165 glLoadIdentity();
166 gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0);
167 }
169 static void keyb(unsigned char key, int x, int y)
170 {
171 switch(key) {
172 case 27:
173 exit(0);
174 }
175 }
177 static int bnstate[32];
178 static int prev_x, prev_y;
180 static void mouse(int bn, int st, int x, int y)
181 {
182 bnstate[bn - GLUT_LEFT_BUTTON] = (st == GLUT_DOWN);
183 prev_x = x;
184 prev_y = y;
185 }
187 static void motion(int x, int y)
188 {
189 int dx = x - prev_x;
190 int dy = y - prev_y;
191 prev_x = x;
192 prev_y = y;
194 if(bnstate[0]) {
195 cam_theta += dx * 0.5;
196 cam_phi += dy * 0.5;
198 if(cam_phi < -90) cam_phi = -90;
199 if(cam_phi > 90) cam_phi = 90;
200 glutPostRedisplay();
201 }
202 if(bnstate[2]) {
203 cam_dist += dy * 0.1;
205 if(cam_dist < 0) cam_dist = 0;
206 glutPostRedisplay();
207 }
208 }