KINECT STATS GENERATOR FOR SPORTS VISUALISATION  1.0
GLWindow.cpp
Go to the documentation of this file.
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 
 All Classes Files Functions Variables Enumerations Enumerator