0

I am trying to get the real coordinates by using glReadPixels and gluUnProject, but it does not work.

void GLWidget::resizeGL(int Width, int Height)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
    glViewport(0, 0, (GLint)Width, (GLint)Height);

    currentWidth = Width;
    currentHeight = Height;
}

...

void GLWidget::plotAxis()
{
    GLdouble xc,yc,zc;

    glPointSize(7.0);
    // Test points
        glColor3f(0, 0, 0);
        glBegin(GL_POINTS);
        glVertex3f(30, 10, 0);
        glVertex3f(40, 10, 10);
        glVertex3f(50, 10, -10);
        glEnd();

}
...
void GLWidget::pickGeometry()
{

    makeCurrent();
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX = 0.0, winY = 0.0, winZ = 0.0;
    GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;

    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetIntegerv(GL_VIEWPORT, viewport);

    this->cursorX=QCursor::pos().x();
    this->cursorY=QCursor::pos().y();

    winX = cursorX;
    winY = viewport[3] - cursorY;

// obtain Z position
    glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

// obtain global coordinates
    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

    qDebug() << "win XYZ" << winX << winY << winZ;
    qDebug() << "pos XYZ" << posX << posY << posZ;
}

void GLWidget::mousePressEvent(QMouseEvent *event)
{
    pressPosition = event->pos();
    if(event->button()==Qt::LeftButton)
    {
    pickGeometry();

    }
}

click on point 30, 10, 0 gives

win XYZ 1190 53 0
pos XYZ 137.762 -82.3627 100

click on point 40, 10, 10 gives

win XYZ 1239 51 0
pos XYZ 147.552 -83.0283 100.

could you point me where I am wrong?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Alex1974
  • 29
  • 4
  • Not programing in your environment nor using GLU for this but guessing from your `y` coordinates your `y` axis is wrong ... beware that window `y` axis usually starts at top of window and points down ... while OpenGL `y` axis starts at bottom and points up .... so you are most likely picking mirrored `y` position from what you think you are picking... btw I am doing the stuff like this: [OpenGL 3D-raypicking with high poly meshes](https://stackoverflow.com/a/51764105/2521214) however that is for perspective projection ... – Spektre Sep 17 '18 at 12:41

1 Answers1

1

The coordinates provided by QCursor::pos() are screen coordinates.
See QPoint QCursor::pos():

Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.

But, the coordinates provided by QMouseEvent::pos() are coordinates relativ to the widget.
See QPoint QMouseEvent::pos() const:

Returns the position of the mouse cursor, relative to the widget that received the event.

This means you have to use the position received by the mouse event instead of QCursor::pos(), to solve your issue:

void GLWidget::mousePressEvent(QMouseEvent *event)
{
    pressPosition = event->pos();    

    .....
}

void OGLWidget::pickGeometry()
{
    makeCurrent();

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetIntegerv(GL_VIEWPORT, viewport);

    cursorX = pressPosition.rx(); // <-- pressPosition instead of QCursor::pos()
    cursorY = pressPosition.ry();

    GLfloat winX = 0.0, winY = 0.0, winZ = 0.0;
    winX = (GLfloat)cursorX;
    winY = (GLfloat)(viewport[3] - cursorY);

    // obtain Z position
    glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

    // obtain global coordinates
    GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;
    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

    qDebug() << "win XYZ" << winX << winY << winZ;
    qDebug() << "pos XYZ" << posX << posY << posZ;
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174