9 #include <gmath/gmath.h>
15 #define MAX_NUM_SPAWNS 800
19 static void cleanup();
20 static void display();
21 static void reshape(int x, int y);
22 static void keydown(unsigned char key, int x, int y);
23 static void keyup(unsigned char key, int x, int y);
24 static void mouse(int bn, int st, int x, int y);
25 static void motion(int x, int y);
28 static unsigned int gen_grad_tex(int sz, const Vec3 &c0, const Vec3 &c1);
30 static std::vector<Mesh*> meshes;
31 static Mesh *mesh_head;
34 static unsigned int grad_tex;
36 static int win_width, win_height;
37 static float cam_theta, cam_phi = 25, cam_dist = 8;
38 static float head_rz, head_rx; /* rot angles x, z axis */
39 static Mat4 head_xform;
40 //static CollSphere coll_sphere; /* sphere used for collision detection */
42 int main(int argc, char **argv)
44 glutInit(&argc, argv);
45 glutInitWindowSize(800, 600);
46 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
47 glutCreateWindow("hair test");
49 /* for the keydown, keyup functions to work */
50 glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF);
52 glutDisplayFunc(display);
53 glutReshapeFunc(reshape);
54 glutKeyboardFunc(keydown);
55 glutKeyboardUpFunc(keyup);
57 glutMotionFunc(motion);
73 grad_tex = gen_grad_tex(32, Vec3(0, 0, 1), Vec3(0, 1, 0));
75 glEnable(GL_DEPTH_TEST);
76 glEnable(GL_CULL_FACE);
77 // glEnable(GL_COLOR_MATERIAL);
79 glEnable(GL_LIGHTING);
82 glClearColor(0.5, 0.5, 0.5, 1);
83 meshes = load_meshes("data/head.fbx");
85 fprintf(stderr, "Failed to load mesh.\n");
89 for(size_t i=0; i<meshes.size(); i++) {
90 meshes[i]->calc_bbox();
92 Vec3 v0 = meshes[i]->bbox.v0;
93 Vec3 v1 = meshes[i]->bbox.v1;
95 printf("mesh: %s\n", meshes[i]->name.c_str());
96 printf("AABB mesh %d: v0: (%f, %f, %f) v1: (%f, %f, %f)\n",
97 (int)i, v0.x, v0.y, v0.z, v1.x, v1.y, v1.z);
99 meshes[i]->update_vbo(MESH_ALL);
101 printf("num vertices: %d num triangles: %d\n",
102 (int)meshes[i]->vertices.size(),
103 (int)meshes[i]->indices.size() / 3);
105 if(meshes[i]->name == "head") {
106 mesh_head = meshes[i];
110 fprintf(stderr, "Failed to find the head mesh.\n");
114 // coll_sphere.radius = 1.0;
115 // coll_sphere.center = Vec3(0, 0.6, 0.53);
117 if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
118 fprintf(stderr, "Failed to initialize hair\n");
122 // hair.add_collider(&coll_sphere);
127 static void cleanup()
129 for(size_t i=0; i<meshes.size(); i++) {
132 glDeleteTextures(1, &grad_tex);
135 static void display()
137 static unsigned long prev_time;
138 unsigned long msec = glutGet(GLUT_ELAPSED_TIME);
139 float dt = (float)(msec - prev_time) / 1000.0;
142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144 head_xform = Mat4::identity;
145 head_xform.rotate_x(gph::deg_to_rad(head_rx));
146 head_xform.rotate_z(-gph::deg_to_rad(head_rz));
148 glMatrixMode(GL_MODELVIEW);
150 glTranslatef(0, 0, -cam_dist);
151 glRotatef(cam_phi, 1, 0, 0);
152 glRotatef(cam_theta, 0, 1, 0);
153 /* multiplying with the head rot matrix */
155 glMultMatrixf(head_xform[0]);
157 glPushAttrib(GL_LINE_BIT);
159 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
161 for(size_t i=0; i<meshes.size(); i++) {
165 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
171 hair.set_transform(head_xform);
176 glPushAttrib(GL_ENABLE_BIT);
177 glDisable(GL_DEPTH_TEST);
178 glDisable(GL_LIGHTING);
180 for (int i=0; i<500; i++) {
182 p.x = (float)rand() / RAND_MAX * 8 - 4;
183 p.y = (float)rand() / RAND_MAX * 4;
186 Vec3 tmp = inverse(head_xform) * p;
187 if(coll_sphere.contains(tmp)) {
190 else glColor3f(0, 1, 0);
192 glVertex3f(p.x, p.y, p.z);
202 glRotatef(90, 1, 0, 0);
204 glPushAttrib(GL_ENABLE_BIT);
205 glDisable(GL_LIGHTING);
206 glEnable(GL_TEXTURE_1D);
207 glBindTexture(GL_TEXTURE_1D, grad_tex);
209 glEnable(GL_TEXTURE_GEN_S);
210 glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
211 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
216 glutSolidSphere(350, 16, 8);
217 glDisable(GL_TEXTURE_1D);
219 glColor3f(0.2, 0.2, 0.2);
220 glutWireSphere(350, 32, 16);
229 assert(glGetError() == GL_NO_ERROR);
232 static void reshape(int x, int y)
234 glViewport(0, 0, x, y);
238 glMatrixMode(GL_PROJECTION);
240 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
243 static bool hpressed;
244 static void keydown(unsigned char key, int /*x*/, int /*y*/)
258 static void keyup(unsigned char key, int /*x*/, int /*y*/)
273 static void mouse(int bn, int st, int x, int y)
275 bnstate[bn] = st == GLUT_DOWN;
280 static void motion(int x, int y)
287 if(!dx && !dy) return;
294 if(head_rx < -45) head_rx = -45;
295 if(head_rx > 45) head_rx = 45;
297 if(head_rz < -90) head_rz = -90;
298 if(head_rz > 90) head_rz = 30;
303 cam_theta += dx * 0.5;
306 if(cam_phi < -90) cam_phi = -90;
307 if(cam_phi > 90) cam_phi = 90;
310 cam_dist += dy * 0.1;
311 if(cam_dist < 0) cam_dist = 0;
321 static unsigned int gen_grad_tex(int sz, const Vec3 &c0, const Vec3 &c1)
323 unsigned char *pixels = new unsigned char[sz * 3];
324 for(int i=0; i<sz; i++) {
325 float t = (float)i / (float)(sz - 1);
326 Vec3 color = c0 + (c1 - c0) * t;
327 pixels[i * 3] = color.x * 255;
328 pixels[i * 3 + 1] = color.y * 255;
329 pixels[i * 3 + 2] = color.z * 255;
333 glGenTextures(1, &tex);
334 glBindTexture(GL_TEXTURE_1D, tex);
336 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
337 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
338 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
340 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, sz, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);