goat3d
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/goatview/src/main.c Fri Sep 27 06:58:37 2013 +0300 1.3 @@ -0,0 +1,191 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <assert.h> 1.7 +#ifndef __APPLE__ 1.8 +#include <GL/glut.h> 1.9 +#else 1.10 +#include <GLUT/glut.h> 1.11 +#endif 1.12 +#include "goat3d.h" 1.13 + 1.14 +static void cleanup(void); 1.15 +static void disp(void); 1.16 +static void draw_scene(struct goat3d *g); 1.17 +static void draw_mesh(struct goat3d_mesh *mesh); 1.18 +static void reshape(int x, int y); 1.19 +static void keyb(unsigned char key, int x, int y); 1.20 +static void mouse(int bn, int st, int x, int y); 1.21 +static void motion(int x, int y); 1.22 + 1.23 +static struct goat3d *goat; 1.24 +static float cam_theta, cam_phi, cam_dist = 10; 1.25 + 1.26 +int main(int argc, char **argv) 1.27 +{ 1.28 + glutInitWindowSize(800, 600); 1.29 + glutInit(&argc, argv); 1.30 + 1.31 + if(!argv[1]) { 1.32 + fprintf(stderr, "you must specify a goat3d scene file to open\n"); 1.33 + return 1; 1.34 + } 1.35 + 1.36 + if(!(goat = goat3d_create())) { 1.37 + fprintf(stderr, "failed to create goat3d\n"); 1.38 + return 1; 1.39 + } 1.40 + if(goat3d_load(goat, argv[1]) == -1) { 1.41 + fprintf(stderr, "failed to load goat3d scene: %s\n", argv[1]); 1.42 + goat3d_free(goat); 1.43 + return 1; 1.44 + } 1.45 + 1.46 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 1.47 + glutCreateWindow(argv[1]); 1.48 + 1.49 + glutDisplayFunc(disp); 1.50 + glutReshapeFunc(reshape); 1.51 + glutKeyboardFunc(keyb); 1.52 + glutMouseFunc(mouse); 1.53 + glutMotionFunc(motion); 1.54 + 1.55 + glEnable(GL_DEPTH_TEST); 1.56 + glEnable(GL_CULL_FACE); 1.57 + glEnable(GL_LIGHTING); 1.58 + glEnable(GL_LIGHT0); 1.59 + 1.60 + glClearColor(0.1, 0.1, 0.1, 1.0); 1.61 + 1.62 + atexit(cleanup); 1.63 + 1.64 + glutMainLoop(); 1.65 + return 0; 1.66 +} 1.67 + 1.68 +static void cleanup(void) 1.69 +{ 1.70 + goat3d_free(goat); 1.71 +} 1.72 + 1.73 +static void disp(void) 1.74 +{ 1.75 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.76 + 1.77 + glMatrixMode(GL_MODELVIEW); 1.78 + glLoadIdentity(); 1.79 + glTranslatef(0, 0, -cam_dist); 1.80 + glRotatef(cam_phi, 1, 0, 0); 1.81 + glRotatef(cam_theta, 0, 1, 0); 1.82 + 1.83 + draw_scene(goat); 1.84 + 1.85 + glutSwapBuffers(); 1.86 + assert(glGetError() == GL_NO_ERROR); 1.87 +} 1.88 + 1.89 +static void draw_scene(struct goat3d *g) 1.90 +{ 1.91 + int i, num_meshes; 1.92 + 1.93 + num_meshes = goat3d_get_mesh_count(g); 1.94 + for(i=0; i<num_meshes; i++) { 1.95 + struct goat3d_mesh *mesh = goat3d_get_mesh(g, i); 1.96 + draw_mesh(mesh); 1.97 + } 1.98 +} 1.99 + 1.100 +static void draw_mesh(struct goat3d_mesh *mesh) 1.101 +{ 1.102 + int vnum, fnum; 1.103 + struct goat3d_material *mtl; 1.104 + float *verts, *normals, *texcoords; 1.105 + int *vidx; 1.106 + 1.107 + if((mtl = goat3d_get_mesh_mtl(mesh))) { 1.108 + /* TODO */ 1.109 + } 1.110 + 1.111 + vnum = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX); 1.112 + fnum = goat3d_get_mesh_face_count(mesh); 1.113 + 1.114 + if(!vnum || !fnum) { 1.115 + return; 1.116 + } 1.117 + 1.118 + verts = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX); 1.119 + normals = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL); 1.120 + texcoords = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD); 1.121 + vidx = goat3d_get_mesh_faces(mesh); 1.122 + 1.123 + glEnableClientState(GL_VERTEX_ARRAY); 1.124 + glVertexPointer(3, GL_FLOAT, 0, verts); 1.125 + 1.126 + if(normals) { 1.127 + glEnableClientState(GL_NORMAL_ARRAY); 1.128 + glNormalPointer(GL_FLOAT, 0, normals); 1.129 + } 1.130 + if(texcoords) { 1.131 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1.132 + glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 1.133 + } 1.134 + 1.135 + glDrawElements(GL_TRIANGLES, fnum * 3, GL_UNSIGNED_INT, vidx); 1.136 + 1.137 + glDisableClientState(GL_VERTEX_ARRAY); 1.138 + if(normals) { 1.139 + glDisableClientState(GL_NORMAL_ARRAY); 1.140 + } 1.141 + if(texcoords) { 1.142 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1.143 + } 1.144 +} 1.145 + 1.146 +static void reshape(int x, int y) 1.147 +{ 1.148 + glViewport(0, 0, x, y); 1.149 + 1.150 + glMatrixMode(GL_PROJECTION); 1.151 + glLoadIdentity(); 1.152 + gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0); 1.153 +} 1.154 + 1.155 +static void keyb(unsigned char key, int x, int y) 1.156 +{ 1.157 + switch(key) { 1.158 + case 27: 1.159 + exit(0); 1.160 + } 1.161 +} 1.162 + 1.163 +static int bnstate[32]; 1.164 +static int prev_x, prev_y; 1.165 + 1.166 +static void mouse(int bn, int st, int x, int y) 1.167 +{ 1.168 + bnstate[bn - GLUT_LEFT_BUTTON] = (st == GLUT_DOWN); 1.169 + prev_x = x; 1.170 + prev_y = y; 1.171 +} 1.172 + 1.173 +static void motion(int x, int y) 1.174 +{ 1.175 + int dx = x - prev_x; 1.176 + int dy = y - prev_y; 1.177 + prev_x = x; 1.178 + prev_y = y; 1.179 + 1.180 + if(bnstate[0]) { 1.181 + cam_theta += dx * 0.5; 1.182 + cam_phi += dy * 0.5; 1.183 + 1.184 + if(cam_phi < -90) cam_phi = -90; 1.185 + if(cam_phi > 90) cam_phi = 90; 1.186 + glutPostRedisplay(); 1.187 + } 1.188 + if(bnstate[2]) { 1.189 + cam_dist += dy * 0.1; 1.190 + 1.191 + if(cam_dist < 0) cam_dist = 0; 1.192 + glutPostRedisplay(); 1.193 + } 1.194 +}