rev |
line source |
eleni@2
|
1 #include <GL/glew.h>
|
eleni@2
|
2 #include <GL/glut.h>
|
eleni@12
|
3
|
eleni@23
|
4 #include <math.h>
|
eleni@0
|
5 #include <stdio.h>
|
eleni@0
|
6
|
eleni@0
|
7 #include "kinect.h"
|
eleni@2
|
8 #include "frame.h"
|
eleni@21
|
9 #include "sdr.h"
|
eleni@12
|
10 #include "tesquad.h"
|
eleni@14
|
11 #include "texture.h"
|
eleni@0
|
12
|
eleni@23
|
13 #define FOV 45.0
|
eleni@23
|
14 #define QUAD_DIST 20.0 /*depth*/
|
eleni@17
|
15
|
eleni@0
|
16 freenect_context *kin_ctx;
|
eleni@0
|
17 freenect_device *kin_dev;
|
eleni@0
|
18 KinectParams kin_params;
|
eleni@2
|
19 Frame *frame;
|
eleni@0
|
20
|
eleni@26
|
21 static const char *filename = "data/textures/wp2.jpg";
|
eleni@23
|
22 static const char *vsdr_path = "data/shaders/invisible.v.glsl";
|
eleni@23
|
23 static const char *fsdr_path = "data/shaders/invisible.f.glsl";
|
eleni@25
|
24 static unsigned char tex;
|
eleni@23
|
25 static unsigned int sprog;
|
eleni@17
|
26 static unsigned int drawing;
|
eleni@17
|
27 static unsigned int debugging;
|
eleni@23
|
28 static int tex_height;
|
eleni@23
|
29 static int tex_width;
|
eleni@23
|
30 static float aspect;
|
eleni@13
|
31 static bool show;
|
eleni@25
|
32 static bool wireframe;
|
eleni@26
|
33 static bool fullscreen;
|
eleni@26
|
34
|
eleni@26
|
35 static float phi = 0;
|
eleni@26
|
36 static float theta = 0;
|
eleni@26
|
37 static float distance = 10;
|
eleni@26
|
38 static int prev_x = -1, prev_y = -1;
|
eleni@26
|
39 static int bn;
|
eleni@13
|
40
|
eleni@2
|
41 static void cleanup();
|
eleni@23
|
42 static bool init();
|
eleni@23
|
43 static void init_tessquad();
|
eleni@2
|
44
|
eleni@2
|
45 static void display();
|
eleni@2
|
46 static void reshape(int w, int h);
|
eleni@2
|
47 static void keyb(unsigned char key, int x, int y);
|
eleni@26
|
48 static void mouse(int button, int status, int x, int y);
|
eleni@26
|
49 static void motion(int x, int y);
|
eleni@2
|
50 static void idle();
|
eleni@2
|
51
|
eleni@2
|
52 bool has_video;
|
eleni@2
|
53 bool has_depth;
|
eleni@2
|
54
|
eleni@2
|
55 int main(int argc, char **argv)
|
eleni@0
|
56 {
|
eleni@0
|
57 if(!init_kinect(&kin_ctx, &kin_dev, &kin_params))
|
eleni@0
|
58 return 1;
|
eleni@0
|
59
|
eleni@7
|
60 if(!init_kinect_frames(kin_ctx, kin_dev, &kin_params)) {
|
eleni@2
|
61 stop_kinect(kin_ctx, kin_dev);
|
eleni@2
|
62 return 1;
|
eleni@2
|
63 }
|
eleni@2
|
64
|
eleni@2
|
65 glutInitWindowSize(800, 600);
|
eleni@2
|
66 glutInit(&argc, argv);
|
eleni@2
|
67 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
|
eleni@2
|
68 glutCreateWindow("Test Kinect");
|
eleni@2
|
69
|
eleni@2
|
70 glewInit();
|
eleni@2
|
71
|
eleni@2
|
72 glutDisplayFunc(display);
|
eleni@2
|
73 glutReshapeFunc(reshape);
|
eleni@2
|
74 glutKeyboardFunc(keyb);
|
eleni@26
|
75 glutMouseFunc(mouse);
|
eleni@26
|
76 glutMotionFunc(motion);
|
eleni@2
|
77 glutIdleFunc(idle);
|
eleni@2
|
78
|
eleni@14
|
79 atexit(cleanup);
|
eleni@23
|
80 if(!init()) {
|
eleni@23
|
81 return 1;
|
eleni@23
|
82 }
|
eleni@2
|
83
|
eleni@2
|
84 glutMainLoop();
|
eleni@2
|
85 }
|
eleni@2
|
86
|
eleni@26
|
87 static bool init()
|
eleni@26
|
88 {
|
eleni@26
|
89 glClearColor(1, 0, 0, 1);
|
eleni@26
|
90
|
eleni@26
|
91 frame = new Frame;
|
eleni@26
|
92 if(!(tex = load_texture(filename, &tex_width, &tex_height))) {
|
eleni@26
|
93 fprintf(stderr, "Failed to load texture: %s\n", filename);
|
eleni@26
|
94 return false;
|
eleni@26
|
95 }
|
eleni@26
|
96
|
eleni@26
|
97 /* shaders setup */
|
eleni@26
|
98 if(!(sprog = sdr_getprog(vsdr_path, fsdr_path))) {
|
eleni@26
|
99 fprintf(stderr, "Failed to create shader program!\n");
|
eleni@26
|
100 return false;
|
eleni@26
|
101 }
|
eleni@26
|
102
|
eleni@26
|
103 glUseProgram(sprog);
|
eleni@26
|
104 int dloc = glGetUniformLocation(sprog, "depth_tex");
|
eleni@26
|
105 if(dloc != -1)
|
eleni@26
|
106 glUniform1i(dloc, 1);
|
eleni@26
|
107 int tloc = glGetUniformLocation(sprog, "tex");
|
eleni@26
|
108 if(tloc != -1)
|
eleni@26
|
109 glUniform1i(tloc, 0);
|
eleni@26
|
110 glUseProgram(0);
|
eleni@26
|
111
|
eleni@26
|
112 /* debugging */
|
eleni@26
|
113 debugging = glGenLists(1);
|
eleni@26
|
114 glNewList(debugging, GL_COMPILE);
|
eleni@26
|
115 glEnable(GL_TEXTURE_2D);
|
eleni@26
|
116 glBindTexture(GL_TEXTURE_2D, frame->video_tex);
|
eleni@26
|
117 draw_tess_quad(-1, -1, 1, 2, 1, 1, true);
|
eleni@26
|
118 glBindTexture(GL_TEXTURE_2D, frame->depth_tex);
|
eleni@26
|
119 draw_tess_quad(0, -1, 1, 2, 1, 1, true);
|
eleni@26
|
120 glDisable(GL_TEXTURE_2D);
|
eleni@26
|
121 glEndList();
|
eleni@26
|
122
|
eleni@26
|
123 return true;
|
eleni@26
|
124 }
|
eleni@26
|
125
|
eleni@26
|
126 static void init_tessquad()
|
eleni@26
|
127 {
|
eleni@26
|
128 if(drawing)
|
eleni@26
|
129 glDeleteLists(drawing, 1);
|
eleni@26
|
130
|
eleni@26
|
131 drawing = glGenLists(1);
|
eleni@26
|
132 glNewList(drawing, GL_COMPILE);
|
eleni@26
|
133 float fov_rads = FOV / 180.0 * M_PI;
|
eleni@26
|
134 float ysz = QUAD_DIST * tan(fov_rads / 2.0);
|
eleni@26
|
135 float xsz = ysz * aspect;
|
eleni@26
|
136 draw_tess_quad(-xsz, -ysz, xsz * 2, ysz * 2, tex_width/8 - 1, tex_height/8 - 1);
|
eleni@26
|
137 glEndList();
|
eleni@26
|
138 }
|
eleni@26
|
139
|
eleni@2
|
140 static void display()
|
eleni@2
|
141 {
|
eleni@14
|
142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
eleni@2
|
143
|
eleni@2
|
144 has_depth = false; has_video = false;
|
eleni@2
|
145 if(freenect_process_events(kin_ctx) != 0) {
|
eleni@2
|
146 fprintf(stderr, "Failed to process events.\n");
|
eleni@2
|
147 exit(0);
|
eleni@2
|
148 }
|
eleni@2
|
149 frame->process();
|
eleni@2
|
150
|
eleni@26
|
151 glMatrixMode(GL_MODELVIEW);
|
eleni@26
|
152 glLoadIdentity();
|
eleni@26
|
153
|
eleni@26
|
154 // camera
|
eleni@26
|
155 glRotatef(phi, 1, 0, 0);
|
eleni@26
|
156 glRotatef(theta, 0, 1, 0);
|
eleni@26
|
157 glTranslatef(0, 0, -distance);
|
eleni@26
|
158
|
eleni@23
|
159 glUseProgram(sprog);
|
eleni@23
|
160
|
eleni@23
|
161 // draw video frame
|
eleni@25
|
162
|
eleni@25
|
163 if(wireframe)
|
eleni@25
|
164 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
eleni@25
|
165
|
eleni@23
|
166 glMatrixMode(GL_MODELVIEW);
|
eleni@23
|
167 glPushMatrix();
|
eleni@23
|
168 glTranslatef(0, 0, -QUAD_DIST);
|
eleni@23
|
169
|
eleni@23
|
170 glActiveTexture(GL_TEXTURE0);
|
eleni@23
|
171 glEnable(GL_TEXTURE_2D);
|
eleni@23
|
172 glBindTexture(GL_TEXTURE_2D, tex);
|
eleni@23
|
173 glActiveTexture(GL_TEXTURE1);
|
eleni@23
|
174 glEnable(GL_TEXTURE_2D);
|
eleni@23
|
175 glBindTexture(GL_TEXTURE_2D, frame->depth_tex);
|
eleni@23
|
176
|
eleni@17
|
177 glCallList(drawing);
|
eleni@23
|
178
|
eleni@23
|
179 glActiveTexture(GL_TEXTURE1);
|
eleni@23
|
180 glDisable(GL_TEXTURE_2D);
|
eleni@23
|
181 glActiveTexture(GL_TEXTURE0);
|
eleni@23
|
182 glDisable(GL_TEXTURE_2D);
|
eleni@23
|
183
|
eleni@23
|
184 glMatrixMode(GL_MODELVIEW);
|
eleni@23
|
185 glPopMatrix();
|
eleni@23
|
186
|
eleni@23
|
187 glUseProgram(0);
|
eleni@23
|
188
|
eleni@25
|
189 if(wireframe)
|
eleni@25
|
190 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
eleni@25
|
191
|
eleni@17
|
192 if(show)
|
eleni@17
|
193 glCallList(debugging);
|
eleni@17
|
194 glFlush();
|
eleni@12
|
195
|
eleni@2
|
196 glutSwapBuffers();
|
eleni@2
|
197 }
|
eleni@2
|
198
|
eleni@2
|
199 static void reshape(int w, int h)
|
eleni@2
|
200 {
|
eleni@23
|
201 aspect = (float)w / (float)h;
|
eleni@2
|
202 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
|
eleni@2
|
203 glMatrixMode(GL_PROJECTION);
|
eleni@2
|
204 glLoadIdentity();
|
eleni@23
|
205 gluPerspective(FOV, aspect, 1, 1000);
|
eleni@23
|
206 init_tessquad();
|
eleni@2
|
207 }
|
eleni@2
|
208
|
eleni@2
|
209 static void keyb(unsigned char key, int x, int y)
|
eleni@2
|
210 {
|
eleni@2
|
211 switch(key) {
|
eleni@13
|
212 case 's':
|
eleni@25
|
213 show = show ? false : true;
|
eleni@25
|
214 break;
|
eleni@25
|
215 case 'w':
|
eleni@25
|
216 wireframe = wireframe ? false : true;
|
eleni@13
|
217 break;
|
eleni@26
|
218 case 'r':
|
eleni@26
|
219 theta = 0;
|
eleni@26
|
220 phi = 0;
|
eleni@26
|
221 distance = 0;
|
eleni@26
|
222 break;
|
eleni@26
|
223 case 'f':
|
eleni@26
|
224 glutFullScreen();
|
eleni@26
|
225 break;
|
eleni@2
|
226 case 27:
|
eleni@2
|
227 exit(0);
|
eleni@2
|
228 default:
|
eleni@2
|
229 break;
|
eleni@2
|
230 }
|
eleni@2
|
231 }
|
eleni@2
|
232
|
eleni@26
|
233 static void mouse(int button, int state, int x, int y)
|
eleni@26
|
234 {
|
eleni@26
|
235 bn = button;
|
eleni@26
|
236 prev_x = x;
|
eleni@26
|
237 prev_y = y;
|
eleni@26
|
238 }
|
eleni@26
|
239
|
eleni@26
|
240 static void motion(int x, int y)
|
eleni@26
|
241 {
|
eleni@26
|
242 switch(bn) {
|
eleni@26
|
243 case GLUT_LEFT_BUTTON:
|
eleni@26
|
244 theta += x - prev_x;
|
eleni@26
|
245 phi += y - prev_y;
|
eleni@26
|
246
|
eleni@26
|
247 theta = theta < 0 ? 360 + theta : theta;
|
eleni@26
|
248 theta = theta > 360 ? theta - 360 : theta;
|
eleni@26
|
249
|
eleni@26
|
250 phi = phi < -90 ? 90 + phi : phi;
|
eleni@26
|
251 phi = phi > 90 ? phi - 90 : phi;
|
eleni@26
|
252 break;
|
eleni@26
|
253
|
eleni@26
|
254 case GLUT_RIGHT_BUTTON:
|
eleni@26
|
255 distance *= (y - prev_y) * 0.01 + 1;
|
eleni@26
|
256 if(distance < 0.0) {
|
eleni@26
|
257 distance = 0.0;
|
eleni@26
|
258 }
|
eleni@26
|
259 break;
|
eleni@26
|
260
|
eleni@26
|
261 default:
|
eleni@26
|
262 break;
|
eleni@26
|
263 }
|
eleni@26
|
264
|
eleni@26
|
265 prev_x = x;
|
eleni@26
|
266 prev_y = y;
|
eleni@26
|
267 }
|
eleni@26
|
268
|
eleni@2
|
269 static void idle()
|
eleni@2
|
270 {
|
eleni@2
|
271 glutPostRedisplay();
|
eleni@2
|
272 }
|
eleni@2
|
273
|
eleni@2
|
274 static void cleanup()
|
eleni@2
|
275 {
|
eleni@23
|
276 glDeleteLists(drawing, 1);
|
eleni@23
|
277 glDeleteLists(debugging, 1);
|
eleni@23
|
278
|
eleni@2
|
279 stop_kinect_frames(kin_dev);
|
eleni@0
|
280 stop_kinect(kin_ctx, kin_dev);
|
eleni@0
|
281 }
|