Skip to content

Commit 3a24bb8

Browse files
author
Kai Ritterbusch
committed
Fixed libfreenect.hpp: made FreenectDeviceState copyable
Added cppview.cpp to examples, as an example for the C++ header Signed-off-by: Kai Ritterbusch <kai.ritterbusch@gmx.de> Signed-off-by: Vincent Le Ligeour <yoda-jm@users.sourceforge.net>
1 parent 2402fcd commit 3a24bb8

File tree

3 files changed

+336
-1
lines changed

3 files changed

+336
-1
lines changed

examples/CMakeLists.txt

100644100755
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,25 @@
33
######################################################################################
44

55
add_executable(glview glview.c)
6+
add_executable(cppview cppview.cpp)
67

78
# Mac just has everything already
89
if(APPLE)
910
set(CMAKE_EXE_LINKER_FLAGS "-framework OpenGL -framework GLUT")
1011
target_link_libraries(glview freenect)
12+
target_link_libraries(cppview freenect)
1113
# Linux, not so much
1214
else()
1315
find_package(Threads REQUIRED)
1416
find_package(OpenGL REQUIRED)
1517
find_package(GLUT REQUIRED)
1618
include_directories(${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${USB_INCLUDE_DIRS})
1719
target_link_libraries(glview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} m)
20+
target_link_libraries(cppview freenect ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} m)
1821
endif()
1922

2023
install (TARGETS glview
2124
DESTINATION bin)
25+
26+
install (TARGETS cppview
27+
DESTINATION bin)

