KINECT STATS GENERATOR FOR SPORTS VISUALISATION
1.0
|
00001 #include "GLWindow.h" 00002 #include <iostream> 00003 #include "ngl/Camera.h" 00004 #include "ngl/Colour.h" 00005 #include "ngl/Light.h" 00006 #include "ngl/Matrix.h" 00007 #include "ngl/Transformation.h" 00008 #include "ngl/TransformStack.h" 00009 #include "ngl/Material.h" 00010 #include "ngl/NGLInit.h" 00011 #include "ngl/Obj.h" 00012 #include "ngl/VBOPrimitives.h" 00013 #include "ngl/ShaderManager.h" 00014 #include "libfreenect.hpp" 00015 #include "libfreenect_sync.h" 00016 #include "Mutex.h" 00017 #include <QDebug> 00018 //---------------------------------------------------------------------------------------------------------------------- 00019 GLWindow::GLWindow( 00020 QWidget *_parent 00021 ) : 00022 QGLWidget(_parent) 00023 { 00024 00025 // set this widget to have the initial keyboard focus 00026 // setFocus(); 00027 // re-size the widget to that of the parent (in this case the GLFrame passed in on construction) 00028 this->resize(_parent->size()); 00029 // Now set the initial GLWindow attributes to default values 00030 // Roate is false 00031 m_rotate=false; 00032 // mouse rotation values set to 0 00033 m_spinXFace=0; 00034 m_spinYFace=0; 00035 m_fpsTimer =startTimer(0); 00036 m_fps=0; 00037 m_frames=0; 00038 m_timer.start(); 00039 //device = &freenect.createDevice(0); 00040 //device->startVideo(); 00041 //device->startDepth(); 00042 //depth.resize(640*480*4); 00043 //rgb.resize(640*480*4); 00044 m_fpsTimer =startTimer(0); 00045 m_fps=0; 00046 m_frames=0; 00047 } 00048 00049 // This virtual function is called once before the first call to paintGL() or resizeGL(), 00050 //and then once whenever the widget has been assigned a new QGLContext. 00051 // This function should set up any required OpenGL context rendering flags, defining display lists, etc. 00052 00053 //---------------------------------------------------------------------------------------------------------------------- 00054 void GLWindow::initializeGL() 00055 { 00056 00057 glClearColor(0.4f, 0.4f, 0.4f, 1.0f); // Grey Background 00058 // enable depth testing for drawing 00059 00060 glEnable(GL_DEPTH_TEST); 00061 ngl::NGLInit *Init = ngl::NGLInit::instance(); 00062 Init->initGlew(); 00063 00064 00065 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 00066 00067 glClearDepth(1.0); 00068 //glDepthFunc(GL_LESS); 00069 //glDisable(GL_DEPTH_TEST); 00070 //glEnable(GL_BLEND); 00071 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00072 glShadeModel(GL_SMOOTH); 00073 glGenTextures(1, &gl_depth_tex); 00074 glBindTexture(GL_TEXTURE_2D, gl_depth_tex); 00075 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 00076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 00077 glGenTextures(1, &gl_rgb_tex); 00078 glBindTexture(GL_TEXTURE_2D, gl_rgb_tex); 00079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 00080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 00081 00082 00083 glClearColor(0.4f, 0.4f, 0.4f, 1.0f); // Grey Background 00084 // enable depth testing for drawing 00085 glEnable(GL_DEPTH_TEST); 00086 // Now we will create a basic Camera from the graphics library 00087 // This is a static camera so it only needs to be set once 00088 // First create Values for the camera position 00089 ngl::Vector From(2,2,2); 00090 ngl::Vector To(0,0,0); 00091 ngl::Vector Up(0,1,0); 00092 Init->initGlew(); 00093 Init->initVBO(); 00094 m_cam= new ngl::Camera(From,To,Up,ngl::PERSPECTIVE); 00095 // set the shape using FOV 45 Aspect Ratio based on Width and Height 00096 // The final two are near and far clipping planes of 0.5 and 10 00097 m_cam->setShape(60,(float)720.0/576.0,0.5,10,ngl::PERSPECTIVE); 00098 00099 m_pcam= new ngl::Camera(ngl::Vector(0,0,8),ngl::Vector(0,0,0),ngl::Vector(0,1,0),ngl::PERSPECTIVE); 00100 m_pcam->setShape(40,(float)2.5/2.0,0.1,120,ngl::PERSPECTIVE); 00101 00102 //m_pcam->setOrthoParams(-1,1,-1,1,1,10.0); //setOrthoParams( 0,0,100,100,1,10); 00103 // set the shape using FOV 45 Aspect Ratio based on Width and Height 00104 // The final two are near and far clipping planes of 0.5 and 10 00105 00106 00107 // now to load the shader and set the values 00108 // grab an instance of shader manager 00109 ngl::ShaderManager *shader=ngl::ShaderManager::instance(); 00110 // load a frag and vert shaders 00111 shader->loadShader("gl3xTest","shaders/Vertex.vs","shaders/Fragment.fs"); 00112 // set this as the active shader 00113 shader->useShader("gl3xTest"); 00114 // now pass the modelView and projection values to the shader 00115 shader->setShaderParamFromMatrix("gl3xTest","ViewMatrix",m_cam->getModelView()); 00116 shader->setShaderParamFromMatrix("gl3xTest","projectionMatrix",m_cam->getProjection()); 00117 // the shader will use the currently active material and light0 so set them 00118 shader->setShaderParam1i("gl3xTest","Normalize",true); 00119 shader->setShaderParam1i("gl3xTest","numLightsEnabled",3); 00120 shader->setShaderParam3f("gl3xTest","eye",m_cam->getEye()[0],m_cam->getEye()[1],m_cam->getEye()[2]); 00121 00122 // load a frag and vert shaders for colour no shading 00123 shader->loadShader("Colour","shaders/Colour.vs","shaders/Colour.fs"); 00124 // set this as the active shader 00125 shader->useShader("Colour"); 00126 shader->setShaderParamFromMatrix("Colour","ViewMatrix",m_pcam->getModelView()); 00127 shader->setShaderParamFromMatrix("Colour","projectionMatrix",m_pcam->getProjection()); 00128 00129 00130 ngl::Material m(ngl::GOLD); 00131 m.use(); 00132 ngl::Light *L1 = new ngl::Light(ngl::Vector(5,12,0,1),ngl::Colour(1,1,1,1),ngl::LIGHTLOCAL); 00133 L1->enable(); 00134 ngl::VBOPrimitives *prim=ngl::VBOPrimitives::instance(); 00135 prim->createVBOQuadPlane("plane",2.5,2,20,20,ngl::Vector(0,1,0)); 00136 } 00137 00138 //---------------------------------------------------------------------------------------------------------------------- 00139 //This virtual function is called whenever the widget has been resized. 00140 // The new size is passed in width and height. 00141 void GLWindow::resizeGL( 00142 int _w, 00143 int _h 00144 ) 00145 { 00146 glViewport(0,0,_w,_h); 00147 m_cam->setShape(45,(float)_w/_h,0.5,10,ngl::PERSPECTIVE); 00148 ngl::ShaderManager *shader=ngl::ShaderManager::instance(); 00149 shader->useShader("gl3xTest"); 00150 shader->setShaderParamFromMatrix("gl3xTest","projectionMatrix",m_cam->getProjection()); 00151 shader->useShader("Colour"); 00152 shader->setShaderParamFromMatrix("Colour","projectionMatrix",m_pcam->getProjection()); 00153 00154 /* 00155 glMatrixMode(GL_PROJECTION); 00156 glLoadIdentity(); 00157 glOrtho (0, 1280, 480, 0, -1.0f, 1.0f); 00158 glMatrixMode(GL_MODELVIEW); 00159 */ 00160 } 00161 00162 //---------------------------------------------------------------------------------------------------------------------- 00163 //This virtual function is called whenever the widget needs to be painted. 00164 // this is our main drawing routine 00165 void GLWindow::paintGL() 00166 { 00167 00168 // device->getDepth(depth); 00169 // device->getRGB(rgb); 00170 00171 00172 00173 00174 // clear the screen and depth buffer 00175 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00176 00177 glDisable(GL_TEXTURE_2D); 00178 // grab an instance of the shader manager 00179 ngl::ShaderManager *shader=ngl::ShaderManager::instance(); 00180 shader->useShader("gl3xTest"); 00181 // clear the screen and depth buffer 00182 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00183 // Rotation based on the mouse position for our global 00184 // transform 00185 ngl::Transformation trans; 00186 trans.setRotation(m_spinXFace,m_spinYFace,0); 00187 // set this in the TX stack 00188 m_transformStack.setGlobal(trans); 00189 // now set this value in the shader for the current ModelMatrix 00190 shader->setShaderParamFromMatrix("gl3xTest","ModelMatrix",m_transformStack.getCurrAndGlobal().getMatrix()); 00191 // get the VBO instance and draw the built in teapot 00192 ngl::VBOPrimitives *prim=ngl::VBOPrimitives::instance(); 00193 00194 00195 00196 m_transformStack.pushTransform(); 00197 { 00198 //m_transformStack.getCurrentTransform().setScale(4,4,4); 00199 shader->setShaderParamFromMatrix("gl3xTest","ModelMatrix",m_transformStack.getCurrAndGlobal().getMatrix()); 00200 prim->draw("teapot"); 00201 } // and before a pop 00202 m_transformStack.popTransform(); 00203 00204 00205 glBindTexture(GL_TEXTURE_2D, gl_depth_tex); 00206 glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &depth[0]); 00207 glDisable(GL_LIGHTING); 00208 shader->useShader("Colour"); 00209 00210 m_transformStack.pushTransform(); 00211 { 00212 m_transformStack.getCurrentTransform().setPosition(-3,2,0); 00213 m_transformStack.getCurrentTransform().setRotation(90.0f,0,180); 00214 shader->setShaderParamFromMatrix("Colour","ModelMatrix",m_transformStack.getCurrentTransform().getMatrix()); 00215 prim->draw("plane"); 00216 } // and before a pop 00217 m_transformStack.popTransform(); 00218 00219 00220 00221 glBindTexture(GL_TEXTURE_2D, gl_rgb_tex); 00222 glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &rgb[0]); 00223 00224 m_transformStack.pushTransform(); 00225 { 00226 m_transformStack.getCurrentTransform().setPosition(-3,-0.5,0); 00227 m_transformStack.getCurrentTransform().setRotation(90.0f,0,180); 00228 shader->setShaderParamFromMatrix("Colour","ModelMatrix",m_transformStack.getCurrentTransform().getMatrix()); 00229 prim->draw("plane"); 00230 } // and before a pop 00231 m_transformStack.popTransform(); 00232 00233 // calculate and draw FPS 00234 ++m_frames; 00235 glUseProgramObjectARB(0); 00236 glColor3f(1,1,1); 00237 QFont font; 00238 font.setPointSize(20); 00239 QString text=QString("Kinect Demo %1 fps").arg(m_fps); 00240 renderText(500,20,text,font); 00241 double x,y,z; 00242 device->getState().getAccelerometers(&x,&y,&z); 00243 text=QString("Accel %1 %2 %3").arg(x).arg(y).arg(z); 00244 renderText(400,40,text,font); 00245 00246 } 00247 00248 //---------------------------------------------------------------------------------------------------------------------- 00249 void GLWindow::mouseMoveEvent ( 00250 QMouseEvent * _event 00251 ) 00252 { 00253 // note the method buttons() is the button state when event was called 00254 // this is different from button() which is used to check which button was 00255 // pressed when the mousePress/Release event is generated 00256 if(m_rotate && _event->buttons() == Qt::LeftButton) 00257 { 00258 m_spinYFace = ( m_spinYFace + (_event->x() - m_origX) ) % 360 ; 00259 m_spinXFace = ( m_spinXFace + (_event->y() - m_origY) ) % 360 ; 00260 m_origX = _event->x(); 00261 m_origY = _event->y(); 00262 } 00263 // re-draw GL 00264 updateGL(); 00265 } 00266 00267 00268 //---------------------------------------------------------------------------------------------------------------------- 00269 void GLWindow::mousePressEvent ( 00270 QMouseEvent * _event 00271 ) 00272 { 00273 // this method is called when the mouse button is pressed in this case we 00274 // store the value where the maouse was clicked (x,y) and set the Rotate flag to true 00275 if(_event->button() == Qt::LeftButton) 00276 { 00277 m_origX = _event->x(); 00278 m_origY = _event->y(); 00279 m_rotate =true; 00280 } 00281 } 00282 00283 //---------------------------------------------------------------------------------------------------------------------- 00284 void GLWindow::mouseReleaseEvent ( 00285 QMouseEvent * _event 00286 ) 00287 { 00288 // this event is called when the mouse button is released 00289 // we then set Rotate to false 00290 if (_event->button() == Qt::LeftButton) 00291 { 00292 m_rotate=false; 00293 } 00294 } 00295 00296 void GLWindow::timerEvent( 00297 QTimerEvent *_event 00298 ) 00299 { 00300 00301 if(_event->timerId() == m_fpsTimer) 00302 { 00303 if( m_timer.elapsed() > 1000.0) 00304 { 00305 m_fps=m_frames; 00306 m_frames=0; 00307 m_timer.restart(); 00308 } 00309 } 00310 // re-draw GL 00311 updateGL(); 00312 00313 } 00314 00315 GLWindow::~GLWindow() 00316 { 00317 device->stopVideo(); 00318 device->stopDepth(); 00319 } 00320 00321 00322 00323 void GLWindow::incrementAngle() 00324 { 00325 m_angle++; 00326 if(m_angle > 30) 00327 { 00328 m_angle = 30; 00329 } 00330 qDebug()<<"Tilt"<<m_angle; 00331 device->setTiltDegrees(m_angle); 00332 } 00333 00334 void GLWindow::decrementAngle() 00335 { 00336 m_angle--; 00337 if(m_angle < -30) 00338 { 00339 m_angle = -30; 00340 } 00341 device->setTiltDegrees(m_angle); 00342 00343 } 00344 00345 void GLWindow::zeroAngle() 00346 { 00347 m_angle=0; 00348 device->setTiltDegrees(m_angle); 00349 00350 } 00351 00352 00353 00354 00355 // Do the projection from u,v,depth to X,Y,Z directly in an opengl matrix 00356 // These numbers come from a combination of the ros kinect_node wiki, and 00357 // nicolas burrus' posts. 00358 void GLWindow::LoadVertexMatrix() 00359 { 00360 float fx = 594.21f; 00361 float fy = 591.04f; 00362 float a = -0.0030711f; 00363 float b = 3.3309495f; 00364 float cx = 339.5f; 00365 float cy = 242.7f; 00366 GLfloat mat[16] = { 00367 1/fx, 0, 0, 0, 00368 0, -1/fy, 0, 0, 00369 0, 0, 0, a, 00370 -cx/fx, cy/fy, -1, b 00371 }; 00372 glMultMatrixf(mat); 00373 } 00374 00375 00376 // This matrix comes from a combination of nicolas burrus's calibration post 00377 // and some python code I haven't documented yet. 00378 void GLWindow::LoadRGBMatrix() 00379 { 00380 float mat[16] = { 00381 5.34866271e+02, 3.89654806e+00, 0.00000000e+00, 1.74704200e-02, 00382 -4.70724694e+00, -5.28843603e+02, 0.00000000e+00, -1.22753400e-02, 00383 -3.19670762e+02, -2.60999685e+02, 0.00000000e+00, -9.99772000e-01, 00384 -6.98445586e+00, 3.31139785e+00, 0.00000000e+00, 1.09167360e-02 00385 }; 00386 glMultMatrixf(mat); 00387 } 00388 00389 00390 00391 void GLWindow::drawPointCloud() 00392 { 00393 00394 uint32_t ts; 00395 00396 static unsigned int indices[480][640]; 00397 static short xyz[480][640][3]; 00398 int i,j; 00399 for (i = 0; i < 480; i++) { 00400 for (j = 0; j < 640; j++) { 00401 xyz[i][j][0] = j; 00402 xyz[i][j][1] = i; 00403 xyz[i][j][2] = depth[i*640+j]; 00404 indices[i][j] = i*640+j; 00405 } 00406 } 00407 00408 glLoadIdentity(); 00409 00410 glPushMatrix(); 00411 // glScalef(zoom,zoom,1); 00412 glTranslatef(0,0,-3.5); 00413 //glRotatef(rotangles[0], 1,0,0); 00414 //glRotatef(rotangles[1], 0,1,0); 00415 glTranslatef(0,0,1.5); 00416 00417 LoadVertexMatrix(); 00418 00419 // Set the projection from the XYZ to the texture image 00420 glMatrixMode(GL_TEXTURE); 00421 glLoadIdentity(); 00422 glScalef(1/640.0f,1/480.0f,1); 00423 LoadRGBMatrix(); 00424 LoadVertexMatrix(); 00425 glMatrixMode(GL_MODELVIEW); 00426 00427 glPointSize(1); 00428 00429 glEnableClientState(GL_VERTEX_ARRAY); 00430 glVertexPointer(3, GL_SHORT, 0, xyz); 00431 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00432 glTexCoordPointer(3, GL_SHORT, 0, xyz); 00433 00434 glEnable(GL_TEXTURE_2D); 00435 glBindTexture(GL_TEXTURE_2D, gl_rgb_tex); 00436 glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &rgb[0]); 00437 00438 glPointSize(2.0f); 00439 glDrawElements(GL_POINTS, 640*480, GL_UNSIGNED_INT, indices); 00440 glPopMatrix(); 00441 glDisable(GL_TEXTURE_2D); 00442 } 00443 00444