Added anchor points and hair strands.
[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 int win_width, win_height;
28 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                 printf("num vertices: %d num triangles: %d\n",
82                                 (int)meshes[i]->vertices.size(),
83                                 (int)meshes[i]->indices.size() / 3);
84
85                 if(meshes[i]->name == "head") {
86                         mesh_head = meshes[i];
87                 }
88         }
89         if(!mesh_head) {
90                 fprintf(stderr, "Failed to find the head mesh.\n");
91                 return false;
92         }
93
94         if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
95                 fprintf(stderr, "Failed to initialize hair\n");
96                 return false;
97         }
98
99         return true;
100 }
101
102 static void cleanup()
103 {
104         for(size_t i=0; i<meshes.size(); i++) {
105                 delete meshes[i];
106         }
107 }
108
109 static void display()
110 {
111         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
112
113         glMatrixMode(GL_MODELVIEW);
114         glLoadIdentity();
115         glTranslatef(0, 0, -cam_dist);
116         glRotatef(cam_phi, 1, 0, 0);
117         glRotatef(cam_theta, 0, 1, 0);
118
119         for(size_t i=0; i<meshes.size(); i++) {
120                 meshes[i]->draw();
121         }
122
123         hair.draw();
124
125         glutSwapBuffers();
126         assert(glGetError() == GL_NO_ERROR);
127 }
128
129 static void reshape(int x, int y)
130 {
131         glViewport(0, 0, x, y);
132         win_width = x;
133         win_height = y;
134
135         glMatrixMode(GL_PROJECTION);
136         glLoadIdentity();
137         gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
138 }
139
140 static void keydown(unsigned char key, int /*x*/, int /*y*/)
141 {
142         switch(key) {
143         case 27:
144                 exit(0);
145         }
146 }
147
148 bool bnstate[8];
149 int prev_x, prev_y;
150
151 static void mouse(int bn, int st, int x, int y)
152 {
153         bnstate[bn] = st == GLUT_DOWN;
154         prev_x = x;
155         prev_y = y;
156 }
157
158 static void motion(int x, int y)
159 {
160         int dx = x - prev_x;
161         int dy = y - prev_y;
162         prev_x = x;
163         prev_y = y;
164
165         if(!dx && !dy) return;
166
167         if(bnstate[0]) {
168                 cam_theta += dx * 0.5;
169                 cam_phi += dy * 0.5;
170
171                 if(cam_phi < -90) cam_phi = -90;
172                 if(cam_phi > 90) cam_phi = 90;
173                 glutPostRedisplay();
174         }
175         if(bnstate[2]) {
176                 cam_dist += dy * 0.1;
177                 if(cam_dist < 0) cam_dist = 0;
178                 glutPostRedisplay();
179         }
180 }