1.構造一個平截臺體(Frustum)
最近距離=-projMatirx.43/projMatrix.33
projMatrix。33 =深度/(深度-最近距離)
projMatrix。44=-最近距離*(深度/(深度-最近距離))
FrustumMatrix = projectionMatrix*viewMatirx;
FM=FrustumMatrix;
//最近面
m_planes[0].a = FrustumMatirx._14 + FrustumMatirx._13;
m_planes[0].b = FrustumMatirx._24 + FrustumMatirx._23;
m_planes[0].c = FrustumMatirx._34 + FrustumMatirx._33;
m_planes[0].d = FrustumMatirx._44 + FrustumMatirx._43;
D3DXPlaneNormalize(&m_planes[0], &m_planes[0]);
// 最遠面
m_planes[1].a = FrustumMatirx._14 - FrustumMatirx._13;
m_planes[1].b = FrustumMatirx._24 - FrustumMatirx._23;
m_planes[1].c = FrustumMatirx._34 - FrustumMatirx._33;
m_planes[1].d = FrustumMatirx._44 - FrustumMatirx._43;
D3DXPlaneNormalize(&m_planes[1], &m_planes[1]);
// 左面
m_planes[2].a = FrustumMatirx._14 + FrustumMatirx._11;
m_planes[2].b = FrustumMatirx._24 + FrustumMatirx._21;
m_planes[2].c = FrustumMatirx._34 + FrustumMatirx._31;
m_planes[2].d = FrustumMatirx._44 + FrustumMatirx._41;
D3DXPlaneNormalize(&m_planes[2], &m_planes[2]);
//右面
m_planes[3].a = FrustumMatirx._14 - FrustumMatirx._11;
m_planes[3].b = FrustumMatirx._24 - FrustumMatirx._21;
m_planes[3].c = FrustumMatirx._34 - FrustumMatirx._31;
m_planes[3].d = FrustumMatirx._44 - FrustumMatirx._41;
D3DXPlaneNormalize(&m_planes[3], &m_planes[3]);
//頂面
m_planes[4].a = FrustumMatirx._14 - FrustumMatirx._12;
m_planes[4].b = FrustumMatirx._24 - FrustumMatirx._22;
m_planes[4].c = FrustumMatirx._34 - FrustumMatirx._32;
m_planes[4].d = FrustumMatirx._44 - FrustumMatirx._42;
D3DXPlaneNormalize(&m_planes[4], &m_planes[4]);
// 地面
m_planes[5].a = FrustumMatirx._14 + FrustumMatirx._12;
m_planes[5].b = FrustumMatirx._24 + FrustumMatirx._22;
m_planes[5].c = FrustumMatirx._34 + FrustumMatirx._32;
m_planes[5].d = FrustumMatirx._44 + FrustumMatirx._42;
D3DXPlaneNormalize(&m_planes[5], &m_planes[5]);
檢測點(x,y,z)是否在平截臺體內:
for(i=0;i<6;i++)
{
if(D3DXPlanDotCoord(&m_panes[i],&D3DVECTOR3(x,y,z))<0.0f)
? ? ?{
? ? ? ? return fase;
? ? ? }
?return true;
}
檢測一個cube中是否有點在frustum
{
for(i=0; i<6; i++)?
{
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter - radius), (zCenter - radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter - radius), (zCenter - radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter + radius), (zCenter - radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter + radius), (zCenter - radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter - radius), (zCenter + radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter - radius), (zCenter + radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter + radius), (zCenter + radius))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter + radius), (zCenter + radius))) >= 0.0f)
{
continue;
}
return false;
}
return true;
}
檢測一個sphere是否在frustum
for(i=0; i<6; i++)
{
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3(xCenter, yCenter, zCenter)) < -radius)
{
return false;
}
}
return true;
?
檢測長方體是否在frustum
for(i=0; i<6; i++)
{
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter - zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter - zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f)
{
continue;
}
if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f)
{
continue;
}
return false;
}
return true;
2.模型列表
struct ModelInfoType
{
D3DXVECTOR4 color;
float positionX, positionY, positionZ;
};
m_ModelInfoList = new ModelInfoType[m_modelCount];
隨機位置隨機顏色產生
srand((unsigned int)time(NULL));
for(i=0; i<m_modelCount; i++)
{
red = (float)rand() / RAND_MAX;
green = (float)rand() / RAND_MAX;
blue = (float)rand() / RAND_MAX;
m_ModelInfoList[i].color = D3DXVECTOR4(red, green, blue, 1.0f);
m_ModelInfoList[i].positionX = (((float)rand()-(float)rand())/RAND_MAX) * 10.0f;
m_ModelInfoList[i].positionY = (((float)rand()-(float)rand())/RAND_MAX) * 10.0f;
m_ModelInfoList[i].positionZ = ((((float)rand()-(float)rand())/RAND_MAX) * 10.0f) + 5.0f;
}
GetData(int index, float& positionX, float& positionY, float& positionZ, D3DXVECTOR4& color)
{
positionX = m_ModelInfoList[index].positionX;
positionY = m_ModelInfoList[index].positionY;
positionZ = m_ModelInfoList[index].positionZ;
color = m_ModelInfoList[index].color;
return;
}
Render:
for(index=0; index<modelCount; index++)
{
m_ModelList->GetData(index, positionX, positionY, positionZ, color);
radius = 1.0f;
renderModel = m_Frustum->CheckSphere(positionX, positionY, positionZ, radius);
// 如果在frustum內則渲染,否則下一個;
if(renderModel)
{
D3DXMatrixTranslation(&worldMatrix, positionX, positionY, positionZ);
m_Model->Render(m_D3D->GetDeviceContext());
m_LightShader->Render(m_D3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_Model->GetTexture(), m_Light->GetDirection(), color);
m_D3D->GetWorldMatrix(worldMatrix);
renderCount++;
}
}
屏幕2D渲染記數,被渲染的球體數量:
?m_text->SetRenderCount(renderCount,m_d3d->GetContext());
?m_D3D->TurnZBufferOff();
?m_D3D->TurnOnAlphaBlending();
?m_text->Render(m_D3D->GetContext(),worldMatirx,orthoMatrix);
?m_D3D->TurnOffAlphaBlending();
?m_D3D->TurnZBufferOn();
?
?
?
?