glview.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 
50 int window;
51 
52 pthread_mutex_t gl_backbuf_mutex = PTHREAD_MUTEX_INITIALIZER;
53 
54 // back: owned by libfreenect (implicit for depth)
55 // mid: owned by callbacks, "latest frame ready"
56 // front: owned by GL, "currently being drawn"
59 
60 GLuint gl_depth_tex;
61 GLuint gl_rgb_tex;
62 GLfloat camera_angle = 0.0;
63 int camera_rotate = 0;
64 int tilt_changed = 0;
65 
70 
73 
74 pthread_cond_t gl_frame_cond = PTHREAD_COND_INITIALIZER;
75 int got_rgb = 0;
76 int got_depth = 0;
77 
79 {
80  pthread_mutex_lock(&gl_backbuf_mutex);
81 
82  // When using YUV_RGB mode, RGB frames only arrive at 15Hz, so we shouldn't force them to draw in lock-step.
83  // However, this is CPU/GPU intensive when we are receiving frames in lockstep.
85  while (!got_depth && !got_rgb) {
86  pthread_cond_wait(&gl_frame_cond, &gl_backbuf_mutex);
87  }
88  } else {
89  while ((!got_depth || !got_rgb) && requested_format != current_format) {
90  pthread_cond_wait(&gl_frame_cond, &gl_backbuf_mutex);
91  }
92  }
93 
95  pthread_mutex_unlock(&gl_backbuf_mutex);
96  return;
97  }
98 
99  uint8_t *tmp;
100 
101  if (got_depth) {
102  tmp = depth_front;
104  depth_mid = tmp;
105  got_depth = 0;
106  }
107  if (got_rgb) {
108  tmp = rgb_front;
109  rgb_front = rgb_mid;
110  rgb_mid = tmp;
111  got_rgb = 0;
112  }
113 
114  pthread_mutex_unlock(&gl_backbuf_mutex);
115  glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
116  glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, depth_front);
117 
118  if (camera_rotate) {
119  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
122  state = freenect_get_tilt_state(f_dev);
123  GLfloat x_accel_raw, x_accel,y_accel_raw,y_accel;
124  x_accel_raw = (GLfloat)state->accelerometer_x/819.0;
125  y_accel_raw = (GLfloat)state->accelerometer_y/819.0;
126 
127  // sloppy acceleration vector cleanup
128  GLfloat accel_length = sqrt(x_accel_raw * x_accel_raw + y_accel_raw * y_accel_raw);
129  x_accel = x_accel_raw/accel_length;
130  y_accel = y_accel_raw/accel_length;
131  camera_angle = atan2(y_accel,x_accel)*180/M_PI -90.0;
132  }
133  else {
134  camera_angle = 0;
135  }
136 
137  glLoadIdentity();
138  glPushMatrix();
139  glTranslatef((640.0/2.0),(480.0/2.0) ,0.0);
140  glRotatef(camera_angle, 0.0, 0.0, 1.0);
141  glTranslatef(-(640.0/2.0),-(480.0/2.0) ,0.0);
142  glBegin(GL_TRIANGLE_FAN);
143  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
144  glTexCoord2f(0, 1); glVertex3f(0,0,1.0);
145  glTexCoord2f(1, 1); glVertex3f(640,0,1.0);
146  glTexCoord2f(1, 0); glVertex3f(640,480,1.0);
147  glTexCoord2f(0, 0); glVertex3f(0,480,1.0);
148  glEnd();
149  glPopMatrix();
150 
151  glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
153  glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb_front);
154  else
155  glTexImage2D(GL_TEXTURE_2D, 0, 1, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, rgb_front+640*4);
156 
157  glPushMatrix();
158  glTranslatef(640+(640.0/2.0),(480.0/2.0) ,0.0);
159  glRotatef(camera_angle, 0.0, 0.0, 1.0);
160  glTranslatef(-(640+(640.0/2.0)),-(480.0/2.0) ,0.0);
161 
162  glBegin(GL_TRIANGLE_FAN);
163  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
164  glTexCoord2f(0, 1); glVertex3f(640,0,0);
165  glTexCoord2f(1, 1); glVertex3f(1280,0,0);
166  glTexCoord2f(1, 0); glVertex3f(1280,480,0);
167  glTexCoord2f(0, 0); glVertex3f(640,480,0);
168  glEnd();
169  glPopMatrix();
170  glutSwapBuffers();
171 }
172 
173 void keyPressed(unsigned char key, int x, int y)
174 {
175  if (key == 27) {
176  die = 1;
177  pthread_join(freenect_thread, NULL);
178  glutDestroyWindow(window);
179  free(depth_mid);
180  free(depth_front);
181  free(rgb_back);
182  free(rgb_mid);
183  free(rgb_front);
184  // Not pthread_exit because OSX leaves a thread lying around and doesn't exit
185  exit(0);
186  }
187  if (key == 'w') {
188  freenect_angle++;
189  if (freenect_angle > 30) {
190  freenect_angle = 30;
191  }
192  tilt_changed++;
193  }
194  if (key == 's') {
195  freenect_angle = 0;
196  tilt_changed++;
197  }
198  if (key == 'f') {
203  else
205  }
206  if (key == 'x') {
207  freenect_angle--;
208  if (freenect_angle < -30) {
209  freenect_angle = -30;
210  }
211  tilt_changed++;
212  }
213  if (key == 'e') {
214  static freenect_flag_value auto_exposure = FREENECT_ON;
215  freenect_set_flag(f_dev, FREENECT_AUTO_EXPOSURE, auto_exposure);
216  auto_exposure = auto_exposure ? FREENECT_OFF : FREENECT_ON;
217  }
218  if (key == 'b') {
219  static freenect_flag_value white_balance = FREENECT_ON;
220  freenect_set_flag(f_dev, FREENECT_AUTO_WHITE_BALANCE, white_balance);
221  white_balance = white_balance ? FREENECT_OFF : FREENECT_ON;
222  }
223  if (key == 'r') {
224  static freenect_flag_value raw_color = FREENECT_ON;
225  freenect_set_flag(f_dev, FREENECT_RAW_COLOR, raw_color);
226  raw_color = raw_color ? FREENECT_OFF : FREENECT_ON;
227  }
228  if (key == 'm') {
229  static freenect_flag_value mirror = FREENECT_ON;
232  mirror = mirror ? FREENECT_OFF : FREENECT_ON;
233  }
234  if (key == '1') {
236  }
237  if (key == '2') {
238  freenect_set_led(f_dev,LED_RED);
239  }
240  if (key == '3') {
242  }
243  if (key == '4') {
245  }
246  if (key == '5') {
247  // 5 is the same as 4
249  }
250  if (key == '6') {
252  }
253  if (key == '0') {
254  freenect_set_led(f_dev,LED_OFF);
255  }
256  if (key == 'o') {
257  if (camera_rotate) {
258  camera_rotate = 0;
259  glDisable(GL_DEPTH_TEST);
260  }
261  else {
262  camera_rotate = 1;
263  glEnable(GL_DEPTH_TEST);
264  }
265  }
266  if (tilt_changed) {
268  tilt_changed = 0;
269  }
270 }
271 
272 void ReSizeGLScene(int Width, int Height)
273 {
274  glViewport(0,0,Width,Height);
275  glMatrixMode(GL_PROJECTION);
276  glLoadIdentity();
277  glOrtho (0, 1280, 0, 480, -5.0f, 5.0f);
278  glMatrixMode(GL_MODELVIEW);
279  glLoadIdentity();
280 
281 }
282 
283 void InitGL(int Width, int Height)
284 {
285  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
286  //glClearDepth(0.0);
287  //glDepthFunc(GL_LESS);
288  //glDepthMask(GL_FALSE);
289  glDisable(GL_DEPTH_TEST);
290  glDisable(GL_BLEND);
291  glDisable(GL_ALPHA_TEST);
292  glEnable(GL_TEXTURE_2D);
293  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
294  glShadeModel(GL_FLAT);
295 
296  glGenTextures(1, &gl_depth_tex);
297  glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
298  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
299  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
300 
301  glGenTextures(1, &gl_rgb_tex);
302  glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
303  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
304  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
305 
306  ReSizeGLScene(Width, Height);
307 }
308 
309 void *gl_threadfunc(void *arg)
310 {
311  printf("GL thread\n");
312 
313  glutInit(&g_argc, g_argv);
314 
315  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
316  glutInitWindowSize(1280, 480);
317  glutInitWindowPosition(0, 0);
318 
319  window = glutCreateWindow("LibFreenect");
320 
321  glutDisplayFunc(&DrawGLScene);
322  glutIdleFunc(&DrawGLScene);
323  glutReshapeFunc(&ReSizeGLScene);
324  glutKeyboardFunc(&keyPressed);
325 
326  InitGL(1280, 480);
327 
328  glutMainLoop();
329 
330  return NULL;
331 }
332 
334 
335 void depth_cb(freenect_device *dev, void *v_depth, uint32_t timestamp)
336 {
337  int i;
338  uint16_t *depth = (uint16_t*)v_depth;
339 
340  pthread_mutex_lock(&gl_backbuf_mutex);
341  for (i=0; i<640*480; i++) {
342  int pval = t_gamma[depth[i]];
343  int lb = pval & 0xff;
344  switch (pval>>8) {
345  case 0:
346  depth_mid[3*i+0] = 255;
347  depth_mid[3*i+1] = 255-lb;
348  depth_mid[3*i+2] = 255-lb;
349  break;
350  case 1:
351  depth_mid[3*i+0] = 255;
352  depth_mid[3*i+1] = lb;
353  depth_mid[3*i+2] = 0;
354  break;
355  case 2:
356  depth_mid[3*i+0] = 255-lb;
357  depth_mid[3*i+1] = 255;
358  depth_mid[3*i+2] = 0;
359  break;
360  case 3:
361  depth_mid[3*i+0] = 0;
362  depth_mid[3*i+1] = 255;
363  depth_mid[3*i+2] = lb;
364  break;
365  case 4:
366  depth_mid[3*i+0] = 0;
367  depth_mid[3*i+1] = 255-lb;
368  depth_mid[3*i+2] = 255;
369  break;
370  case 5:
371  depth_mid[3*i+0] = 0;
372  depth_mid[3*i+1] = 0;
373  depth_mid[3*i+2] = 255-lb;
374  break;
375  default:
376  depth_mid[3*i+0] = 0;
377  depth_mid[3*i+1] = 0;
378  depth_mid[3*i+2] = 0;
379  break;
380  }
381  }
382  got_depth++;
383  pthread_cond_signal(&gl_frame_cond);
384  pthread_mutex_unlock(&gl_backbuf_mutex);
385 }
386 
387 void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
388 {
389  pthread_mutex_lock(&gl_backbuf_mutex);
390 
391  // swap buffers
392  assert (rgb_back == rgb);
393  rgb_back = rgb_mid;
395  rgb_mid = (uint8_t*)rgb;
396 
397  got_rgb++;
398  pthread_cond_signal(&gl_frame_cond);
399  pthread_mutex_unlock(&gl_backbuf_mutex);
400 }
401 
402 void *freenect_threadfunc(void *arg)
403 {
404  int accelCount = 0;
405 
407  freenect_set_led(f_dev,LED_RED);
413 
414  freenect_start_depth(f_dev);
415  freenect_start_video(f_dev);
416 
417  printf("'w' - tilt up, 's' - level, 'x' - tilt down, '0'-'6' - select LED mode \n");
418  printf("'f' - change video format, 'm' - mirror video, 'o' - rotate video with accelerometer \n");
419  printf("'e' - auto exposure, 'b' - white balance, 'r' - raw color \n");
420 
421  while (!die && freenect_process_events(f_ctx) >= 0) {
422  //Throttle the text output
423  if (accelCount++ >= 2000)
424  {
425  accelCount = 0;
428  state = freenect_get_tilt_state(f_dev);
429  double dx,dy,dz;
430  freenect_get_mks_accel(state, &dx, &dy, &dz);
431  printf("\r raw acceleration: %4d %4d %4d mks acceleration: %4f %4f %4f", state->accelerometer_x, state->accelerometer_y, state->accelerometer_z, dx, dy, dz);
432  fflush(stdout);
433  }
434 
436  freenect_stop_video(f_dev);
438  freenect_start_video(f_dev);
440  }
441  }
442 
443  printf("\nshutting down streams...\n");
444 
445  freenect_stop_depth(f_dev);
446  freenect_stop_video(f_dev);
447 
448  freenect_close_device(f_dev);
449  freenect_shutdown(f_ctx);
450 
451  printf("-- done!\n");
452  return NULL;
453 }
454 
455 int main(int argc, char **argv)
456 {
457  int res;
458 
459  depth_mid = (uint8_t*)malloc(640*480*3);
460  depth_front = (uint8_t*)malloc(640*480*3);
461  rgb_back = (uint8_t*)malloc(640*480*3);
462  rgb_mid = (uint8_t*)malloc(640*480*3);
463  rgb_front = (uint8_t*)malloc(640*480*3);
464 
465  printf("Kinect camera test\n");
466 
467  int i;
468  for (i=0; i<2048; i++) {
469  float v = i/2048.0;
470  v = powf(v, 3)* 6;
471  t_gamma[i] = v*6*256;
472  }
473 
474  g_argc = argc;
475  g_argv = argv;
476 
477  if (freenect_init(&f_ctx, NULL) < 0) {
478  printf("freenect_init() failed\n");
479  return 1;
480  }
481 
484 
485  int nr_devices = freenect_num_devices (f_ctx);
486  printf ("Number of devices found: %d\n", nr_devices);
487 
488  int user_device_number = 0;
489  if (argc > 1)
490  user_device_number = atoi(argv[1]);
491 
492  if (nr_devices < 1) {
493  freenect_shutdown(f_ctx);
494  return 1;
495  }
496 
497  if (freenect_open_device(f_ctx, &f_dev, user_device_number) < 0) {
498  printf("Could not open device\n");
499  freenect_shutdown(f_ctx);
500  return 1;
501  }
502 
503  res = pthread_create(&freenect_thread, NULL, freenect_threadfunc, NULL);
504  if (res) {
505  printf("pthread_create failed\n");
506  freenect_shutdown(f_ctx);
507  return 1;
508  }
509 
510  // OS X requires GLUT to run on the main thread
511  gl_threadfunc(NULL);
512 
513  return 0;
514 }
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
freenect_device * f_dev
Definition: glview.c:67
uint16_t t_gamma[2048]
Definition: glview.c:333
void freenect_get_mks_accel(freenect_raw_tilt_state *state, double *x, double *y, double *z)
Definition: fakenect.c:227
int main(int argc, char **argv)
Definition: glview.c:455
freenect_flag_value
Possible values for setting each freenect_flag
Definition: libfreenect.h:121
volatile int die
Definition: glview.c:45
int freenect_stop_video(freenect_device *dev)
Definition: fakenect.c:383
freenect_video_format
Definition: libfreenect.h:86
unsigned short uint16_t
int window
Definition: glview.c:50
freenect_video_format current_format
Definition: glview.c:72
int g_argc
Definition: glview.c:47
int freenect_num_devices(freenect_context *ctx)
Definition: fakenect.c:308
int got_rgb
Definition: glview.c:75
void depth_cb(freenect_device *dev, void *v_depth, uint32_t timestamp)
Definition: glview.c:335
void ReSizeGLScene(int Width, int Height)
Definition: glview.c:272
uint8_t * depth_mid
Definition: glview.c:57
int freenect_start_depth(freenect_device *dev)
Definition: fakenect.c:365
pthread_t freenect_thread
Definition: glview.c:44
GLuint gl_rgb_tex
Definition: glview.c:61
int freenect_set_led(freenect_device *dev, freenect_led_options option)
Definition: fakenect.c:414
int freenect_set_video_buffer(freenect_device *dev, void *buf)
Definition: fakenect.c:349
unsigned char uint8_t
freenect_context * f_ctx
Definition: glview.c:66
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
FREENECTAPI int freenect_set_flag(freenect_device *dev, freenect_flag flag, freenect_flag_value value)
Definition: flags.c:48
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:246
int freenect_set_tilt_degs(freenect_device *dev, double angle)
Definition: fakenect.c:410
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: fakenect.c:236
void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
Definition: glview.c:387
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
void * freenect_threadfunc(void *arg)
Definition: glview.c:402
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: fakenect.c:260
int camera_rotate
Definition: glview.c:63
pthread_mutex_t gl_backbuf_mutex
Definition: glview.c:52
GLuint gl_depth_tex
Definition: glview.c:60
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: fakenect.c:284
GLfloat camera_angle
Definition: glview.c:62
uint8_t * rgb_front
Definition: glview.c:58
pthread_cond_t gl_frame_cond
Definition: glview.c:74
freenect_raw_tilt_state * freenect_get_tilt_state(freenect_device *dev)
Definition: fakenect.c:217
int freenect_update_tilt_state(freenect_device *dev)
Definition: fakenect.c:418
char ** g_argv
Definition: glview.c:48
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
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
uint8_t * rgb_mid
Definition: glview.c:58
int freenect_led
Definition: glview.c:69
Data from the tilt motor and accelerometer.
Definition: libfreenect.h:167
uint8_t * rgb_back
Definition: glview.c:58
freenect_video_format requested_format
Definition: glview.c:71
unsigned int uint32_t
capture state
Definition: micview.c:53
freenect_device_flags
Definition: libfreenect.h:58
int freenect_stop_depth(freenect_device *dev)
Definition: fakenect.c:377
int got_depth
Definition: glview.c:76
void * gl_threadfunc(void *arg)
Definition: glview.c:309
int tilt_changed
Definition: glview.c:64
void keyPressed(unsigned char key, int x, int y)
Definition: glview.c:173
void DrawGLScene()
Definition: glview.c:78
int freenect_process_events(freenect_context *ctx)
Definition: fakenect.c:140
void InitGL(int Width, int Height)
Definition: glview.c:283
int freenect_angle
Definition: glview.c:68
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327
uint8_t * depth_front
Definition: glview.c:57


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Thu Jun 6 2019 19:25:38