a23fcb54186a01118040a25894151672651f28ee
[hair] / src / main.cc
1 #include <GL/glew.h>
2 #include <GL/glut.h>
3
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string>
8
9 #include "mesh.h"
10 #include "hair.h"
11
12 #define MAX_NUM_SPAWNS 4
13 #define THRESH 0.5
14
15 static bool init();
16 static void cleanup();
17 static void display();
18 static void reshape(int x, int y);
19 static void keydown(unsigned char key, int x, int y);
20 static void mouse(int bn, int st, int x, int y);
21 static void motion(int x, int y);
22
23 static std::vector<Mesh*> meshes;
24 static Mesh *mesh_head;
25 static Hair hair;
26
27 static int win_width, win_height;
28 static float cam_theta, cam_phi = 25, cam_dist = 8;
29
30 int main(int argc, char **argv)
31 {
32         glutInit(&argc, argv);
33         glutInitWindowSize(800, 600);
34         glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
35         glutCreateWindow("hair test");
36
37         glutDisplayFunc(display);
38         glutReshapeFunc(reshape);
39         glutKeyboardFunc(keydown);
40         glutMouseFunc(mouse);
41         glutMotionFunc(motion);
42
43         if(!init()) {
44                 return 1;
45         }
46         atexit(cleanup);
47
48         glutMainLoop();
49         return 0;
50 }
51
52 static bool init()
53 {
54         glewInit();
55
56         glEnable(GL_DEPTH_TEST);
57         glEnable(GL_CULL_FACE);
58         glEnable(GL_COLOR_MATERIAL);
59
60         glEnable(GL_LIGHTING);
61         glEnable(GL_LIGHT0);
62
63         glClearColor(0.5, 0.5, 0.5, 1);
64         meshes = load_meshes("data/head.fbx");
65         if (meshes.empty()) {
66                 fprintf(stderr, "Failed to load mesh.\n");
67                 return false;
68         }
69
70         for(size_t i=0; i<meshes.size(); i++) {
71                 meshes[i]->calc_bbox();
72 /*
73                 Vec3 v0 = meshes[i]->bbox.v0;
74                 Vec3 v1 = meshes[i]->bbox.v1;
75
76                 printf("mesh: %s\n", meshes[i]->name.c_str());
77                 printf("AABB mesh %d: v0: (%f, %f, %f) v1: (%f, %f, %f)\n",
78                                 (int)i, v0.x, v0.y, v0.z, v1.x, v1.y, v1.z);
79 */
80                 meshes[i]->update_vbo(MESH_ALL);
81 /*
82                 printf("num vertices: %d num triangles: %d\n",
83                                 (int)meshes[i]->vertices.size(),
84                                 (int)meshes[i]->indices.size() / 3);
85 */
86                 if(meshes[i]->name == "head") {
87                         mesh_head = meshes[i];
88                 }
89         }
90         if(!mesh_head) {
91                 fprintf(stderr, "Failed to find the head mesh.\n");
92                 return false;
93         }
94
95         if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
96                 fprintf(stderr, "Failed to initialize hair\n");
97                 return false;
98         }
99
100         return true;
101 }
102
103 static void cleanup()
104 {
105         for(size_t i=0; i<meshes.size(); i++) {
106                 delete meshes[i];
107         }
108 }
109
110 static void display()
111 {
112         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
113
114         glMatrixMode(GL_MODELVIEW);
115         glLoadIdentity();
116         glTranslatef(0, 0, -cam_dist);
117         glRotatef(cam_phi, 1, 0, 0);
118         glRotatef(cam_theta, 0, 1, 0);
119
120         for(size_t i=0; i<meshes.size(); i++) {
121                 meshes[i]->draw();
122         }
123
124         hair.draw();
125
126         glutSwapBuffers();
127         assert(glGetError() == GL_NO_ERROR);
128 }
129
130 static void reshape(int x, int y)
131 {
132         glViewport(0, 0, x, y);
133         win_width = x;
134         win_height = y;
135
136         glMatrixMode(GL_PROJECTION);
137         glLoadIdentity();
138         gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
139 }
140
141 static void keydown(unsigned char key, int /*x*/, int /*y*/)
142 {
143         switch(key) {
144         case 27:
145                 exit(0);
146         }
147 }
148
149 bool bnstate[8];
150 int prev_x, prev_y;
151
152 static void mouse(int bn, int st, int x, int y)
153 {
154         bnstate[bn] = st == GLUT_DOWN;
155         prev_x = x;
156         prev_y = y;
157 }
158
159 static void motion(int x, int y)
160 {
161         int dx = x - prev_x;
162         int dy = y - prev_y;
163         prev_x = x;
164         prev_y = y;
165
166         if(!dx && !dy) return;
167
168         if(bnstate[0]) {
169                 cam_theta += dx * 0.5;
170                 cam_phi += dy * 0.5;
171
172                 if(cam_phi < -90) cam_phi = -90;
173                 if(cam_phi > 90) cam_phi = 90;
174                 glutPostRedisplay();
175         }
176         if(bnstate[2]) {
177                 cam_dist += dy * 0.1;
178                 if(cam_dist < 0) cam_dist = 0;
179                 glutPostRedisplay();
180         }
181 }