goat3d

annotate goatview/src/main.c @ 56:ca549434dc95

fixed a crashing bug in anm_destroy_node introduced when I added the multiple animations per node
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Jan 2014 02:50:54 +0200
parents f5fdefbb7a1d
children
rev   line source
nuclear@19 1 #include <stdio.h>
nuclear@19 2 #include <stdlib.h>
nuclear@19 3 #include <assert.h>
nuclear@19 4 #ifndef __APPLE__
nuclear@19 5 #include <GL/glut.h>
nuclear@19 6 #else
nuclear@19 7 #include <GLUT/glut.h>
nuclear@19 8 #endif
nuclear@19 9 #include "goat3d.h"
nuclear@19 10
nuclear@19 11 static void cleanup(void);
nuclear@19 12 static void disp(void);
nuclear@19 13 static void draw_scene(struct goat3d *g);
nuclear@19 14 static void draw_mesh(struct goat3d_mesh *mesh);
nuclear@19 15 static void reshape(int x, int y);
nuclear@19 16 static void keyb(unsigned char key, int x, int y);
nuclear@19 17 static void mouse(int bn, int st, int x, int y);
nuclear@19 18 static void motion(int x, int y);
nuclear@19 19
nuclear@19 20 static struct goat3d *goat;
nuclear@19 21 static float cam_theta, cam_phi, cam_dist = 10;
nuclear@19 22
nuclear@19 23 int main(int argc, char **argv)
nuclear@19 24 {
nuclear@46 25 int i, nmeshes;
nuclear@46 26
nuclear@19 27 glutInitWindowSize(800, 600);
nuclear@19 28 glutInit(&argc, argv);
nuclear@19 29
nuclear@19 30 if(!argv[1]) {
nuclear@19 31 fprintf(stderr, "you must specify a goat3d scene file to open\n");
nuclear@19 32 return 1;
nuclear@19 33 }
nuclear@19 34
nuclear@19 35 if(!(goat = goat3d_create())) {
nuclear@19 36 fprintf(stderr, "failed to create goat3d\n");
nuclear@19 37 return 1;
nuclear@19 38 }
nuclear@19 39 if(goat3d_load(goat, argv[1]) == -1) {
nuclear@19 40 fprintf(stderr, "failed to load goat3d scene: %s\n", argv[1]);
nuclear@19 41 goat3d_free(goat);
nuclear@19 42 return 1;
nuclear@19 43 }
nuclear@19 44
nuclear@46 45 nmeshes = goat3d_get_mesh_count(goat);
nuclear@46 46 printf("loaded %d meshes\n", nmeshes);
nuclear@46 47 for(i=0; i<nmeshes; i++) {
nuclear@46 48 struct goat3d_mesh *m = goat3d_get_mesh(goat, i);
nuclear@46 49
nuclear@46 50 printf("- mesh[%d]: %s (%d verts, %d faces)\n", i, goat3d_get_mesh_name(m),
nuclear@46 51 goat3d_get_mesh_attrib_count(m, GOAT3D_MESH_ATTR_VERTEX),
nuclear@46 52 goat3d_get_mesh_face_count(m));
nuclear@46 53 }
nuclear@46 54
nuclear@19 55 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
nuclear@19 56 glutCreateWindow(argv[1]);
nuclear@19 57
nuclear@19 58 glutDisplayFunc(disp);
nuclear@19 59 glutReshapeFunc(reshape);
nuclear@19 60 glutKeyboardFunc(keyb);
nuclear@19 61 glutMouseFunc(mouse);
nuclear@19 62 glutMotionFunc(motion);
nuclear@19 63
nuclear@19 64 glEnable(GL_DEPTH_TEST);
nuclear@19 65 glEnable(GL_CULL_FACE);
nuclear@19 66 glEnable(GL_LIGHTING);
nuclear@19 67 glEnable(GL_LIGHT0);
nuclear@19 68
nuclear@19 69 glClearColor(0.1, 0.1, 0.1, 1.0);
nuclear@19 70
nuclear@19 71 atexit(cleanup);
nuclear@19 72
nuclear@19 73 glutMainLoop();
nuclear@19 74 return 0;
nuclear@19 75 }
nuclear@19 76
nuclear@19 77 static void cleanup(void)
nuclear@19 78 {
nuclear@19 79 goat3d_free(goat);
nuclear@19 80 }
nuclear@19 81
nuclear@19 82 static void disp(void)
nuclear@19 83 {
nuclear@19 84 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@19 85
nuclear@19 86 glMatrixMode(GL_MODELVIEW);
nuclear@19 87 glLoadIdentity();
nuclear@19 88 glTranslatef(0, 0, -cam_dist);
nuclear@19 89 glRotatef(cam_phi, 1, 0, 0);
nuclear@19 90 glRotatef(cam_theta, 0, 1, 0);
nuclear@19 91
nuclear@19 92 draw_scene(goat);
nuclear@19 93
nuclear@19 94 glutSwapBuffers();
nuclear@19 95 assert(glGetError() == GL_NO_ERROR);
nuclear@19 96 }
nuclear@19 97
nuclear@19 98 static void draw_scene(struct goat3d *g)
nuclear@19 99 {
nuclear@19 100 int i, num_meshes;
nuclear@19 101
nuclear@19 102 num_meshes = goat3d_get_mesh_count(g);
nuclear@19 103 for(i=0; i<num_meshes; i++) {
nuclear@19 104 struct goat3d_mesh *mesh = goat3d_get_mesh(g, i);
nuclear@19 105 draw_mesh(mesh);
nuclear@19 106 }
nuclear@19 107 }
nuclear@19 108
nuclear@19 109 static void draw_mesh(struct goat3d_mesh *mesh)
nuclear@19 110 {
nuclear@19 111 int vnum, fnum;
nuclear@19 112 struct goat3d_material *mtl;
nuclear@19 113 float *verts, *normals, *texcoords;
nuclear@19 114 int *vidx;
nuclear@19 115
nuclear@19 116 if((mtl = goat3d_get_mesh_mtl(mesh))) {
nuclear@20 117 float white[] = {1, 1, 1, 1};
nuclear@20 118 float black[] = {0, 0, 0, 0};
nuclear@20 119 float zero = 0.0;
nuclear@20 120 const float *diffuse, *specular, *shininess;
nuclear@20 121
nuclear@20 122 if(!(diffuse = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) {
nuclear@20 123 diffuse = white;
nuclear@20 124 }
nuclear@20 125 if(!(specular = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) {
nuclear@20 126 specular = black;
nuclear@20 127 }
nuclear@20 128 if(!(shininess = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SHININESS))) {
nuclear@20 129 shininess = &zero;
nuclear@20 130 }
nuclear@20 131
nuclear@20 132 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
nuclear@20 133 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
nuclear@20 134 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, *shininess);
nuclear@19 135 }
nuclear@19 136
nuclear@19 137 vnum = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX);
nuclear@19 138 fnum = goat3d_get_mesh_face_count(mesh);
nuclear@19 139
nuclear@19 140 if(!vnum || !fnum) {
nuclear@19 141 return;
nuclear@19 142 }
nuclear@19 143
nuclear@19 144 verts = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
nuclear@19 145 normals = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
nuclear@19 146 texcoords = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
nuclear@19 147 vidx = goat3d_get_mesh_faces(mesh);
nuclear@19 148
nuclear@19 149 glEnableClientState(GL_VERTEX_ARRAY);
nuclear@19 150 glVertexPointer(3, GL_FLOAT, 0, verts);
nuclear@19 151
nuclear@19 152 if(normals) {
nuclear@19 153 glEnableClientState(GL_NORMAL_ARRAY);
nuclear@19 154 glNormalPointer(GL_FLOAT, 0, normals);
nuclear@19 155 }
nuclear@19 156 if(texcoords) {
nuclear@19 157 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@19 158 glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
nuclear@19 159 }
nuclear@19 160
nuclear@19 161 glDrawElements(GL_TRIANGLES, fnum * 3, GL_UNSIGNED_INT, vidx);
nuclear@19 162
nuclear@19 163 glDisableClientState(GL_VERTEX_ARRAY);
nuclear@19 164 if(normals) {
nuclear@19 165 glDisableClientState(GL_NORMAL_ARRAY);
nuclear@19 166 }
nuclear@19 167 if(texcoords) {
nuclear@19 168 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@19 169 }
nuclear@19 170 }
nuclear@19 171
nuclear@19 172 static void reshape(int x, int y)
nuclear@19 173 {
nuclear@19 174 glViewport(0, 0, x, y);
nuclear@19 175
nuclear@19 176 glMatrixMode(GL_PROJECTION);
nuclear@19 177 glLoadIdentity();
nuclear@19 178 gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0);
nuclear@19 179 }
nuclear@19 180
nuclear@19 181 static void keyb(unsigned char key, int x, int y)
nuclear@19 182 {
nuclear@19 183 switch(key) {
nuclear@19 184 case 27:
nuclear@19 185 exit(0);
nuclear@19 186 }
nuclear@19 187 }
nuclear@19 188
nuclear@19 189 static int bnstate[32];
nuclear@19 190 static int prev_x, prev_y;
nuclear@19 191
nuclear@19 192 static void mouse(int bn, int st, int x, int y)
nuclear@19 193 {
nuclear@19 194 bnstate[bn - GLUT_LEFT_BUTTON] = (st == GLUT_DOWN);
nuclear@19 195 prev_x = x;
nuclear@19 196 prev_y = y;
nuclear@19 197 }
nuclear@19 198
nuclear@19 199 static void motion(int x, int y)
nuclear@19 200 {
nuclear@19 201 int dx = x - prev_x;
nuclear@19 202 int dy = y - prev_y;
nuclear@19 203 prev_x = x;
nuclear@19 204 prev_y = y;
nuclear@19 205
nuclear@19 206 if(bnstate[0]) {
nuclear@19 207 cam_theta += dx * 0.5;
nuclear@19 208 cam_phi += dy * 0.5;
nuclear@19 209
nuclear@19 210 if(cam_phi < -90) cam_phi = -90;
nuclear@19 211 if(cam_phi > 90) cam_phi = 90;
nuclear@19 212 glutPostRedisplay();
nuclear@19 213 }
nuclear@19 214 if(bnstate[2]) {
nuclear@19 215 cam_dist += dy * 0.1;
nuclear@19 216
nuclear@19 217 if(cam_dist < 0) cam_dist = 0;
nuclear@19 218 glutPostRedisplay();
nuclear@19 219 }
nuclear@19 220 }