一个网格(Mesh)对象是由一个或多个子集(Subset)组成。每个子集中又由一系列三角形、一个属性表来组成,一系列三角形用于组成网格(Mesh)的一部分,属性表用于指定三角形的材质、贴图以及渲染状态等。每个子集指定一个唯一的非负整数来标识子集,如0、1、2等。前面已经用到了Mesh类的DrawSubset()方法来绘制一个指定的子集,通过Mesh类的NumberAttributes属性可以获得网格中属性表的数目,即子集的数目,所以在不清楚网格中子集数目的情况下下绘制子集,可以如下代码来绘制网格中所有的子集对象:
for (int i = 0; i < meshObj.NumberAttributes; i++)
{
//绘制网格子集
meshObj.DrawSubset(i);
}
一个网格对象中可能包含多个子集,不同子集主要通过属性(AttributeID)来区别。
private void DeclareMultiSubsets()
{
int numberVerts = 8;
short[] indices = {
0,1,2, // 前面
1,3,2, // 前面
4,5,6, // 后面
6,5,7, // 后面
0,5,4, // 顶面
0,2,5, // 顶面
1,6,7, // 底面
1,7,3, // 底面
0,6,1, // 左面
4,6,0, // 左面
2,3,7, // 右面
5,2,7 // 右面
};
//创建网格对象
meshObj = new Mesh(indices.Length / 3, numberVerts, MeshFlags.Managed,
CustomVertex.PositionColored.Format, device);
//设置顶点缓冲数据
using (VertexBuffer vb = meshObj.VertexBuffer)
{
GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, 0x00ff00ff));
data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, 0x00ffff00));
data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, 0x0000ffff));
data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, 0x00ff0000));
data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, 0x000000ff));
data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, 0x0000ff00));
data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, 0x00ffffff));
data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, 0x00000000));
vb.Unlock();
}
//设置缓冲
using (IndexBuffer ib = meshObj.IndexBuffer)
{
ib.SetData(indices, 0, LockFlags.None);
}
//设置缓冲数据属性,为每个面设置属性
int[] attribBuffer = meshObj.LockAttributeBufferArray(LockFlags.None);
//设定前6个面的属性为0
for (int i = 0; i < 6; i++)
{
attribBuffer[i] = 0;
}
//设定后6个面的属性为1
for (int i = 0; i < 6; i++)
{
attribBuffer[i + 6] = 1;
}
// 解锁属性缓冲
meshObj.UnlockAttributeBuffer(attribBuffer);
// 创建属性
AttributeRange subset1 = new AttributeRange();
subset1.AttributeId = 0;
subset1.FaceStart = 0;
subset1.FaceCount = 6;
subset1.VertexCount = 36;
subset1.VertexStart = 0;
AttributeRange subset2 = new AttributeRange();
subset2.AttributeId = 1;
subset2.FaceStart = 6;
subset2.FaceCount = 6;
subset2.VertexCount = 36;
subset2.VertexStart = 0;
meshObj.SetAttributeTable(new AttributeRange[]{subset1,subset2});
}
如果要显示前面、后面和顶面,则在渲染函数中绘制第一个属性,如下代码:
meshObj.DrawSubset(0);
若要显示左面、右面和底面,则在渲染函数中绘制第二个属性,如下代码:
meshObj.DrawSubset(1);