简化模型的多边形

(整期优先)网络出版时间:2009-04-16
/ 1

摘要 本文介绍了一种简单快速的简化模型多边形的方法,并给出了D3D的实现代码
关键词 减面,多边形

一般在游戏中为了实现逼真的效果,通常会使用高细节的模型,它们的多边形数目非常庞大。借助于现在显卡强大的运算和渲染能力,这还不是什么问题。但在某些特殊环境下,比如远景的物体,或者网络传输带宽的限制,并不需要这么精确的模型,所以可以适当剔除一些多边形,这就是所谓的多边形减面算法。
在对模型表面作处理之前,首先要作些辅助工作。因为现在不但要知道这个模型是由哪些顶点构成的,还要知道每个顶点被哪些三角形使用,以及和每个顶点直接关联的邻接点。另外还应该得到组成每个三角形的三个顶点,以方便查询。基于以上思路,要建立三个数据结构:

第一个的定义是:
typedef struct _TriangleInfo
{
int id;
D3DXVECTOR3 pt;
_TriangleInfo* next;
}TriangleInfo,*LPTriangleInfo;
这是用来收集每个三角形的三个顶点。

第二个的定义是:
typedef struct _FaceInfo
{
int id;
D3DXVECTOR3 pt;
D3DXVECTOR3 vertex[3];
_FaceInfo* next;
_FaceInfo* tail;
}FaceInfo,*LPFaceInfo;
这是用来收集和每个顶点相关联的所有三角形

第三个的定义是:
typedef struct _VertexInfo
{
int id;
D3DXVECTOR3 pt;
_VertexInfo* next;
_VertexInfo* tail;
}VertexInfo,*LPVertexInfo;
这是用来收集某个顶点的所有邻接点。

在使用这三个数据结构之前要对它们进行初始化,主要是利用D3D的顶点缓冲区和索引缓冲区的数据,可以这样得到两个缓冲区,实现代码如下:

//得到顶点缓冲区
m_nNowVertex=m_pMyMesh->GetSysMemMesh()->GetNumVertices();
m_pd3dDevice->CreateVertexBuffer(m_nNowVertex*sizeof(CUSTOMVERTEX),
D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&m_pOldVB,0);
m_nOldVertex=m_nNowVertex;

m_pMyMesh->GetSysMemMesh()->GetVertexBuffer(&pOldVB);
m_pOldVB->Lock(0,0,(LPVOID*)&pDestVert,0);
pOldVB->Lock(0,0,(LPVOID*)&pSrcVert,0);
CopyMemory(pDestVert,pSrcVert,m_nNowVertex*sizeof(CUSTOMVERTEX));
m_pOldVB->Unlock();
pOldVB->Unlock();
pOldVB->Release();

//得到索引缓冲区
m_nNowFace=m_pMyMesh->GetSysMemMesh()->GetNumFaces();
m_pd3dDevice->CreateIndexBuffer(m_nNowFace*3*sizeof(WORD),D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,D3DPOOL_MANAGED,&m_pOldIB,0);
m_nOldFace=m_nNowFace;

m_pMyMesh->GetSysMemMesh()->GetIndexBuffer(&pOldIB);
m_pOldIB->Lock(0,0,(LPVOID*)&pDestIdx,0);
pOldIB->Lock(0,0,(LPVOID*)&pSrcIdx,0);
CopyMemory(pDestIdx,pSrcIdx,3*m_nNowFace*sizeof(WORD));
m_pOldIB->Unlock();
pOldIB->Unlock();
pOldIB->Release();

前两个数据结构初始化比较简单,具体过程可参考源代码,这里只列举一下得到邻接点的完整过程: