在三维图形程序设计中,网格模型占有非常重要的地位,而且也是比较复杂的部分,特别是包含动画和蒙皮信息的网格模型。
.x文件格式分析
.x文件格式最初是为传统的Direct3D保留模式而设计的,在DirectX
6.0问世后,针对立即模式对它作过一次扩展。要想在Direct3D程序中灵活自如地使用网格模型,应当深入理解.x文件格式。
.x文件是由模板(template)驱动的,模板定义了如何存储一个数据对象,这样用户便可以自己定义具体的格式。Direct3D预
定义了许多模板,这些预定义的模板位于rmxftmpl.h中,模板标识符都在rmxfguid.h中,通用文件DXUTMesh.cpp包含了这两个头文件
。模板所允许的数据类型称为可选成员(optional member),这些可选成员作为数据对象的子对象来保存,子对象可以是另一种数据类型或对先前数据对象的引用,或是一个二进制对象。
来看一个.x文件(cube_1.x)的完整内容:
xof 0302txt 0064
Header {
1;
0;
1;
}
Mesh Cube { //网格
8; //8个顶点,以下为8个顶点的坐标
1.000000;1.000000;-1.000000;,
-1.000000;1.000000;-1.000000;,
-1.000000;1.000000;1.000000;,
1.000000;1.000000;1.000000;,
1.000000;-1.000000;-1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000;-1.000000;1.000000;,
1.000000;-1.000000;1.000000;;
12; // 12个面, 以下为每个面三个顶点的索引
3;0,1,2;,
3;0,2,3;,
3;0,4,5;,
3;0,5,1;,
3;1,5,6;,
3;1,6,2;,
3;2,6,7;,
3;2,7,3;,
3;3,7,4;,
3;3,4,0;,
3;4,7,6;,
3;4,6,5;;
}
该模型的效果图如下:
第一行文件头中的 "xof"告诉程序,它加载的文件是一个.x文件,"0302"表示它使用的是DirectX
3.2 版本的模板,"txt"表示这些数据是以文本形式存储的,"0064"定义了浮点数的位数是64位。
文件头后面的一个数据块涉及了模板和数据对象等内容。一个模板和一个数据对象之间的差异在于所有的模板都是以一个template单词开始,模板看起来很像一个C语言的结构定义,数据对象就是那些模板的实例。使用模板定义包含在.x文件里的数据对象(一个模板定义了数据对象的布局),每个模板都可以通过一个数据类型的集合去定义并容纳任何类型的数据。同时,任何数据类型的组合都可以在一个模板里使用。
模板header的定义如下:
template Header {
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
WORD major;
WORD minor;
DWORD flags;
}
各成员分别表示.x文件最大版本,最小版本,以及定义方式。
.x文件中涉及模板的概念,它由四部分组成:第一部分是模板的名字,可是由数字、字符、下划线构成,但不能以数字开头,第二部分是GUID(Global
Unique Identifier,全局唯一标识符),第三部分由各个数据项构成,最后一部分用于控制模板的限制程度,一个模板可以是开放的、闭合的或受限的。开放模板的定义在结束部位有一个待展开的方括号[...]表示它可以包含其他数据类型,封闭模板不能包含其他任何数据类型,受限模板只能包含特定的数据类型。模板的使用与结构体有相似之处。
一般情况下,.x文件都至少包含一个Mesh模板,其定义如下:
Defines a simple mesh. The first array is a list of
vertices, and the second array defines the faces of the mesh by indexing into
the vertex array.
template Mesh
{
<3D82AB44-62DA-11CF-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
Where:
- nVertices - Number of vertices.
- array Vector vertices[nVertices] - Array of
vertices, each of type Vector.
- nFaces - Number of faces.
- array MeshFace faces[nFaces] - Array of faces,
each of type MeshFace.
- [ ... ] - Any .x file template can be used here.
This makes the architecture extensible. Material and TextureFilename
templates are typically used.
Mesh模板是一个开放的模板,同时它还用到了Vector模板和MeshFace模板,它们的定义如下:
Defines a vector.
template Vector
{
< 3D82AB5E-62DA-11cf-AB39-0020AF71E433 >
float x;
float y;
float z;
}
Used by the Mesh template to define a mesh's faces.
Each element of the nFaceVertexIndices array references a mesh vertex used to
build the face.
template MeshFace
{
< 3D82AB5F-62DA-11cf-AB39-0020AF71E433 >
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
Where:
- nFaceVertexIndices - Number of indices.
- array DWORD faceVertexIndices[nFaceVertexIndices]
- Array of indices.
因为没有为网格模型设置材质和纹理等信息,所以该文件显示效果是一个黑色立方体,接下来将为该立方体添加材质、法线和纹理信息。