关于OpenGL Math:OpenGL Math – 为世界空间坐标投影屏幕空间

OpenGL Math - Projecting Screen space to World space coords

到了一天结束时做一点数学计算的时候了。

我需要投影4个窗口大小的点:

<0,0><1024768>

变成一个世界空间坐标,这样它将形成一个四边形,稍后将用于地形剔除,而不需要进行地面投影。

仅用于测试,我使用鼠标坐标-并尝试将它们投影到世界坐标


断然的

下面是如何一步一步地准确地完成它。

0)在工作区内获取鼠标坐标

1)如果不需要模型矩阵,则获取投影矩阵和视图矩阵。

2)倍增投影*视图

3)将乘法结果求反

4)构造一个矢量4,由

x=窗口x范围内的mouseposition.x。-转换为介于-1和1之间的值

y=e窗口y范围内的cx1〔7〕。-转换为介于-1和1之间的值-如果需要,请记住反转mouseposition.y。

Z=the depth value(可以用glreadpixel获得)-您可以手动从-1转到1(znear、zfar)

W=1.0

5)将矢量乘以之前创建的逆矩阵

6)矩阵乘法(透视除法)后,将结果向量除以其w分量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        POINT mousePos;
        GetCursorPos(&mousePos);
        ScreenToClient( this->GetWindowHWND(), &mousePos );        

        CMatrix4x4 matProjection = m_pCamera->getViewMatrix() *  m_pCamera->getProjectionMatrix() ;

        CMatrix4x4 matInverse =  matProjection.inverse();


        float in[4];
        float winZ = 1.0;


        in[0]=(2.0f*((float)(mousePos.x-0)/(this->GetResolution().x-0)))-1.0f,
        in[1]=1.0f-(2.0f*((float)(mousePos.y-0)/(this->GetResolution().y-0)));
        in[2]=2.0* winZ -1.0;
        in[3]=1.0;          

        CVector4 vIn = CVector4(in[0],in[1],in[2],in[3]);
        pos = vIn * matInverse;

        pos.w = 1.0 / pos.w;

        pos.x *= pos.w;
        pos.y *= pos.w;
        pos.z *= pos.w;



        sprintf(strTitle,"%f %f %f / %f,%f,%f",m_pCamera->m_vPosition.x,m_pCamera->m_vPosition.y,m_pCamera->m_vPosition.z,pos.x,pos.y,pos.z);

        SetWindowText(this->GetWindowHWND(),strTitle);


把你所有的矩阵相乘。然后反转结果。投影后的点总是在-1,1中。所以四个角屏幕点是-1,-1;-1,1;1,-1;1,1。但您仍然需要选择th z值。如果您在OpenGL中,z在-1和1之间。对于DirectX,范围是0到1。最后把你的点用矩阵变换


如果您可以访问glu库,请使用glunproject(winx、winy、winz、model、projection、viewport和objx、objy和objz);

winXwinY将以像素为单位显示屏幕的角落。winZ是[0,1]中的一个数字,它将指定点应落在zNearzFar之间的位置。objX-Z将保存结果。中间变量是相关的矩阵。如果需要,可以查询它们。