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();