【问题标题】:glReadPixels and gluUnProject do not work properlyglReadPixels 和 gluUnProject 无法正常工作
【发布时间】:2018-09-17 10:25:56
【问题描述】:

我正在尝试使用glReadPixelsgluUnProject 获取真实坐标,但它不起作用。

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();

    }
}

点击点30,10,0给出

赢得 XYZ 1190 53 0
位置 XYZ 137.762 -82.3627 100

点击点40、10、10给出

赢得 XYZ 1239 51 0
位置 XYZ 147.552 -83.0283 100。

你能指出我哪里错了吗?

【问题讨论】:

  • 不在您的环境中编程,也没有为此使用 GLU,但从您的 y 坐标猜测您的 y 轴是错误的......请注意窗口 y 轴通常从窗口顶部开始,并且向下指向...而 OpenGL y 轴从底部开始并向上指向...。所以您很可能会从您认为正在选择的位置中选择镜像的y 位置...顺便说一句,我正在做这样的事情: OpenGL 3D-raypicking with high poly meshes 但是这是用于透视投影...

标签: c++ qt opengl


【解决方案1】:

QCursor::pos()提供的坐标是屏幕坐标。
QPoint QCursor::pos()

返回主屏幕光标(热点)的位置在全局屏幕坐标中

但是,QMouseEvent::pos() 提供的坐标是相对于小部件的坐标。
QPoint QMouseEvent::pos() const:

返回鼠标光标的位置相对于接收事件的小部件

这意味着您必须使用鼠标事件接收到的位置而不是QCursor::pos(),来解决您的问题:

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;
}

【讨论】:

  • 非常感谢。现在,它运作良好。我花了将近一周的时间。
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 2021-08-02
  • 2013-08-01
  • 2011-10-10
  • 2017-05-16
  • 2016-11-26
相关资源
最近更新 更多