examples/cppview.cpp

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
/*This file is part of the OpenKinect Project. http://www.openkinect.org
2+
3+
Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB
4+
file for details.
5+
6+
This code is licensed to you under the terms of the Apache License,
7+
version 2.0, or, at your option, the terms of the GNU General Public
8+
License, version 2.0. See the APACHE20 and GPL2 files for the text of
9+
the licenses, or the following URLs:
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
http://www.gnu.org/licenses/gpl-2.0.txt
12+
13+
If you redistribute this file in source form, modified or unmodified,
14+
you may:
15+
16+
- Leave this header intact and distribute it under the same terms,
17+
accompanying it with the APACHE20 and GPL2 files, or
18+
- Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19+
- Delete the GPL v2 clause and accompany it with the APACHE20 file
20+
21+
In all cases you must keep the copyright notice intact and include a
22+
copy of the CONTRIB file.
23+
24+
Binary distributions must follow the binary distribution requirements
25+
of either License.*/
26+
27+
28+
#include "libfreenect.hpp"
29+
#include <pthread.h>
30+
#include <stdio.h>
31+
#include <iostream>
32+
#include <string.h>
33+
#include <cmath>
34+
#include <vector>
35+
36+
#if defined(__APPLE__)
37+
#include <GLUT/glut.h>
38+
#include <OpenGL/gl.h>
39+
#include <OpenGL/glu.h>
40+
#else
41+
#include <GL/glut.h>
42+
#include <GL/gl.h>
43+
#include <GL/glu.h>
44+
#endif
45+
46+
47+
class Mutex {
48+
public:
49+
Mutex() {
50+
m_mutex=PTHREAD_MUTEX_INITIALIZER;
51+
}
52+
void lock() {
53+
pthread_mutex_lock( &m_mutex );
54+
}
55+
void unlock() {
56+
pthread_mutex_unlock( &m_mutex );
57+
}
58+
private:
59+
pthread_mutex_t m_mutex;
60+
};
61+
62+
/* thanks to Yoda---- from IRC */
63+
class MyFreenectDevice : public Freenect::FreenectDevice {
64+
public:
65+
MyFreenectDevice(freenect_context *_ctx, int _index)
66+
: Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_VIDEO_RGB_SIZE),m_buffer_video(FREENECT_VIDEO_RGB_SIZE), m_gamma(2048), m_new_rgb_frame(false), m_new_depth_frame(false)
67+
{
68+
for( unsigned int i = 0 ; i < 2048 ; i++) {
69+
float v = i/2048.0;
70+
v = std::pow(v, 3)* 6;
71+
m_gamma[i] = v*6*256;
72+
}
73+
}
74+
// Do not call directly even in child
75+
void VideoCallback(void* _rgb, uint32_t timestamp) {
76+
std::cout << "RGB callback" << std::endl;
77+
m_rgb_mutex.lock();
78+
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
79+
std::copy(rgb, rgb+FREENECT_VIDEO_RGB_SIZE, m_buffer_video.begin());
80+
m_new_rgb_frame = true;
81+
m_rgb_mutex.unlock();
82+
};
83+
// Do not call directly even in child
84+
void DepthCallback(void* _depth, uint32_t timestamp) {
85+
std::cout << "Depth callback" << std::endl;
86+
m_depth_mutex.lock();
87+
uint16_t* depth = static_cast<uint16_t*>(_depth);
88+
for( unsigned int i = 0 ; i < FREENECT_FRAME_PIX ; i++) {
89+
int pval = m_gamma[depth[i]];
90+
int lb = pval & 0xff;
91+
switch (pval>>8) {
92+
case 0:
93+
m_buffer_depth[3*i+0] = 255;
94+
m_buffer_depth[3*i+1] = 255-lb;
95+
m_buffer_depth[3*i+2] = 255-lb;
96+
break;
97+
case 1:
98+
m_buffer_depth[3*i+0] = 255;
99+
m_buffer_depth[3*i+1] = lb;
100+
m_buffer_depth[3*i+2] = 0;
101+
break;
102+
case 2:
103+
m_buffer_depth[3*i+0] = 255-lb;
104+
m_buffer_depth[3*i+1] = 255;
105+
m_buffer_depth[3*i+2] = 0;
106+
break;
107+
case 3:
108+
m_buffer_depth[3*i+0] = 0;
109+
m_buffer_depth[3*i+1] = 255;
110+
m_buffer_depth[3*i+2] = lb;
111+
break;
112+
case 4:
113+
m_buffer_depth[3*i+0] = 0;
114+
m_buffer_depth[3*i+1] = 255-lb;
115+
m_buffer_depth[3*i+2] = 255;
116+
break;
117+
case 5:
118+
m_buffer_depth[3*i+0] = 0;
119+
m_buffer_depth[3*i+1] = 0;
120+
m_buffer_depth[3*i+2] = 255-lb;
121+
break;
122+
default:
123+
m_buffer_depth[3*i+0] = 0;
124+
m_buffer_depth[3*i+1] = 0;
125+
m_buffer_depth[3*i+2] = 0;
126+
break;
127+
}
128+
}
129+
m_new_depth_frame = true;
130+
m_depth_mutex.unlock();
131+
}
132+
bool getRGB(std::vector<uint8_t> &buffer) {
133+
m_rgb_mutex.lock();
134+
if(m_new_rgb_frame) {
135+
buffer.swap(m_buffer_video);
136+
m_new_rgb_frame = false;
137+
m_rgb_mutex.unlock();
138+
return true;
139+
} else {
140+
m_rgb_mutex.unlock();
141+
return false;
142+
}
143+
}
144+
145+
bool getDepth(std::vector<uint8_t> &buffer) {
146+
m_depth_mutex.lock();
147+
if(m_new_depth_frame) {
148+
buffer.swap(m_buffer_depth);
149+
m_new_depth_frame = false;
150+
m_depth_mutex.unlock();
151+
return true;
152+
} else {
153+
m_depth_mutex.unlock();
154+
return false;
155+
}
156+
}
157+
158+
private:
159+
std::vector<uint8_t> m_buffer_depth;
160+
std::vector<uint8_t> m_buffer_video;
161+
std::vector<uint16_t> m_gamma;
162+
Mutex m_rgb_mutex;
163+
Mutex m_depth_mutex;
164+
bool m_new_rgb_frame;
165+
bool m_new_depth_frame;
166+
};
167+
168+
Freenect::Freenect<MyFreenectDevice> freenect;
169+
MyFreenectDevice* device;
170+
171+
GLuint gl_depth_tex;
172+
GLuint gl_rgb_tex;
173+
174+
bool die;
175+
double freenect_angle(0);
176+
int got_frames(0),window(0);
177+
int g_argc;
178+
char **g_argv;
179+
180+
void DrawGLScene()
181+
{
182+
static std::vector<uint8_t> depth(640*480*4);
183+
static std::vector<uint8_t> rgb(640*480*4);
184+
185+
device->getDepth(depth);
186+
device->getRGB(rgb);
187+
188+
got_frames = 0;
189+
190+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
191+
glLoadIdentity();
192+
193+
glEnable(GL_TEXTURE_2D);
194+
195+
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
196+
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &depth[0]);
197+
198+
glBegin(GL_TRIANGLE_FAN);
199+
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
200+
glTexCoord2f(0, 0); glVertex3f(0,0,0);
201+
glTexCoord2f(1, 0); glVertex3f(640,0,0);
202+
glTexCoord2f(1, 1); glVertex3f(640,480,0);
203+
glTexCoord2f(0, 1); glVertex3f(0,480,0);
204+
glEnd();
205+
206+
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
207+
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &rgb[0]);
208+
209+
glBegin(GL_TRIANGLE_FAN);
210+
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
211+
glTexCoord2f(0, 0); glVertex3f(640,0,0);
212+
glTexCoord2f(1, 0); glVertex3f(1280,0,0);
213+
glTexCoord2f(1, 1); glVertex3f(1280,480,0);
214+
glTexCoord2f(0, 1); glVertex3f(640,480,0);
215+
glEnd();
216+
217+
glutSwapBuffers();
218+
}
219+
220+
void keyPressed(unsigned char key, int x, int y)
221+
{
222+
/* FreenectDeviceState::getState() doesnt really work as expected */
223+
//double freenect_angle = device->getState().getTiltDegs();
224+
225+
if (key == 27) {
226+
die = 1;
227+
glutDestroyWindow(window);
228+
}
229+
if (key == 'w') {
230+
freenect_angle++;
231+
if (freenect_angle > 30) {
232+
freenect_angle = 30;
233+
}
234+
}
235+
if (key == 's') {
236+
freenect_angle = 0;
237+
}
238+
if (key == 'x') {
239+
freenect_angle--;
240+
if (freenect_angle < -30) {
241+
freenect_angle = -30;
242+
}
243+
}
244+
if (key == '1') {
245+
device->setLed(LED_GREEN);
246+
}
247+
if (key == '2') {
248+
device->setLed(LED_RED);
249+
}
250+
if (key == '3') {
251+
device->setLed(LED_YELLOW);
252+
}
253+
if (key == '4') {
254+
device->setLed(LED_BLINK_YELLOW);
255+
}
256+
if (key == '5') {
257+
device->setLed(LED_BLINK_GREEN);
258+
}
259+
if (key == '6') {
260+
device->setLed(LED_BLINK_RED_YELLOW);
261+
}
262+
if (key == '0') {
263+
device->setLed(LED_OFF);
264+
}
265+
device->setTiltDegrees(freenect_angle);
266+
}
267+
268+
void ReSizeGLScene(int Width, int Height)
269+
{
270+
glViewport(0,0,Width,Height);
271+
glMatrixMode(GL_PROJECTION);
272+
glLoadIdentity();
273+
glOrtho (0, 1280, 480, 0, -1.0f, 1.0f);
274+
glMatrixMode(GL_MODELVIEW);
275+
}
276+
277+
void InitGL(int Width, int Height)
278+
{
279+
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
280+
glClearDepth(1.0);
281+
glDepthFunc(GL_LESS);
282+
glDisable(GL_DEPTH_TEST);
283+
glEnable(GL_BLEND);
284+
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
285+
glShadeModel(GL_SMOOTH);
286+
glGenTextures(1, &gl_depth_tex);
287+
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
288+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
289+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
290+
glGenTextures(1, &gl_rgb_tex);
291+
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
292+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
293+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
294+
ReSizeGLScene(Width, Height);
295+
}
296+
297+
void *gl_threadfunc(void *arg)
298+
{
299+
printf("GL thread\n");
300+
301+
glutInit(&g_argc, g_argv);
302+
303+
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
304+
glutInitWindowSize(1280, 480);
305+
glutInitWindowPosition(0, 0);
306+
307+
window = glutCreateWindow("LibFreenect");
308+
309+
glutDisplayFunc(&DrawGLScene);
310+
glutIdleFunc(&DrawGLScene);
311+
glutReshapeFunc(&ReSizeGLScene);
312+
glutKeyboardFunc(&keyPressed);
313+
314+
InitGL(1280, 480);
315+
316+
glutMainLoop();
317+
318+
return NULL;
319+
}
320+
321+
int main(int argc, char **argv) {
322+
device = &freenect.createDevice(0);
323+
device->startVideo();
324+
device->startDepth();
325+
gl_threadfunc(NULL);
326+
device->stopVideo();
327+
device->stopDepth();
328+
return 0;
329+
}

include/libfreenect.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace Freenect {
4141
const Noncopyable& operator=( const Noncopyable& );
4242
};
4343

44-
class FreenectDeviceState : Noncopyable {
44+
class FreenectDeviceState {
4545
friend class FreenectDevice;
4646
FreenectDeviceState(freenect_raw_tilt_state *_state):
4747
m_state(_state)

0 commit comments

Comments
 (0)