【问题标题】:gluUnProject not workinggluUnProject 不工作
【发布时间】:2012-08-03 22:45:22
【问题描述】:

我正在尝试使用 gluUnProject 将鼠标坐标转换为世界坐标,但它似乎不起作用,或者我只是误解了 glUnProject 函数的功能,这是我正在使用的代码,我的矩阵全部检查很好,至于鼠标 x 坐标上的 -300,我使用的是 C++ Win32 对话框,ScreenToClient 给了我很时髦的结果。

        int appWidth  = CApplication::GetInstance()->GetWidth();
        int appHeight = CApplication::GetInstance()->GetHeight();
        float fAspect = (float)appWidth / (float)appHeight;

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0f, fAspect, 0.1f, 100000.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(m_vecCamera.x, -m_vecCamera.y, m_vecCamera.z);

        GLint viewport[4];
        GLdouble modelview[16];
        GLdouble projection[16];
        GLfloat winX, winY, winZ;
        GLdouble posX, posY, posZ;

        glEnable(GL_DEPTH);
        //Retrieve the Model/View, Projection, and Viewport Matrices
        glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
        glGetDoublev( GL_PROJECTION_MATRIX, projection );
        glGetIntegerv( GL_VIEWPORT, viewport );

        //Retrieve the Mouse X and the flipped Mouse Y
        winX = (float)pInput->msg.param1-300.0f;
        winY = (float)viewport[3]-(float)pInput->msg.param2;
        glReadPixels( int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

        gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

然而,这给了我相对于屏幕中心的坐标,我假设是相对于我的相机,我也尝试实现自己的功能

Vector2f MouseUnProject(int x, int y)
{

        GLint viewport[4];
        GLdouble modelview[16];
        GLdouble projection[16];
        GLfloat winX, winY, winZ;
        GLdouble posX, posY, posZ;

        glEnable(GL_DEPTH);
        //Retrieve the Model/View, Projection, and Viewport Matrices
        glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
        glGetDoublev( GL_PROJECTION_MATRIX, projection );
        glGetIntegerv( GL_VIEWPORT, viewport );

        //Retrieve the Mouse X and the flipped Mouse Y
        winX = (float)x;
        winY = (float)viewport[3]-y;
        glReadPixels( int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

        double projectionX, projectionY;
        double viewX, viewY;
        double worldX, worldY;

        //Convert from Screen Coords to Projection Coords
        projectionX = (double)winX / ((double)viewport[2]/2.0) - 1.0;
        projectionY = (double)winY / ((double)viewport[3]/2.0) + 1.0;

        //Convert from projection Coords to View Coords
        viewX = projectionX * modelview[14];
        viewY = projectionY * modelview[14];

        //Convert from View Coords to World Coords
        worldX = viewX + modelview[12];
        worldY = viewY - modelview[13];

        return Vector2f(worldX, worldY);

}

它适用于特定的安装,但是当移动相机时,数字会立即下降一点,从投影到视图坐标的转换“似乎”没问题,而且投影坐标肯定很好。

我真的更喜欢使用 glUnProject 而不是我自己的函数,但我无法让它为我的生活工作,而且我发现的所有谷歌搜索似乎都没有回答我的问题。 GL 文档中的“对象空间”到底是什么意思,也许我对此的理解是错误的,如果是这样,我还需要做什么才能让我的坐标进入正确的空间?

【问题讨论】:

  • 你需要有一些几何图形来转换(例如,你的鼠标在什么地方?--当你的世界中没有任何东西时,转换到世界坐标是没有意义的)。您正在绘制几何图形,对吗?
  • 我想获得相对于世界单位矩阵的相机 Z(从 -100 开始)处的鼠标坐标,GLU 文档对这个函数的作用真的很模糊,我已经设置了投影矩阵,并已重置模型/视图矩阵并将相机平移应用到它,我有一个从 (0,0,0) 开始并从那里向一个方向延伸的地图(纹理四边形)。我的印象是,在应用视图变换之前,这个函数基本上会给我鼠标的位置,我没有看到什么以及如何正确使用这个函数?
  • 鼠标坐标加上深度为您提供透视分割后对象的位置(即屏幕坐标:在某某(x,y)位置和屏幕中的某个深度)。 gluUnProject 所做的是将这个位置 back 转换为原始对象的位置。因此,如果您绘制一个三角形,并且该三角形的一个顶点位于像素 (124,89) 处,深度为 0.647,则 gluUnProject 将能够告诉您该顶点的坐标。我不太确定你的问题是什么,但是我不太确定你在问什么。
  • 简单地说,我有一个地图编辑器,我希望在 3D 空间中检索鼠标的坐标,我的地图从 (0,0) 开始并延伸,比如说 X 和 Y 中的 1000轴,我希望我检索到的坐标在地图的左上角显示为 0,0,在右下角显示为 1000、1000,无论相机的平移如何,即当我的鼠标悬停在它们上方时
  • 好。所以,它是这样工作的:你开始你的框架。你画你的地图。您对鼠标下的深度进行采样。您将鼠标位置和深度连同模型视图和投影矩阵的当前值一起传递给 gluUnProject。结果应该是你想要的位置。我怀疑你的问题是你没有先渲染对象,所以你的深度值是错误的。您应该使用 print 语句检查这一点——当您将鼠标悬停在对象上时,它应该会发生显着变化。

标签: c++ opengl glu


【解决方案1】:

是在一年前发布的,但无论如何....所以你得到了相对于屏幕的坐标,因为你调用了 gluPerspective。此调用在内部调用 glfrustum,它将在 {-1, 1} 范围内生成归一化坐标。但是,如果您直接使用您的近/远值调用 glfrustum,您将在该范围内从 gluUnproject 获得结果。

要返回您的地图编辑器坐标,只需从 gluUnproject 获取结果并手动将范围转换回您的编辑器坐标系,即{-1,1} => {0, max}

首先你应该通过输入 (0,0), (midX, midY), (maxX, maxY) 来测试 gluUnProject 并且 gluUnProject 的结果应该是 (-1, -1, depth), (0, 0 , 深度) 和 (1, 1, 深度)。如果您使用 glFrustum 设置投影矩阵,则上述结果将在近/远范围内返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多