c++ - gluUnProject 不工作

标签 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);

}

它适用于特定的支架,但是当移动相机时,数字会立即变小,从投影到 View 坐标的转换“似乎”没问题,而且投影坐标绝对不错。

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

最佳答案

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

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

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

关于c++ - gluUnProject 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11804258/

相关文章:

c++ - 编译使用 OpenGL 的代码时找不到 libGLESv2.dll

c++ - OpenGL - 最大化/最小化输出窗口调整内部对象的大小。我怎样才能避免这种情况?

Android OpenGL ES 2.0 读取 gluunproject/或 calc raycollision 与近远坐标的 z-buffer

c++ - 为什么 GLU 会在这个地方崩溃?

c++ - C++0x 中是否有本地化支持的更新?

c++ - 有没有办法解决这个模板循环依赖

c++ - 从 C++ 开始,密码验证器

c++ - OpenCV 将仿射变换应用于单个点而不是整个图像

ios - 如何使用 2D 纹理将 RGB 位图渲染到 GLKView 中?