gluUnProject无法正常工作

时间:2012-08-03 22:45:23

标签: c++ opengl glu

我正在尝试使用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文档究竟是什么意思“对象空间”或许我对它的理解是错误的,如果是这样的话,我还需要做些什么来使我的坐标在正确的空间?

1 个答案:

答案 0 :(得分:0)

是一年前发布的,但无论如何....所以你得到相对于屏幕的坐标因为你打电话给gluPerspective。这个调用在内部调用glfrustum,它将生成范围为{-1,1}的规范化坐标。但是,如果您使用near / far值直接调用glfrustum,您将获得该范围内gluUnproject的结果。

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

要开始,你应该通过输入(0,0),(midX,midY),(maxX,maxY)来测试gluUnProject,而gluUnProject的结果应该是(-1,-1,深度),(0,0) ,深度)和(1,1,深度)。如果使用glFrustum设置投影矩阵,则上述结果将在near / far范围内返回。