goat3d

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