hiview.c
Go to the documentation of this file.
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
5  * for details.
6  *
7  * This code is licensed to you under the terms of the Apache License, version
8  * 2.0, or, at your option, the terms of the GNU General Public License,
9  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10  * or the following URLs:
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * http://www.gnu.org/licenses/gpl-2.0.txt
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
16  * 1) Leave this header intact and distribute it under the same terms,
17  * accompanying it with the APACHE20 and GPL20 files, or
18  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20  * In all cases you must keep the copyright notice intact and include a copy
21  * of the CONTRIB file.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32 #include "libfreenect.h"
33 
34 #include <pthread.h>
35 
36 #if defined(__APPLE__)
37 #include <GLUT/glut.h>
38 #else
39 #include <GL/glut.h>
40 #endif
41 
42 #include <math.h>
43 
44 pthread_t freenect_thread;
45 volatile int die = 0;
46 
47 int g_argc;
48 char **g_argv;
49 
52 
53 pthread_mutex_t depth_mutex = PTHREAD_MUTEX_INITIALIZER;
54 pthread_mutex_t video_mutex = PTHREAD_MUTEX_INITIALIZER;
55 
56 // back: owned by libfreenect (implicit for depth)
57 // mid: owned by callbacks, "latest frame ready"
58 // front: owned by GL, "currently being drawn"
61 
62 GLuint gl_depth_tex;
63 GLuint gl_rgb_tex;
64 
68 
73 
74 pthread_cond_t gl_frame_cond = PTHREAD_COND_INITIALIZER;
75 int got_rgb = 0;
76 int got_depth = 0;
77 int depth_on = 1;
78 
79 void DispatchDraws() {
80  pthread_mutex_lock(&depth_mutex);
81  if (got_depth) {
82  glutSetWindow(depth_window);
83  glutPostRedisplay();
84  }
85  pthread_mutex_unlock(&depth_mutex);
86  pthread_mutex_lock(&video_mutex);
87  if (got_rgb) {
88  glutSetWindow(video_window);
89  glutPostRedisplay();
90  }
91  pthread_mutex_unlock(&video_mutex);
92 }
93 
95 {
96  pthread_mutex_lock(&depth_mutex);
97  if (got_depth) {
98  uint8_t* tmp = depth_front;
100  depth_mid = tmp;
101  got_depth = 0;
102  }
103  pthread_mutex_unlock(&depth_mutex);
104 
105  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
106  glLoadIdentity();
107 
108  glEnable(GL_TEXTURE_2D);
109 
110  glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
111  glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, depth_front);
112 
113  glBegin(GL_TRIANGLE_FAN);
114  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
115  glTexCoord2f(0, 0); glVertex3f(0,0,0);
116  glTexCoord2f(1, 0); glVertex3f(640,0,0);
117  glTexCoord2f(1, 1); glVertex3f(640,480,0);
118  glTexCoord2f(0, 1); glVertex3f(0,480,0);
119  glEnd();
120 
121  glutSwapBuffers();
122 }
123 
125 {
127  return;
128  }
129 
130  pthread_mutex_lock(&video_mutex);
131 
133 
134  if (got_rgb) {
135  uint8_t *tmp = rgb_front;
136  rgb_front = rgb_mid;
137  rgb_mid = tmp;
138  got_rgb = 0;
139  }
140 
141  pthread_mutex_unlock(&video_mutex);
142 
143  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144  glLoadIdentity();
145 
146  glEnable(GL_TEXTURE_2D);
147 
148  glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
150  glTexImage2D(GL_TEXTURE_2D, 0, 3, frame_mode.width, frame_mode.height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb_front);
151  } else {
152  glTexImage2D(GL_TEXTURE_2D, 0, 1, frame_mode.width, frame_mode.height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, rgb_front);
153  }
154  glBegin(GL_TRIANGLE_FAN);
155  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
156  glTexCoord2f(0, 0); glVertex3f(0,0,0);
157  glTexCoord2f(1, 0); glVertex3f(frame_mode.width,0,0);
158  glTexCoord2f(1, 1); glVertex3f(frame_mode.width,frame_mode.height,0);
159  glTexCoord2f(0, 1); glVertex3f(0,frame_mode.height,0);
160  glEnd();
161 
162  glutSwapBuffers();
163 }
164 
165 void keyPressed(unsigned char key, int x, int y)
166 {
167  if (key == 27) {
168  die = 1;
169  pthread_join(freenect_thread, NULL);
170  glutDestroyWindow(depth_window);
171  glutDestroyWindow(video_window);
172  free(depth_mid);
173  free(depth_front);
174  free(rgb_back);
175  free(rgb_mid);
176  free(rgb_front);
177  // Not pthread_exit because OSX leaves a thread lying around and doesn't exit
178  exit(0);
179  }
180  if (key == 'f') {
181  // Cycle through:
182  // 1) 1280x1024 RGB
183  // 2) 1280x1024 IR
184  // 3) 640x480 RGB
185  // 4) 640x480 YUV
186  // 5) 640x480 IR
190  // Since we can't stream the high-res IR while running the depth stream,
191  // we force the depth stream off when we reach this res in the cycle.
192  freenect_stop_depth(f_dev);
193  memset(depth_mid, 0, 640*480*3); // black out the depth camera
194  got_depth++;
195  depth_on = 0;
196  } else if (current_format == FREENECT_VIDEO_IR_8BIT) {
199  }
203  } else if (current_format == FREENECT_VIDEO_YUV_RGB) {
205  } else if (current_format == FREENECT_VIDEO_IR_8BIT) {
208  }
209  }
210  glutSetWindow(video_window);
212  glutReshapeWindow(s.width, s.height);
213  }
214  if (key == 'd') { // Toggle depth camera.
215  if(depth_on) {
216  freenect_stop_depth(f_dev);
217  memset(depth_mid, 0, 640*480*3); // black out the depth camera
218  got_depth++;
219  depth_on = 0;
220  } else {
221  freenect_start_depth(f_dev);
222  depth_on = 1;
223  }
224  }
225 }
226 
227 void ReSizeGLScene(int Width, int Height)
228 {
229  glViewport(0,0,Width,Height);
230  glMatrixMode(GL_PROJECTION);
231  glLoadIdentity();
232  glOrtho (0, Width, Height, 0, -1.0f, 1.0f);
233  glMatrixMode(GL_MODELVIEW);
234 }
235 
236 void InitGL(int Width, int Height)
237 {
238  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
239  glClearDepth(1.0);
240  glDepthFunc(GL_LESS);
241  glDisable(GL_DEPTH_TEST);
242  glEnable(GL_BLEND);
243  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
244  glShadeModel(GL_SMOOTH);
245  glGenTextures(1, &gl_depth_tex);
246  glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
247  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
248  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
249  glGenTextures(1, &gl_rgb_tex);
250  glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
251  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
252  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
253  ReSizeGLScene(Width, Height);
254 }
255 
256 void *gl_threadfunc(void *arg)
257 {
258  printf("GL thread\n");
259 
260  glutInit(&g_argc, g_argv);
261 
262  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
263  glutInitWindowSize(640, 480);
264  glutInitWindowPosition(0, 0);
265 
266  depth_window = glutCreateWindow("Depth");
267  glutDisplayFunc(&DrawDepthScene);
268  glutIdleFunc(&DispatchDraws);
269  glutKeyboardFunc(&keyPressed);
270  InitGL(640, 480);
271 
273  glutInitWindowPosition(640,0);
274  glutInitWindowSize(mode.width, mode.height);
275  video_window = glutCreateWindow("Video");
276 
277  glutDisplayFunc(&DrawVideoScene);
278  glutIdleFunc(&DispatchDraws);
279  glutReshapeFunc(&ReSizeGLScene);
280  glutKeyboardFunc(&keyPressed);
281 
282  InitGL(640, 480);
283  ReSizeGLScene(mode.width, mode.height);
284 
285  glutMainLoop();
286 
287  return NULL;
288 }
289 
291 
292 void depth_cb(freenect_device *dev, void *v_depth, uint32_t timestamp)
293 {
294  int i;
295  uint16_t *depth = (uint16_t*)v_depth;
296 
297  pthread_mutex_lock(&depth_mutex);
298  for (i=0; i<640*480; i++) {
299  int pval = t_gamma[depth[i]];
300  int lb = pval & 0xff;
301  switch (pval>>8) {
302  case 0:
303  depth_mid[3*i+0] = 255;
304  depth_mid[3*i+1] = 255-lb;
305  depth_mid[3*i+2] = 255-lb;
306  break;
307  case 1:
308  depth_mid[3*i+0] = 255;
309  depth_mid[3*i+1] = lb;
310  depth_mid[3*i+2] = 0;
311  break;
312  case 2:
313  depth_mid[3*i+0] = 255-lb;
314  depth_mid[3*i+1] = 255;
315  depth_mid[3*i+2] = 0;
316  break;
317  case 3:
318  depth_mid[3*i+0] = 0;
319  depth_mid[3*i+1] = 255;
320  depth_mid[3*i+2] = lb;
321  break;
322  case 4:
323  depth_mid[3*i+0] = 0;
324  depth_mid[3*i+1] = 255-lb;
325  depth_mid[3*i+2] = 255;
326  break;
327  case 5:
328  depth_mid[3*i+0] = 0;
329  depth_mid[3*i+1] = 0;
330  depth_mid[3*i+2] = 255-lb;
331  break;
332  default:
333  depth_mid[3*i+0] = 0;
334  depth_mid[3*i+1] = 0;
335  depth_mid[3*i+2] = 0;
336  break;
337  }
338  }
339  got_depth++;
340  pthread_mutex_unlock(&depth_mutex);
341 }
342 
343 void video_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
344 {
345  pthread_mutex_lock(&video_mutex);
346 
347  // swap buffers
348  assert (rgb_back == rgb);
349  rgb_back = rgb_mid;
351  rgb_mid = (uint8_t*)rgb;
352 
353  got_rgb++;
354  pthread_mutex_unlock(&video_mutex);
355 }
356 
357 void *freenect_threadfunc(void *arg)
358 {
359  freenect_set_led(f_dev,LED_RED);
368 
369  freenect_start_depth(f_dev);
370  freenect_start_video(f_dev);
371 
372  int status = 0;
373  while (!die && status >= 0) {
374  status = freenect_process_events(f_ctx);
376  freenect_stop_video(f_dev);
378  pthread_mutex_lock(&video_mutex);
379  free(rgb_back);
380  free(rgb_mid);
381  free(rgb_front);
387  pthread_mutex_unlock(&video_mutex);
389  freenect_start_video(f_dev);
390  }
391  }
392 
393  if (status < 0) {
394  printf("Something went terribly wrong. Aborting.\n");
395  return NULL;
396  }
397 
398  printf("\nshutting down streams...\n");
399 
400  freenect_stop_depth(f_dev);
401  freenect_stop_video(f_dev);
402 
403  freenect_close_device(f_dev);
404  freenect_shutdown(f_ctx);
405 
406  printf("-- done!\n");
407  return NULL;
408 }
409 
410 int main(int argc, char **argv)
411 {
412  int res;
413 
414  depth_mid = (uint8_t*)malloc(640*480*3);
415  depth_front = (uint8_t*)malloc(640*480*3);
416 
417  printf("Kinect camera test\n");
418 
419  int i;
420  for (i=0; i<2048; i++) {
421  float v = i/2048.0;
422  v = powf(v, 3)* 6;
423  t_gamma[i] = v*6*256;
424  }
425 
426  g_argc = argc;
427  g_argv = argv;
428 
429  if (freenect_init(&f_ctx, NULL) < 0) {
430  printf("freenect_init() failed\n");
431  return 1;
432  }
433 
436 
437  int nr_devices = freenect_num_devices (f_ctx);
438  printf ("Number of devices found: %d\n", nr_devices);
439 
440  int user_device_number = 0;
441  if (argc > 1)
442  user_device_number = atoi(argv[1]);
443 
444  if (nr_devices < 1) {
445  freenect_shutdown(f_ctx);
446  return 1;
447  }
448 
449  if (freenect_open_device(f_ctx, &f_dev, user_device_number) < 0) {
450  printf("Could not open device\n");
451  freenect_shutdown(f_ctx);
452  return 1;
453  }
454 
455  res = pthread_create(&freenect_thread, NULL, freenect_threadfunc, NULL);
456  if (res) {
457  printf("pthread_create failed\n");
458  freenect_shutdown(f_ctx);
459  return 1;
460  }
461 
462  // OS X requires GLUT to run on the main thread
463  gl_threadfunc(NULL);
464 
465  return 0;
466 }
uint16_t t_gamma[2048]
Definition: hiview.c:290
void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb)
Definition: fakenect.c:241
void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs)
Definition: fakenect.c:338
void DrawDepthScene()
Definition: hiview.c:94
int freenect_stop_video(freenect_device *dev)
Definition: fakenect.c:383
freenect_video_format
Definition: libfreenect.h:86
unsigned short uint16_t
freenect_context * f_ctx
Definition: hiview.c:65
int g_argc
Definition: hiview.c:47
pthread_mutex_t video_mutex
Definition: hiview.c:54
int freenect_num_devices(freenect_context *ctx)
Definition: fakenect.c:308
void InitGL(int Width, int Height)
Definition: hiview.c:236
void * gl_threadfunc(void *arg)
Definition: hiview.c:256
void keyPressed(unsigned char key, int x, int y)
Definition: hiview.c:165
int freenect_start_depth(freenect_device *dev)
Definition: fakenect.c:365
int freenect_set_led(freenect_device *dev, freenect_led_options option)
Definition: fakenect.c:414
int depth_window
Definition: hiview.c:50
int freenect_set_video_buffer(freenect_device *dev, void *buf)
Definition: fakenect.c:349
unsigned char uint8_t
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
pthread_mutex_t depth_mutex
Definition: hiview.c:53
freenect_resolution current_resolution
Definition: hiview.c:72
void DrawVideoScene()
Definition: hiview.c:124
volatile int die
Definition: hiview.c:45
void depth_cb(freenect_device *dev, void *v_depth, uint32_t timestamp)
Definition: hiview.c:292
void ReSizeGLScene(int Width, int Height)
Definition: hiview.c:227
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:246
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: fakenect.c:236
uint8_t * rgb_back
Definition: hiview.c:60
char ** g_argv
Definition: hiview.c:48
void freenect_set_log_level(freenect_context *ctx, freenect_loglevel level)
Definition: fakenect.c:401
int freenect_start_video(freenect_device *dev)
Definition: fakenect.c:371
uint8_t * rgb_mid
Definition: hiview.c:60
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: fakenect.c:260
int freenect_led
Definition: hiview.c:67
freenect_video_format current_format
Definition: hiview.c:70
uint8_t * depth_mid
Definition: hiview.c:59
int got_depth
Definition: hiview.c:76
int video_window
Definition: hiview.c:51
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: fakenect.c:284
uint8_t * rgb_front
Definition: hiview.c:60
int got_rgb
Definition: hiview.c:75
pthread_cond_t gl_frame_cond
Definition: hiview.c:74
pthread_t freenect_thread
Definition: hiview.c:44
GLuint gl_depth_tex
Definition: hiview.c:62
int freenect_close_device(freenect_device *dev)
Definition: fakenect.c:406
int freenect_set_depth_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:253
freenect_frame_mode freenect_get_current_video_mode(freenect_device *dev)
Definition: fakenect.c:279
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
void * freenect_threadfunc(void *arg)
Definition: hiview.c:357
int depth_on
Definition: hiview.c:77
freenect_resolution
Definition: libfreenect.h:77
void DispatchDraws()
Definition: hiview.c:79
unsigned int uint32_t
int main(int argc, char **argv)
Definition: hiview.c:410
freenect_device_flags
Definition: libfreenect.h:58
int freenect_stop_depth(freenect_device *dev)
Definition: fakenect.c:377
void video_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
Definition: hiview.c:343
freenect_resolution requested_resolution
Definition: hiview.c:71
freenect_device * f_dev
Definition: hiview.c:66
freenect_video_format requested_format
Definition: hiview.c:69
GLuint gl_rgb_tex
Definition: hiview.c:63
int freenect_process_events(freenect_context *ctx)
Definition: fakenect.c:140
uint8_t * depth_front
Definition: hiview.c:59
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Mon Jun 10 2019 13:46:42