在一天结束时进行一些数学运算的时间..
我需要预测窗口大小的4个点:
< 0,0> < 1024,768>
进入世界空间坐标,这样它将形成一个四边形的形状,以后将用于地形剔除 - 没有GluUnproject
仅供测试,我使用鼠标坐标 - 并尝试将它们投射到世界坐标上
答案 0 :(得分:32)
<强>分辨强>
以下是如何准确地执行此操作。
构造一个由
组成的vector4 窗口x 范围内的 x = mouseposition.x
y = mouseposition.y
z = the depth value
(这可以通过glReadPixel获得)
w = 1.0
将矢量乘以在
在矩阵乘法(透视除法)
之后将结果向量除以它的w分量 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 :(得分:7)
将所有矩阵相乘。然后反转结果。投影后的点总是在-1,1。所以四个角点的屏幕点是-1,-1; 1,1; 1,-1; 1,1。但是你仍然需要选择z值。如果你在OpenGL中,z介于-1和1之间。对于directx,范围是0到1.最后取点并用矩阵转换它们
答案 2 :(得分:2)
如果您可以访问glu库,请使用gluUnProject(winX,winY,winZ,model,projection,viewport,&amp; objX,&amp; objY,&amp; objZ);
winX
和winY
将成为屏幕的一角(以像素为单位)。 winZ
是[0,1]中的数字,用于指定点落入的zNear
和zFar
(剪裁平面)之间的位置。 objX-Z
将保留结果。中间变量是相关矩阵。如果需要,可以查询它们。
答案 3 :(得分:0)
我必须对此处提供的答案进行一些调整。但是,这是我最终得到的代码(请注意,我使用的是GLM,这可能会影响乘法顺序)。 nearResult是近平面上的投影点,farResult是远平面上的投影点。我想进行射线投射以查看鼠标悬停在什么地方,因此我将其转换为方向矢量,然后该方向矢量将从相机的位置开始。
vec3 getRayFromScreenSpace(const vec2 & pos)
{
mat4 invMat= inverse(m_glData.getPerspective()*m_glData.getView());
vec4 near = vec4((pos.x - Constants::m_halfScreenWidth) / Constants::m_halfScreenWidth, -1*(pos.y - Constants::m_halfScreenHeight) / Constants::m_halfScreenHeight, -1, 1.0);
vec4 far = vec4((pos.x - Constants::m_halfScreenWidth) / Constants::m_halfScreenWidth, -1*(pos.y - Constants::m_halfScreenHeight) / Constants::m_halfScreenHeight, 1, 1.0);
vec4 nearResult = invMat*near;
vec4 farResult = invMat*far;
nearResult /= nearResult.w;
farResult /= farResult.w;
vec3 dir = vec3(farResult - nearResult );
return normalize(dir);
}