0

I am pretty new to Qt so sorry if this is a straight forward question.

I am using Qt 5.5 and trying to visualize a point cloud in QOpenGLWidget.

This is my header:

class PointCloudWindow : public QOpenGLWidget
{
public:
    void setDepthMap(DepthMapGrabber* grabber);

protected:
    void initializeGL();
    void paintGL();

private:
    QMatrix4x4 m_projection;
    DepthMapGrabber* m_grabber;
};

and here is the corresponding cpp:

void PointCloudWindow::setDepthMap(DepthMapGrabber* grabber) {
    m_grabber = grabber;

    QTimer* updatePointCloud = new QTimer(this);
    connect(updatePointCloud, SIGNAL(timeout()), SLOT(update()));
    updatePointCloud->start();
}

void PointCloudWindow::initializeGL() {
    glewInit(); // TODO: check for return value if error occured

    glEnable(GL_DEPTH_TEST);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void PointCloudWindow::paintGL() {
    m_grabber->getNextDepthFrame(); // TODO: check for return value if error occured

    m_projection.setToIdentity();
    m_projection.perspective(45.0f, width() / (float)height(), 0.01f, 100.0f);

    if (m_grabber->getDepthMap()->cloud) {
        glBegin(GL_POINTS);
        glColor3f(0.8f, 0.8f, 0.8f);
        for (UINT i = 0; i < m_grabber->getDepthMap()->size; ++i)
        {
            glVertex3f(m_grabber->getDepthMap()->cloud[i].X, m_grabber->getDepthMap()->cloud[i].Y, m_grabber->getDepthMap()->cloud[i].Z);
        }
        glEnd();
    }
}

This is how my point cloud looks like after visualization:

point cloud from Kinect V2

My problem is that as you can see (monitor is cut in half for example) if a point has a z value, which is bigger, then 1.0 then it gets clipped of. I tried to set the near and far plane, but no effect. I searched through Google and tried several things, but was unable to figure out how this works in Qt. I manged to visualize this point cloud with OpenGL and GLUT before. Any help or explanation how to do this in Qt would be much appreciated!

Silex
  • 2,583
  • 3
  • 35
  • 59

1 Answers1

2

m_projection is just a member variable in your class. It's not going to automatically "jump" into the OpenGL context. You've to explicitly load it into OpenGL. Normally you'd load a matrix like that into a uniform for use in a shader. But since you're not using shaders (booo! ;-) ) and use old, ugly and slow immediate mode (don't do that) you'll have to load it into the fixed function projection matrix.

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(m_projection.constData());
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Hi, yea that is true! I just put it there, that I have the projection matrix...I just didn't know how to apply it. I tried as you suggested, but now I get a black screen. Oh, and I had to use glLoadMatrixf instead of glLoadMatrixd. Any suggestion how to fix this? – Silex Nov 17 '15 at 19:02
  • 1
    @Silex: I guess your z values are positive, right? OpenGL's default modelview transform looks down the negative Z axis, which will obviously clip your positive values. So you either rotate modelview by 180° around the Y axis, or scale Z=-1 (which will mirror your points). Without applying a projection and a modelview transform the default volume is the -1…1 cube (in local coordinates). NDC space (for some reason) is [-1,1]×[-1,1]×[0,1] – datenwolf Nov 17 '15 at 19:07
  • You are absolutely right. Now I remember that I had to add a 180 degree rotation to my previous code when I used OpenGL with GLUT. I tested it and now it works! Thank you very much! – Silex Nov 17 '15 at 19:16
  • @datenwolf: uhm? NDC space is [-1,1] even on Z? – peppe Nov 19 '15 at 20:34
  • @peppe: You're right of course. Had a D3D confusion brainfart there. – datenwolf Nov 19 '15 at 22:46