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