void ExtractFrustumPlanes(XMFLOAT4 planes[6], CXMMATRIX M) { // // Left // planes[0].x = M(0,3) + M(0,0); planes[0].y = M(1,3) + M(1,0); planes[0].z = M(2,3) + M(2,0); planes[0].w = M(3,3) + M(3,0); // // Right // planes[1].x = M(0,3) - M(0,0); planes[1].y = M(1,3) - M(1,0); planes[1].z = M(2,3) - M(2,0); planes[1].w = M(3,3) - M(3,0); // // Bottom // planes[2].x = M(0,3) + M(0,1); planes[2].y = M(1,3) + M(1,1); planes[2].z = M(2,3) + M(2,1); planes[2].w = M(3,3) + M(3,1); // // Top // planes[3].x = M(0,3) - M(0,1); planes[3].y = M(1,3) - M(1,1); planes[3].z = M(2,3) - M(2,1); planes[3].w = M(3,3) - M(3,1); // // Near // planes[4].x = M(0,2); planes[4].y = M(1,2); planes[4].z = M(2,2); planes[4].w = M(3,2); // // Far // planes[5].x = M(0,3) - M(0,2); planes[5].y = M(1,3) - M(1,2); planes[5].z = M(2,3) - M(2,2); planes[5].w = M(3,3) - M(3,2); // Normalize the plane equations. for(int i = 0; i < 6; ++i) { XMVECTOR v = XMPlaneNormalize(XMLoadFloat4(&planes[i])); XMStoreFloat4(&planes[i], v); } }
void ExtractFrustumPlanes(XMFLOAT4 planes[6], CXMMATRIX M) { // // Left // planes[0].x = M.r[0].m128_f32[3] + M.r[0].m128_f32[0]; planes[0].y = M.r[1].m128_f32[3] + M.r[1].m128_f32[0]; planes[0].z = M.r[2].m128_f32[3] + M.r[2].m128_f32[0]; planes[0].w = M.r[3].m128_f32[3] + M.r[3].m128_f32[0]; // // Right // planes[1].x = M.r[0].m128_f32[3] - M.r[0].m128_f32[0]; planes[1].y = M.r[1].m128_f32[3] - M.r[1].m128_f32[0]; planes[1].z = M.r[2].m128_f32[3] - M.r[2].m128_f32[0]; planes[1].w = M.r[3].m128_f32[3] - M.r[3].m128_f32[0]; // // Bottom // planes[2].x = M.r[0].m128_f32[3] + M.r[0].m128_f32[1]; planes[2].y = M.r[1].m128_f32[3] + M.r[1].m128_f32[1]; planes[2].z = M.r[2].m128_f32[3] + M.r[2].m128_f32[1]; planes[2].w = M.r[3].m128_f32[3] + M.r[3].m128_f32[1]; // // Top // planes[3].x = M.r[0].m128_f32[3] - M.r[0].m128_f32[1]; planes[3].y = M.r[1].m128_f32[3] - M.r[1].m128_f32[1]; planes[3].z = M.r[2].m128_f32[3] - M.r[2].m128_f32[1]; planes[3].w = M.r[3].m128_f32[3] - M.r[3].m128_f32[1]; // // Near // planes[4].x = M.r[0].m128_f32[2]; planes[4].y = M.r[1].m128_f32[2]; planes[4].z = M.r[2].m128_f32[2]; planes[4].w = M.r[3].m128_f32[2]; // // Far // planes[5].x = M.r[0].m128_f32[3] - M.r[0].m128_f32[2]; planes[5].y = M.r[1].m128_f32[3] - M.r[1].m128_f32[2]; planes[5].z = M.r[2].m128_f32[3] - M.r[2].m128_f32[2]; planes[5].w = M.r[3].m128_f32[3] - M.r[3].m128_f32[2]; // Normalize the plane equations. for (int i = 0; i < 6; ++i) { XMVECTOR v = XMPlaneNormalize(XMLoadFloat4(&planes[i])); XMStoreFloat4(&planes[i], v); } }
void Frustum::ConstructFrustum(float screenDepth, XMFLOAT4X4 projectionMatrix, XMFLOAT4X4 viewMatrix) { view=viewMatrix; float zMinimum, r; XMFLOAT4X4 matrix; // Calculate the minimum Z distance in the frustum. zMinimum = -projectionMatrix._43 / projectionMatrix._33; r = screenDepth / (screenDepth - zMinimum); projectionMatrix._33 = r; projectionMatrix._43 = -r * zMinimum; // Create the frustum matrix from the view matrix and updated projection matrix. XMStoreFloat4x4( &matrix,XMMatrixMultiply(XMLoadFloat4x4(&viewMatrix), XMLoadFloat4x4(&projectionMatrix)) ); // Calculate near plane of frustum. m_planes[0].x = matrix._14 + matrix._13; m_planes[0].y = matrix._24 + matrix._23; m_planes[0].z = matrix._34 + matrix._33; m_planes[0].w = matrix._44 + matrix._43; XMStoreFloat4( &m_planesNorm[0],XMPlaneNormalize(XMLoadFloat4(&m_planes[0])) ); // Calculate far plane of frustum. m_planes[1].x = matrix._14 - matrix._13; m_planes[1].y = matrix._24 - matrix._23; m_planes[1].z = matrix._34 - matrix._33; m_planes[1].w = matrix._44 - matrix._43; XMStoreFloat4( &m_planesNorm[1],XMPlaneNormalize(XMLoadFloat4(&m_planes[1])) ); // Calculate left plane of frustum. m_planes[2].x = matrix._14 + matrix._11; m_planes[2].y = matrix._24 + matrix._21; m_planes[2].z = matrix._34 + matrix._31; m_planes[2].w = matrix._44 + matrix._41; XMStoreFloat4( &m_planesNorm[2],XMPlaneNormalize(XMLoadFloat4(&m_planes[2])) ); // Calculate right plane of frustum. m_planes[3].x = matrix._14 - matrix._11; m_planes[3].y = matrix._24 - matrix._21; m_planes[3].z = matrix._34 - matrix._31; m_planes[3].w = matrix._44 - matrix._41; XMStoreFloat4( &m_planesNorm[3],XMPlaneNormalize(XMLoadFloat4(&m_planes[3])) ); // Calculate top plane of frustum. m_planes[4].x = matrix._14 - matrix._12; m_planes[4].y = matrix._24 - matrix._22; m_planes[4].z = matrix._34 - matrix._32; m_planes[4].w = matrix._44 - matrix._42; XMStoreFloat4( &m_planesNorm[4],XMPlaneNormalize(XMLoadFloat4(&m_planes[4])) ); // Calculate bottom plane of frustum. m_planes[5].x = matrix._14 + matrix._12; m_planes[5].y = matrix._24 + matrix._22; m_planes[5].z = matrix._34 + matrix._32; m_planes[5].w = matrix._44 + matrix._42; XMStoreFloat4( &m_planesNorm[5],XMPlaneNormalize(XMLoadFloat4(&m_planes[5])) ); }
void SuperSolarSystemApp::DrawIceCube( ) { float blendFactor[] ={ 0.0f, 0.0f, 0.0f, 0.0f }; ID3DX11EffectTechnique *activeTech; D3DX11_TECHNIQUE_DESC techDesc; // // 画冰立方, 仅将其渲染到模板缓冲 // mD3dImmediateContext->IASetInputLayout( InputLayouts::NormalObjLayout ); mD3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); activeTech = Effects::NormalObjFX->NormalObjTech; activeTech->GetDesc( &techDesc ); UINT stride = sizeof( Vertex::NormalObjVertex ); UINT offset = 0; mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset ); mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 ); for ( UINT p = 0; p < techDesc.Passes; p++ ) { XMMATRIX world = XMLoadFloat4x4( &mWorld[ICECUBE] ); XMMATRIX worldViewProj = XMMatrixMultiply( world, mCamera.GetViewProj( ) ); XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world ); // 设置effect中的常量缓冲 Effects::NormalObjFX->SetWorldViewProj( worldViewProj ); Effects::NormalObjFX->SetWorld( world ); Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose ); Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[ICECUBE] ) ); // 设置纹理和材质 Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[ICECUBE] ); Effects::NormalObjFX->SetMaterial( mMat[ICECUBE] ); // 禁止对缓冲目标写操作 mD3dImmediateContext->OMSetBlendState( RenderStates::NoRenderTargetWritesBS, blendFactor, 0xffffffff ); // 将镜子的可见像素渲染到模板缓冲 // 但是不能将镜子的深度信息写到深度缓存, 否则将阻塞镜像 // 这里将镜子可见像素的 stencil value 设置为1, 当做标记了镜子像素 mD3dImmediateContext->OMSetDepthStencilState( RenderStates::MirrorDSS, 1 ); activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext ); mD3dImmediateContext->DrawIndexed( mLTIndexCount[LTVT_ICECUBE], mLTIndexOffset[LTVT_ICECUBE], mLTVertexOffset[LTVT_ICECUBE] ); // // 恢复措施 // mD3dImmediateContext->OMSetDepthStencilState( 0, 0 ); mD3dImmediateContext->OMSetBlendState( 0, blendFactor, 0xffffffff ); } // // 画天体的镜像 // stride = sizeof( Vertex::NormalObjVertex ); offset = 0; mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset ); mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 ); activeTech = Effects::NormalObjFX->NormalObjTech; activeTech->GetDesc( &techDesc ); for ( UINT p = 0; p < techDesc.Passes; ++p ) { // 对每一个冰面镜面确定成像内容 for ( int planeID = 0; planeID < 6; planeID++ ) { // 未经过世界坐标变换的镜面 XMVECTOR mirrorPlane = XMVectorSet( mIceCubeNormals[planeID].x, mIceCubeNormals[planeID].y, mIceCubeNormals[planeID].z, 1.0f ); // 将平面依据世界矩阵做变换 mirrorPlane = XMPlaneNormalize( mirrorPlane ); mirrorPlane = XMPlaneTransform( mirrorPlane, MathHelper::InverseTranspose( XMLoadFloat4x4( &mWorld[ICECUBE] ) ) ); XMMATRIX R = XMMatrixReflect( mirrorPlane ); for ( int starID = SUN; starID < STARNUMBER; starID++ ) { if ( ICECUBE == starID ) { continue; } XMVECTOR target = XMVectorSet( mWorld[starID]._41, mWorld[starID]._42, mWorld[starID]._43, 1.0f ); // 在镜子后面的物体不做镜像 if ( MathHelper::PointPlanePosRelation( target, mirrorPlane ) == MathHelper::BEHIND_THE_PLANE ) { continue; } // 设置转换矩阵 XMMATRIX world = XMLoadFloat4x4( &mWorld[starID] ) * R; XMMATRIX worldViewProj = XMMatrixMultiply( world, mCamera.GetViewProj( ) ); XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world ); // 设置effect中的常量缓冲 Effects::NormalObjFX->SetWorldViewProj( worldViewProj ); Effects::NormalObjFX->SetWorld( world ); Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose ); Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[starID] ) ); // 设置纹理和材质 Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[starID] ); Effects::NormalObjFX->SetMaterial( mMat[starID] ); // 设置RenderStates if ( WIREFENCE == starID ) { mD3dImmediateContext->RSSetState( RenderStates::NoCullRS ); } // 处理镜面反射的光线方向, 待解决 // 改变正面的判定方式 mD3dImmediateContext->RSSetState( RenderStates::CullClockwiseRS ); // 只在模板缓冲中标记为可见的镜面像素中写入镜像信息 mD3dImmediateContext->OMSetDepthStencilState( RenderStates::DrawReflectionDSS, 1 ); activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext ); mD3dImmediateContext->DrawIndexed( mLTIndexCount[LTVT_STAR], mLTIndexOffset[LTVT_STAR], mLTVertexOffset[LTVT_STAR] ); // // 恢复措施 // mD3dImmediateContext->RSSetState( 0 ); mD3dImmediateContext->OMSetDepthStencilState( 0, 0 ); } } } // // 最后将冰立方渲染至背面缓存, 但是要经过 blending 透明化处理 // mD3dImmediateContext->IASetInputLayout( InputLayouts::NormalObjLayout ); mD3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); activeTech = Effects::NormalObjFX->NormalObjTech; activeTech->GetDesc( &techDesc ); stride = sizeof( Vertex::NormalObjVertex ); offset = 0; mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset ); mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 ); for ( UINT p = 0; p < techDesc.Passes; p++ ) { XMMATRIX world = XMLoadFloat4x4( &mWorld[ICECUBE] ); XMMATRIX worldViewProj = XMMatrixMultiply( world, mCamera.GetViewProj( ) ); XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world ); // 设置effect中的常量缓冲 Effects::NormalObjFX->SetWorldViewProj( worldViewProj ); Effects::NormalObjFX->SetWorld( world ); Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose ); Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[ICECUBE] ) ); // 设置纹理和材质 Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[ICECUBE] ); Effects::NormalObjFX->SetMaterial( mMat[ICECUBE] ); mD3dImmediateContext->OMSetBlendState( RenderStates::TransparentBS, blendFactor, 0xffffffff ); activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext ); mD3dImmediateContext->DrawIndexed( mLTIndexCount[LTVT_ICECUBE], mLTIndexOffset[LTVT_ICECUBE], mLTVertexOffset[LTVT_ICECUBE] ); //恢复设置 mD3dImmediateContext->OMSetDepthStencilState( 0, 0 ); mD3dImmediateContext->OMSetBlendState( 0, blendFactor, 0xffffffff ); } }
void Frustum::ConstructFrustum(FLOAT screenDepth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix) { FLOAT zMinimum, r; XMMATRIX matrix; // Calculate the minimum Z distance in the frustum. zMinimum = -projectionMatrix._43 / projectionMatrix._33; r = screenDepth / (screenDepth - zMinimum); projectionMatrix._33 = r; projectionMatrix._43 = -r * zMinimum; // Create the frustum matrix from the view matrix and updated projection matrix. matrix = XMMatrixMultiply(viewMatrix, projectionMatrix); XMVECTOR tmp_vector; // Calculate near plane of frustum. m_planes[0].x = matrix._14 + matrix._13; m_planes[0].y = matrix._24 + matrix._23; m_planes[0].z = matrix._34 + matrix._33; m_planes[0].w = matrix._44 + matrix._43; tmp_vector = XMLoadFloat4(&m_planes[0]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[0], tmp_vector); // Calculate far plane of frustum. m_planes[1].x = matrix._14 - matrix._13; m_planes[1].y = matrix._24 - matrix._23; m_planes[1].z = matrix._34 - matrix._33; m_planes[1].w = matrix._44 - matrix._43; tmp_vector = XMLoadFloat4(&m_planes[1]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[1], tmp_vector); // Calculate left plane of frustum. m_planes[2].x = matrix._14 + matrix._11; m_planes[2].y = matrix._24 + matrix._21; m_planes[2].z = matrix._34 + matrix._31; m_planes[2].w = matrix._44 + matrix._41; tmp_vector = XMLoadFloat4(&m_planes[2]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[2], tmp_vector); // Calculate right plane of frustum. m_planes[3].x = matrix._14 - matrix._11; m_planes[3].y = matrix._24 - matrix._21; m_planes[3].z = matrix._34 - matrix._31; m_planes[3].w = matrix._44 - matrix._41; tmp_vector = XMLoadFloat4(&m_planes[3]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[3], tmp_vector); // Calculate top plane of frustum. m_planes[4].x = matrix._14 - matrix._12; m_planes[4].y = matrix._24 - matrix._22; m_planes[4].z = matrix._34 - matrix._32; m_planes[4].w = matrix._44 - matrix._42; tmp_vector = XMLoadFloat4(&m_planes[4]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[4], tmp_vector); // Calculate bottom plane of frustum. m_planes[5].x = matrix._14 + matrix._12; m_planes[5].y = matrix._24 + matrix._22; m_planes[5].z = matrix._34 + matrix._32; m_planes[5].w = matrix._44 + matrix._42; tmp_vector = XMLoadFloat4(&m_planes[5]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[5], tmp_vector); return; }
void Frustum::CreateFrustum(float screenDepth, XMMATRIX viewMatrix, XMMATRIX projMatrix) { float zMinimum, r; XMFLOAT4X4 projMatrixFloat; XMFLOAT4X4 frustumMatrix; XMStoreFloat4x4(&projMatrixFloat, projMatrix); // Calculate the minimum Z distance in the frustum. zMinimum = -projMatrixFloat._43 / projMatrixFloat._33; r = screenDepth / (screenDepth - zMinimum); projMatrixFloat._33 = r; projMatrixFloat._43 = -r * zMinimum; XMMATRIX updatedProjMatrix = XMLoadFloat4x4(&projMatrixFloat); //Create the frustum from the viewMatrix and updated projectionMatrix XMStoreFloat4x4(&frustumMatrix, XMMatrixMultiply(viewMatrix, updatedProjMatrix)); ; //Calculate near plane of frustum XMVectorSetX(this->planes[0], frustumMatrix._14 + frustumMatrix._13); XMVectorSetY(this->planes[0], frustumMatrix._24 + frustumMatrix._23); XMVectorSetZ(this->planes[0], frustumMatrix._34 + frustumMatrix._33); XMVectorSetW(this->planes[0], frustumMatrix._44 + frustumMatrix._43); this->planes[0] = XMPlaneNormalize(this->planes[0]); //this->planes[0] = XMVector3Normalize(this->planes[0]); //Calculate far plane of frustum XMVectorSetX(this->planes[1], frustumMatrix._14 - frustumMatrix._13); XMVectorSetY(this->planes[1], frustumMatrix._24 - frustumMatrix._23); XMVectorSetZ(this->planes[1], frustumMatrix._34 - frustumMatrix._33); XMVectorSetW(this->planes[1], frustumMatrix._44 - frustumMatrix._43); this->planes[1] = XMPlaneNormalize(this->planes[1]); //this->planes[1] = XMVector3Normalize(this->planes[1]); //Calculate left plane of frustum XMVectorSetX(this->planes[2], frustumMatrix._14 + frustumMatrix._11); XMVectorSetY(this->planes[2], frustumMatrix._24 + frustumMatrix._21); XMVectorSetZ(this->planes[2], frustumMatrix._34 + frustumMatrix._31); XMVectorSetW(this->planes[2], frustumMatrix._44 + frustumMatrix._41); this->planes[2] = XMPlaneNormalize(this->planes[2]); //this->planes[2] = XMVector3Normalize(this->planes[2]); //Calculate right plane of frustum XMVectorSetX(this->planes[3], frustumMatrix._14 - frustumMatrix._11); XMVectorSetY(this->planes[3], frustumMatrix._24 - frustumMatrix._21); XMVectorSetZ(this->planes[3], frustumMatrix._34 - frustumMatrix._31); XMVectorSetW(this->planes[3], frustumMatrix._44 - frustumMatrix._41); this->planes[3] = XMPlaneNormalize(this->planes[3]); //this->planes[3] = XMVector3Normalize(this->planes[3]); //Calculate top plane of frustum XMVectorSetX(this->planes[4], frustumMatrix._14 - frustumMatrix._12); XMVectorSetY(this->planes[4], frustumMatrix._24 - frustumMatrix._22); XMVectorSetZ(this->planes[4], frustumMatrix._34 - frustumMatrix._32); XMVectorSetW(this->planes[4], frustumMatrix._44 - frustumMatrix._42); this->planes[4] = XMPlaneNormalize(this->planes[4]); //this->planes[4] = XMVector3Normalize(this->planes[4]); //Calculate bottom plane of frustum XMVectorSetX(this->planes[5], frustumMatrix._14 + frustumMatrix._12); XMVectorSetY(this->planes[5], frustumMatrix._24 + frustumMatrix._22); XMVectorSetZ(this->planes[5], frustumMatrix._34 + frustumMatrix._32); XMVectorSetW(this->planes[5], frustumMatrix._44 + frustumMatrix._42); this->planes[5] = XMPlaneNormalize(this->planes[5]); //this->planes[5] = XMVector3Normalize(this->planes[5]); /*for (int i = 0; i < 6; i++) { float denom = 1.0f / XMVectorGetX(XMVector3Length(this->planes[i])); XMVectorSetX(this->planes[i], XMVectorGetX(this->planes[i]) * denom); XMVectorSetY(this->planes[i], XMVectorGetY(this->planes[i]) * denom); XMVectorSetZ(this->planes[i], XMVectorGetZ(this->planes[i]) * denom); XMVectorSetW(this->planes[i], XMVectorGetW(this->planes[i]) * denom); }*/ return; }
void FrustumClass::ConstructFrustum(XMMATRIX& projectionMatrix, XMMATRIX& viewMatrix) { float zMinimum, r; XMFLOAT4X4 matrix; XMMATRIX projection; XMFLOAT4X4 proj; XMStoreFloat4x4(&proj, projectionMatrix); // Calculate the minimum Z distance in the frustum. //zMinimum = -projectionMatrix._43 / projectionMatrix._33; //r = m_screenDepth / (m_screenDepth - zMinimum); //projectionMatrix._33 = r; //projectionMatrix._43 = -r * zMinimum; zMinimum = -proj._43 / proj._33; r = m_screenDepth / (m_screenDepth - zMinimum); proj._33 = r; proj._43 = -r * zMinimum; projection = XMLoadFloat4x4(&proj); // Create the frustum matrix from the view matrix and updated projection matrix. XMStoreFloat4x4(&matrix, XMMatrixMultiply(viewMatrix, projectionMatrix)); XMVECTOR tmp_vector; // Calculate near plane of frustum. m_planes[0].x = matrix._14 + matrix._13; m_planes[0].y = matrix._24 + matrix._23; m_planes[0].z = matrix._34 + matrix._33; m_planes[0].w = matrix._44 + matrix._43; tmp_vector = XMLoadFloat4(&m_planes[0]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[0], tmp_vector); // Calculate far plane of frustum. m_planes[1].x = matrix._14 - matrix._13; m_planes[1].y = matrix._24 - matrix._23; m_planes[1].z = matrix._34 - matrix._33; m_planes[1].w = matrix._44 - matrix._43; tmp_vector = XMLoadFloat4(&m_planes[1]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[1], tmp_vector); // Calculate left plane of frustum. m_planes[2].x = matrix._14 + matrix._11; m_planes[2].y = matrix._24 + matrix._21; m_planes[2].z = matrix._34 + matrix._31; m_planes[2].w = matrix._44 + matrix._41; tmp_vector = XMLoadFloat4(&m_planes[2]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[2], tmp_vector); // Calculate right plane of frustum. m_planes[3].x = matrix._14 - matrix._11; m_planes[3].y = matrix._24 - matrix._21; m_planes[3].z = matrix._34 - matrix._31; m_planes[3].w = matrix._44 - matrix._41; tmp_vector = XMLoadFloat4(&m_planes[3]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[3], tmp_vector); // Calculate top plane of frustum. m_planes[4].x = matrix._14 - matrix._12; m_planes[4].y = matrix._24 - matrix._22; m_planes[4].z = matrix._34 - matrix._32; m_planes[4].w = matrix._44 - matrix._42; tmp_vector = XMLoadFloat4(&m_planes[4]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[4], tmp_vector); // Calculate bottom plane of frustum. m_planes[5].x = matrix._14 + matrix._12; m_planes[5].y = matrix._24 + matrix._22; m_planes[5].z = matrix._34 + matrix._32; m_planes[5].w = matrix._44 + matrix._42; tmp_vector = XMLoadFloat4(&m_planes[5]); XMPlaneNormalize(tmp_vector); XMStoreFloat4(&m_planes[5], tmp_vector); }
void Frustum::ConstructFrustum(float screenDepth, XMMATRIX &projectionMatrix, XMMATRIX &viewMatrix) { float zMinimum, r; XMMATRIX matrix; XMFLOAT4X4 f_matrix, f_projectionMatrix, f_viewMatrix; XMFLOAT4 planes[6]; // Create the frustum matrix from the view matrix and updated projection matrix. matrix = XMMatrixMultiply(viewMatrix, projectionMatrix); XMStoreFloat4x4(&f_projectionMatrix, projectionMatrix); XMStoreFloat4x4(&f_viewMatrix, viewMatrix); XMStoreFloat4x4(&f_matrix, matrix); // Calculate the minimum Z distance in the frustum. zMinimum = -f_projectionMatrix._43 / f_projectionMatrix._33; r = screenDepth / (screenDepth - zMinimum); f_projectionMatrix._33 = r; f_projectionMatrix._43 = -r * zMinimum; // Calculate near plane of frustum. planes[0].x = f_matrix._14 + f_matrix._13; planes[0].y = f_matrix._24 + f_matrix._23; planes[0].z = f_matrix._34 + f_matrix._33; planes[0].w = f_matrix._44 + f_matrix._43; // Calculate far plane of frustum. planes[1].x = f_matrix._14 - f_matrix._13; planes[1].y = f_matrix._24 - f_matrix._23; planes[1].z = f_matrix._34 - f_matrix._33; planes[1].w = f_matrix._44 - f_matrix._43; // Calculate left plane of frustum. planes[2].x = f_matrix._14 + f_matrix._11; planes[2].y = f_matrix._24 + f_matrix._21; planes[2].z = f_matrix._34 + f_matrix._31; planes[2].w = f_matrix._44 + f_matrix._41; // Calculate right plane of frustum. planes[3].x = f_matrix._14 - f_matrix._11; planes[3].y = f_matrix._24 - f_matrix._21; planes[3].z = f_matrix._34 - f_matrix._31; planes[3].w = f_matrix._44 - f_matrix._41; // Calculate top plane of frustum. planes[4].x = f_matrix._14 - f_matrix._12; planes[4].y = f_matrix._24 - f_matrix._22; planes[4].z = f_matrix._34 - f_matrix._32; planes[4].w = f_matrix._44 - f_matrix._42; // Calculate bottom plane of frustum. planes[5].x = f_matrix._14 + f_matrix._12; planes[5].y = f_matrix._24 + f_matrix._22; planes[5].z = f_matrix._34 + f_matrix._32; planes[5].w = f_matrix._44 + f_matrix._42; int i = 0; for (auto plane : planes) { m_planes[i] = XMLoadFloat4(&plane); XMPlaneNormalize(m_planes[i]); i++; } return; }