游戏中的场景以及物体在渲染时不是按照一个规格渲染,当距离较远时会渲染较为粗略的模型,这就用到了模型的LOD(Level of Detail)。
LOD功能也就是减少模型的顶点数,主要是用ID3DXPMesh的SetNumVertices方法来设置顶点数。减少的顶点根据顶点的权重来判断。
函数D3DXGeneratePMesh(
LPD3DXMESH pMesh,
CONST DWORD* pAdjacency,
CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights,
CONST FLOAT *pVertexWeights,
DWORD MinValue,
DWORD Options,
LPD3DXPMESH* ppPMesh);来从ID3DXMesh转为ID3DXPMesh。
在转换之前有三个步骤清理,焊接,检查是否有效。我们把每个物体类分为若干个不同顶点数的ID3DXMesh。保存为:
LPD3DXMESH LODMeshs[MAXLODLEVEL];
MeshNodeForLOD(){GenMesh=NULL;ZeroMemory(LODMeshs,MAXLODLEVEL*sizeof(LPD3DXMESH));};
}*LPMESHNODEFORLOD;
我们封装一个函数从ID3DXMesh转为ID3DXPMesh,然后保存多个ID3DXMesh存储在MeshNodeForLOD中。返回MeshNodeForLOD结构体。
HRESULT MakeMeshLOD( LPDIRECT3DDEVICE9 DVC,LPD3DXMESH pMesh,DWORD* pAdj,LPMESHNODEFORLOD pMeshNode )
if ((pMesh==NULL) || (pAdj==NULL) )
LPD3DXMESH pTempMesh =NULL; //临时网格模型变量
hr = D3DXCleanMesh( D3DXCLEAN_SIMPLIFICATION, pMesh,pAdj,&pTempMesh,pAdj, NULL ) ;
ZeroMemory( &Epsilons, sizeof(D3DXWELDEPSILONS) );
hr = D3DXWeldVertices( pMesh,D3DXWELDEPSILONS_WELDPARTIALMATCHES,
&Epsilons,pAdj,pAdj, NULL, NULL );
//检查对原始网格模型进行整理、简化之后,还需要检查处理后的网格模型是否有效
hr = D3DXValidMesh( pMesh, pAdj, NULL );
DWORD MaxVetex=pMesh->GetNumVertices();
hr = D3DXGeneratePMesh( pMesh, pAdj,NULL, NULL, 1, D3DXMESHSIMP_VERTEX, &ppMesh );
MaxVetex=pMesh->GetNumVertices();
for (int i=0;i<MAXLODLEVEL;i++)
ppMesh->SetNumVertices(MaxVetex*0.8);
hr=ppMesh->CloneMeshFVF(ppMesh->GetOptions(),ppMesh->GetFVF(),DVC,&pMeshNode->LODMeshs[i]);
MaxVetex=pMeshNode->LODMeshs[i]->GetNumVertices();
MaxVetex=ppMesh->GetNumVertices();
if( !(pMeshNode->LODMeshs[i]->GetFVF() & D3DFVF_NORMAL) )
hr=pMeshNode->LODMeshs[i]->CloneMeshFVF( pMeshNode->LODMeshs[i]->GetOptions(),
pMeshNode->LODMeshs[i]->GetFVF() | D3DFVF_NORMAL,
SAFE_RELEASE( pMeshNode->LODMeshs[i] );
pMeshNode->LODMeshs[i] = pTempMesh;
hr=D3DXComputeNormals( pMeshNode->LODMeshs[i], NULL ) ;
}
在渲染时,可以选择任意的某个进行渲染。
浙公网安备 33010602011771号