7. cNodeTreeMesh::Create and cNodeTreeMesh::Free

来源:互联网 发布:妙趣横生的算法怎么样 编辑:程序博客网 时间:2024/05/17 05:07
 

7. cNodeTreeMesh::Create and cNodeTreeMesh::Free

cNodeTreeMesh::Create是整个处理过程的开端。要创建一个NodeTree结构,你需要一个网格(mesh)资源,较好的方法是从cMesh对象中获得。cMesh对象包含了一个网格列表,它把含一个.x文件,并可以使得事情变得简单,仅仅需要处理列表中的第一个网格就可以。

 

要使用Create函数,需要一个指向先前初始化的cGraphics对象,先前载入的cMesh对象,和你想使用的树类型(QUADTREE OCTREE),你准备了整个的类以便去渲染。除了刚才提到的函数的变量,你也需要指定一个每个节点允许的多边形的数量,和节点在分裂之前的最大大小。

BOOL cNodeTreeMesh::Create(cGraphics *Graphics, cMesh *Mesh,

int TreeType,

float MaxSize, long MaxPolygons)

{

ID3DXMesh *LoadMesh;

unsigned short *IndexPtr;

DWORD *Attributes;

unsigned long i;

float MaxX, MaxY, MaxZ;

// 释放先前的 mesh

Free();

// 错误校验

if((m_Graphics = Graphics) == NULL)

return FALSE;

if(Mesh == NULL)

return FALSE;

if(!Mesh->GetParentMesh()->m_NumMaterials)

return FALSE;

// 获取资源网格信息

m_Mesh = Mesh->GetParentMesh(); // 指向mesh

LoadMesh = m_Mesh->m_Mesh; // ID3DXMesh 指针

m_VertexFVF = LoadMesh->GetFVF(); // Get FVF and size

m_VertexSize = D3DXGetFVFVertexSize(m_VertexFVF);

m_NumPolygons = LoadMesh->GetNumFaces(); // 多边形数量

m_MaxPolygons = MaxPolygons; // 保存多边形最大值

// 创建多边形列表和纹理组

m_PolygonList = new sPolygon[m_NumPolygons]();

m_NumGroups = m_Mesh->m_NumMaterials;

m_Groups = new sGroup[m_NumGroups]();

// Lock vertex, index, and attribute buffers

LoadMesh->LockIndexBuffer(D3DLOCK_READONLY,(BYTE**)&IndexPtr);

LoadMesh->LockAttributeBuffer(D3DLOCK_READONLY, &Attributes);

 

这里,你看到一些新的东西。ID3DXMesh使用顶点缓冲,另外,ID3DXMesh使用所谓的索引顶点缓冲。为取代在其它需要绘出保存顶点,你可以将所有顶点保存在缓冲区(按次序),并创建第二个数组用来与画出多每个多边形的三个顶点保持联系。这个数组就是索引数组(index array.

 

下面,一个调用属性缓冲(attribute buffer)ID3DXMesh对象,他是一个简单的数组,用来指定纹理是哪个多边形使用。是一个一对一的关系存在于数组元素和多边形。这就是属性缓冲,被用于指定多边形的各自的纹理组

 

下面的代码开始循环在mesh中通过每个多边形,找出构建多边形所使用的三个顶点。同时,使用多边形的数据结构保存要绘出的多表形要使用的纹理。

// 装在多边形信息到结构体中

for(i=0;i<m_NumPolygons;i++) {

m_PolygonList[i].Vertex[0] = *IndexPtr++; // 保存多边形

m_PolygonList[i].Vertex[1] = *IndexPtr++; // 索引数量

m_PolygonList[i].Vertex[2] = *IndexPtr++; // 在结构体中

 

// 保存多边形纹理组和数目

m_PolygonList[i].Group = Attributes[i];

m_Groups[Attributes[i]].NumPolygons++;

}

// 解锁缓冲区并释放他们(包括mesh

LoadMesh->UnlockIndexBuffer();

LoadMesh->UnlockAttributeBuffer();

// 创建纹理组顶点缓冲

for(i=0;i<m_NumGroups;i++) {

if(m_Groups[i].NumPolygons != 0)

m_Groups[i].VertexBuffer.Create(m_Graphics, /

m_Groups[i].NumPolygons * 3, /

m_VertexFVF, m_VertexSize);

}

 

在先前代码中,你可以看到mesh的索引数组和属性缓冲被锁定。在这一点,你仅需构建一个多边形信息的列表(它的所有顶点被每一个多边形使用,附加使用纹理组)。当你结束构建多变性数据列表,索引和属性缓冲被锁定,并且实际上的纹理组被配置。

 

每个纹理组包含一个cVertexBuffer对象,用来保存要被绘出的顶点。这是标准顶点缓冲,你将会爱上它,所以使用它并不会难。

// Get the size of the bounding cube

MaxX = (float)max(fabs(Mesh->GetParentMesh()->m_Min.x), /

fabs(Mesh->GetParentMesh()->m_Max.x));

MaxY = (float)max(fabs(Mesh->GetParentMesh()->m_Min.y), /

fabs(Mesh->GetParentMesh()->m_Max.y));

MaxZ = (float)max(fabs(Mesh->GetParentMesh()->m_Min.z), /

fabs(Mesh->GetParentMesh()->m_Max.z));

m_Size = max(MaxX, max(MaxY, MaxZ)) * 2.0f;

m_MaxSize = MaxSize;

// Create the parent node

m_ParentNode = new sNode();

 

这里,离资源网格中最远的点被计算。为了计算准确,世界必须是一个完全的立方体,所以你使用中心点到边的距离。当创建了父节点(m_ParentNode)之后,在锁定网格的顶点缓冲区可以读取顶点坐标。最后一点,节点调用SortNode函数:

// Sort polygons into nodes

LoadMesh->LockVertexBuffer(D3DLOCK_READONLY, /

(BYTE**)&m_VertexPtr);

SortNode(m_ParentNode, 0.0f, 0.0f, 0.0f, m_Size);

LoadMesh->UnlockVertexBuffer();

return TRUE;

}

 

一经排序,网格的顶点缓冲进行解锁,并返回TRUE标志成功。 在这一点,节点树mesh就已经被使用了。当你结束,要释放:

BOOL cNodeTreeMesh::Free()

{

delete m_ParentNode; // Delete parent node and all child nodes

m_ParentNode = NULL;

m_Graphics = NULL;

m_NumPolygons = 0; // No more polygons

delete [] m_PolygonList; // Delete polygon array

m_PolygonList = NULL;

m_NumGroups = 0; // No more texture groups

delete [] m_Groups; // Delete texture groups

m_Groups = NULL;

return TRUE;

}

 

原创粉丝点击