void GLRenderSystemCommon::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram) { Radian thetaY(fovy / 2.0f); Real tanThetaY = Math::Tan(thetaY); // Real thetaX = thetaY * aspect; Real tanThetaX = tanThetaY * aspect; // Math::Tan(thetaX); Real half_w = tanThetaX * nearPlane; Real half_h = tanThetaY * nearPlane; Real iw = 1.0f / half_w; Real ih = 1.0f / half_h; Real q; if (farPlane == 0) { q = 0; } else { q = 2.0f / (farPlane - nearPlane); } dest = Matrix4::ZERO; dest[0][0] = iw; dest[1][1] = ih; dest[2][2] = -q; dest[2][3] = -(farPlane + nearPlane) / (farPlane - nearPlane); dest[3][3] = 1; }
void GLRenderSystemCommon::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram) { Radian thetaY(fovy / 2.0f); Real tanThetaY = Math::Tan(thetaY); // Calc matrix elements Real w = (1.0f / tanThetaY) / aspect; Real h = 1.0f / tanThetaY; Real q, qn; if (farPlane == 0) { // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } else { q = -(farPlane + nearPlane) / (farPlane - nearPlane); qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane); } // NB This creates Z in range [-1,1] // // [ w 0 0 0 ] // [ 0 h 0 0 ] // [ 0 0 q qn ] // [ 0 0 -1 0 ] dest = Matrix4::ZERO; dest[0][0] = w; dest[1][1] = h; dest[2][2] = q; dest[2][3] = qn; dest[3][2] = -1; }
//----------------------------------------------------------------------- void Frustum::calcProjectionParameters(Real& left, Real& right, Real& bottom, Real& top) const { if (mCustomProjMatrix) //自定义投影矩阵 { // 转换剪裁平面角到相机空间中 Matrix4 invProj = mProjMatrix.inverse(); //对透视投影矩阵求逆得观察矩阵 Vector3 topLeft(-0.5f, 0.5f, 0.0f); //左上角 Vector3 bottomRight(0.5f, -0.5f, 0.0f); //右下角 topLeft = invProj * topLeft; bottomRight = invProj * bottomRight; left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; } else { //视锥体手动扩展设置 if (mFrustumExtentsManuallySet) { left = mLeft; right = mRight; top = mTop; bottom = mBottom; } // 计算通用的投影参数 else if (mProjType == PT_PERSPECTIVE) //透视投影 { Radian thetaY(mFOVy * 0.5f); //thetaY= mFovy的一半 Real tanThetaY = Math::Tan(thetaY); Real tanThetaX = tanThetaY * mAspect; //用于3d立体显示参数 Real nearFocal = mNearDist / mFocalLength; Real nearOffsetX = mFrustumOffset.x * nearFocal; Real nearOffsetY = mFrustumOffset.y * nearFocal; Real half_w = tanThetaX * mNearDist; Real half_h = tanThetaY * mNearDist; left = -half_w + nearOffsetX; right = +half_w + nearOffsetX; bottom = -half_h + nearOffsetY; top = +half_h + nearOffsetY; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } else { //正交投影 // 不知道怎样应用视锥体偏移到正交投影相机,这里就无效化 Real half_w = getOrthoWindowWidth() * 0.5f; Real half_h = getOrthoWindowHeight() * 0.5f; left = -half_w; right = +half_w; bottom = -half_h; top = +half_h; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } } }