这篇文件的主要内容来自于《Direct3D游戏编程入门教程(第二版)》。
现今流行的3D游戏格式有很多种,根据游戏类型的不同,每个游戏使用的文件格式也不同,一般来说,都是一个游戏对应于一种文件格式。不过看到《Professional XNA Game Programming》一书中使用x文件就能制作出很漂亮的赛车游戏,觉得对游戏制作爱好者来说x或fbx文件够用了。对我这种3D菜鸟来说,要自己创建一个模型实在是太难了,如果没有一个美术师帮你绘制模型,那么最好的方法就是从网上下载免费模型文件将它导入到3D工具中,我使用的是3DS Max9,然后通过插件导出为X或FBX文件。导出X文件的插件我用的是Panda Directx Exporter,可至http://www.andytather.co.uk/Panda/directxmax_downloads.aspx下载对应你的3DSMax的版本,对应3DS Max 9的最新版本是Panda Directx Exporter x86 (5.9.67.0) for 3DS Max 9 (32 bit) ,将解压后的PandaDirectXMaxExporter_x86.dle文件复制到3DS安装文件夹的plgin目录,即可在导出菜单下拉框中找到x文件的选项(官网上说要正常使用,还需安装2007年11月的Direct SDK)。fbx导出插件用的是Autodesk的官方插件,可到http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=10775855下载对应版本,使用帮助可见http://download.autodesk.com/us/fbx/3dsMax_online/_index.html。以下是我在使用过程中总结的一点经验,如有错误请及时指正。
最简单的模型的导出
首先在3DS中创建一个“平面”,观察一下3DS的坐标轴,可以看出它使用的是右手坐标系,但默认情况下Z轴朝上,而在XNA中默认是Y轴朝上。因为我想在XY平面中绘制一个平面,所以在顶视图中拉出一个矩形,然后在“修改”面板中将这个矩形的长度、宽度、长度分段,宽度分段都设置为1,再将这个正方形移至(0,0,0),名称默认为“Plane01”保持不变,颜色设置为红色(255,0,0),如下图所示,这应该是最简单的模型了,导出后可以看一下它的源代码,学习x文件的结构:
下一步选择菜单中的“文件”→“导出…”,在弹出的“选择要导出的文件”对话框的“保存类型”下来框中选择“Panda DirectX(*.X)”类型并选择输出目录和文件名称,我把它命名为square保存至C盘。点击保存后就会弹出Panda DirectX Exporter选项卡,共有六个选项卡。
1.3DS Max Objects选项卡
主要是输出数据类型的设置(注意在我的电脑上有些字母被遮住了,不知道原因,不过大致意思也能猜出)。
Output Options:我选择“Mesh difination”和“Materials”,不勾选“Inline”(这个我不懂),因为不使用骨骼动画,所以也不勾选“Bones”, Output Types:勾选“Geometric(几何体)”和“Dummy(虚拟体)”。
2.Mesh选项卡
设置网格的选项。
勾选“Mesh normals(需要导出法线)”和“Vertex colors”,Optmize mesh下拉菜单选择“Normal(法线)”,还可以选择“None(不作优化)”和“Optimized(已做优化)”。不选择“Mapping coordinares(纹理坐标)”,“Flip normals(翻转法线)”、“Use custom nromals(使用自定义法线)”和“Use local object space(使用模型坐标系,这会导致导出的文件丢失世界矩阵的信息)”。
3.Animaton选项卡
关于模型动画的设置。
因为这个例子中不使用动画,所以无需设置。
4.Textures&.fx files选项卡
设置纹理和fx文件。
Texture Conversion:本例不使用纹理,所以选择“None”。
.fx Effect Files:因为不使用effect所以不勾选“Include .fx files(包含fx文件)”和“Include .fx parameters(包含fx参数)”,其实自己也不知道如何设置,但在《Professional XNA Game Programming》中的所有x文件都是包含fx的。
5.X File Settings选项卡
DX File Type:我选择“Text”,这样可以在文本编辑器中看到源文件,不选择“Binary(二进制)”和“Binary with Compression(压缩的二进制文件)” 。在《Professional XNA Game Programming》中的所有x文件都是二进制的,所以用文本编辑器打开后是乱码。
DX Frame:本例中不使用层次模型,所以选择“No Frame(不包含框架)”,不选择“Top frame only(将只输出顶部框架)”和“Sub frame hierarchy(输出子框架层次)”。
Coordinate System:不选择“Left Handed Axis(左手坐标系,选择此项会将Y和Z坐标互换)”。
Xfile Animation Options:本例不使用动画,所以不选择“Include Animation”,Type下拉菜单可选“Closed(动画封闭)”和“Open(动画开放)”。Pos.Quality可选择“Spline Positions(样条位置)”和“Linear Positions(线性位置)”。
设置完以上选项后点击确定保存文件,我把它命名为“square.x”。
X文件的结构
在写字板中打开此文件,源代码如下:
xof 0303txt 0032 template Vector { <3d82ab5e-62da-11cf-ab39-0020af71e433> FLOAT x; FLOAT y; FLOAT z; } template MeshFace { <3d82ab5f-62da-11cf-ab39-0020af71e433> DWORD nFaceVertexIndices; array DWORD faceVertexIndices[nFaceVertexIndices]; } template Mesh { <3d82ab44-62da-11cf-ab39-0020af71e433> DWORD nVertices; array Vector vertices[nVertices]; DWORD nFaces; array MeshFace faces[nFaces]; [...] } template MeshNormals { <f6f23f43-7686-11cf-8f52-0040333594a3> DWORD nNormals; array Vector normals[nNormals]; DWORD nFaceNormals; array MeshFace faceNormals[nFaceNormals]; } template ColorRGBA { <35ff44e0-6c7c-11cf-8f52-0040333594a3> FLOAT red; FLOAT green; FLOAT blue; FLOAT alpha; } template ColorRGB { <d3e16e81-7835-11cf-8f52-0040333594a3> FLOAT red; FLOAT green; FLOAT blue; } template Material { <3d82ab4d-62da-11cf-ab39-0020af71e433> ColorRGBA faceColor; FLOAT power; ColorRGB specularColor; ColorRGB emissiveColor; [...] } template MeshMaterialList { <f6f23f42-7686-11cf-8f52-0040333594a3> DWORD nMaterials; DWORD nFaceIndexes; array DWORD faceIndexes[nFaceIndexes]; [Material <3d82ab4d-62da-11cf-ab39-0020af71e433>] } Mesh Plane01 { 4; -0.500000;-0.500000;0.000000;, 0.500000;-0.500000;0.000000;, -0.500000;0.500000;0.000000;, 0.500000;0.500000;0.000000;; 2; 3;2,0,3;, 3;1,3,0;; MeshNormals { 1; 0.000000;0.000000;1.000000;; 2; 3;0,0,0;, 3;0,0,0;; } MeshMaterialList { 1; 2; 0, 0; Material { 1.000000;0.000000;0.000000;1.000000;; 0.000000; 1.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; } } }
下面逐一解释。
首部
第一行xof 0303txt 0032中,起始的4个字节是魔数(magic number,所谓魔数就是用于标识某些特定文件格式的字节序列,比如bmp文件的魔数是BM,exe文件的魔数是MZ或PE)“xof”。主版本号为03,次版本号也是03,“txt”表示文本文件格式(还可以是bin),浮点数设置为0032(还可以是0064)。
模板
从“template Vector …”到“template MeshTextureCoords…”部分叫做模板。模板由四部分组成。以template Mesh为例:
template Mesh { <3d82ab44-62da-11cf-ab39-0020af71e433> DWORD nVertices; array Vector vertices[nVertices]; DWORD nFaces; array MeshFace faces[nFaces]; [...] }
其中第一部分“template Mesh”是一个独一无二的名称,可以由数字、字符、下划线构成,但不能以数字开头。第二部分是一个UUID(Universally Unique Identifier;全球唯一标识符),这里是<3d82ab44-62da-11cf-ab39-0020af71e433>。第三部分由各个数据项构成。例如在Mesh模板中 DWORD nVertices; array Vector vertices[nVertices]; DWORD nFaces; array MeshFace faces[nFaces];
再对照看一下下面的数据:
Mesh Plane01 { 4; -0.500000;-0.500000;0.000000;, 0.500000;-0.500000;0.000000;, -0.500000;0.500000;0.000000;, 0.500000;0.500000;0.000000;; 2; 3;2,0,3;, 3;1,3,0;;
可知第一个数字“4”表示有四个顶点,下面四行代码是顶点坐标数组,再下面的“2”表示有两个三角形。第四部分是“[...]”控制模板的限制程度,一个模板可以是开放的、闭合的或受限的。开放模板可以包含所有其他数据类型,封闭模板不可以包含任何其他数据类型,受限模板只可以包含特定的数据类型。一个待展开的“[...]”表示是一个开放模板。其他模板类似不再赘述。
数据
Mesh Plane01 { 4; //四个顶点 -0.500000;-0.500000;0.000000;, //顶点0坐标 0.500000;-0.500000;0.000000;, //顶点1坐标 -0.500000;0.500000;0.000000;, //顶点2坐标 0.500000;0.500000;0.000000;; //顶点3坐标 2; //两个三角形 3;2,0,3;, //第一个三角形 3;1,3,0;; //第二个三角形
其中“Plane01”就是在3DS中默认的名称。
MeshNormals { 1; //1条法线 0.000000;0.000000;1.000000;; //方向为(0,0,1) 2; //两条面法线 3;0,0,0;, //第一条面法线 3;0,0,0;; //第二条面法线 } MeshMaterialList { 1; //1个材质 2; //两个面 0, //第一个面使用材质0 0; //第二个面使用材质0 Material { 1.000000;0.000000;0.000000;1.000000;; //材质颜色,还记得我设置了红色吗 0.000000; //镜面反射power 1.000000;0.000000;0.000000;; //镜面反射颜色,也是红色,因为在3DS中默认漫反射和镜面反射使用的颜色相同 0.000000;0.000000;0.000000;; //自发光颜色 } }
在XNA中的截图如下:
文章来源:http://shiba.hpe.sh.cn/jiaoyanzu/WULI/showArticle.aspx?articleId=414&classId=4