有很多朋友也许想更加了解X文件,正好,本文将全面的介绍X文件的使用。我想这是一篇纯技术性的文档,我就不加以诗篇歌颂润色了。相信读我的文章,就像啃牙签;)好了,我们板起面孔。首先给你一个完整的印象----传说中的X文件: xof 0302txt 0032
template Header { <3D82AB43-62DA-11cf-AB39-0020AF71E433> DWORD major; DWORD minor; DWORD flags; }
template Frame { <3D82AB46-62DA-11cf-AB39-0020AF71E433> [FrameTransformMatrix] [Mesh] }
Header { 1; 0; 1; }
Frame Scene_Root { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; } Frame Pyramid_Frame { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; } Mesh PyramidMesh { 5; 0.00000;10.00000;0.00000;, -10.00000;0.00000;10.00000;, 10.00000;0.00000;10.00000;, -10.00000;0.00000;-10.00000;, 10.00000;0.00000;-10.00000;; 6; 3;0,1,2;, 3;0,2,3;, 3;0,3,4;, 3;0,4,1;, 3;2,1,4;, 3;2,4,3;; MeshMaterialList { 1; 6; 0,0,0,0,0,0;; Material Material0 { 1.000000; 1.000000; 1.000000; 1.000000;; 0.000000; 0.050000; 0.050000; 0.050000;; 0.000000; 0.000000; 0.000000;; } } } } } xof 0302txt 0032 xof表示这是一个真正的X文件。0302txt表示通知程序使用Directx的X文件,版本为3.2的模版,其中txt表示此文件为文本文件,可读,并非是一个2进制文件。0032表示一个浮点数的位数为32,如果想要用64位的浮点数,可以写成0064。
下面将分别介绍各个主题。
声明一个模版:\\\\\\\\\\\\\\假设声明 template ContactEntry 首先需要用guidgen.exe产生一个GUID。产生的GUID如下: // {4C9D055B-C64D-4bfe-A7D9-981F507E45FF} DEFINE_GUID(<<name>>, 0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, 0x1f, 0x50, 0x7e, 0x45, 0xff); 之后需要在程序代码中加入: #include "initguid.h" // At beginning of source code file - add DEFINE_GUIDs DEFINE_GUID(ContactEntry, 0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, 0x1f, 0x50, 0x7e, 0x45, 0xff); 还要在X文件中加入: template ContactEntry { <4C9D055B-C64D-4bfe-A7D9-981F507E45FF>
声明模版用到的数据类型: 关键字 描述 WORD 16-bit value (short) DWORD 32-bit value (32-bit int or long) FLOAT IEEE float value (float) DOUBLE 64-bit floating-point value (double) CHAR 8-bit signed value (signed char) UCHAR 8-bit unsigned value (unsigned char) BYTE 8-bit unsigned value (unsigned char) STRING A NULL-terminated string (char[])) array Signifies an array of following data type to follow ([]) 举例: DWORD value; array STRING Text[20];//定义一个名为Text的数组,类型为STRING,大小为20。 DWORD ArraySize; array STRING Names[ArraySize]; //可以将大小设置为变量。
声明一个ContactEntry模版: template ContactEntry { <4C9D055B-C64D-4bfe-A7D9-981F507E45FF> STRING Name; // The contact's name STRING PhoneNumber; // The contact's phone number DWORD Age; // The contact's age } 实例化一个模版对象: ContactEntry JimsEntry { "Jim Adams"; "(800) 555-1212"; 30; } {JimsEntry} 可以用这样的形式引用一个数据对象。例如,在一个animation sequence template中引用
一个Frame data object做为其内嵌数据对象。也可以利用引用表示一个数据对象的副本,没有必要重复
书写这个数据对象。
内嵌数据对象和模版约束:\\\\\\\\\\\\\\template ClosedTemplate { <4C9D055B-C64D-4bfe-A7D9-981F507E45FF> DWORD ClosedData; } template OpenTemplate { <4C9D055B-C64D-4bff-A7D9-981F507E45FF> DWORD OpenData; [...] } template RestrictedTemplate { <4C9D055B-C64D-4c00-A7D9-981F507E45FF> DWORD RestrictedData; [ClosedTemplate] [OpenTemplate] } ClosedTemplate是标准的模版声明。 OpenTemplate中包含一个[...],表示这是一个开放模版。开放模版允许在[]中内嵌任何数据对象。例如
,你可以实例化OpenTemplate,在里面定义一个OpenData变量和内嵌一个ClosedTemplate的实例。 RestrictedTemplate为约束模版。约束模版实例化时只允许包含它列出的数据对象,如,不能在
RestrictedTemplate包含[ClosedTemplate],[OpenTemplate]以外的数据对象。
用DirectX .X Standard Templates工作:\\\\\\\\\\\\\\\\\X文件广泛用于包含一个mesh信息。一个Standard Templates包含了过多的信息。 Table 3.2: DirectX .X Standard Templates Template Name Description Animation: Defines animation data for a single frame. AnimationKey: Defines a single key frame for the parent animation template. AnimationOptions: Contains animation playback information. AnimationSet: Contains a collection of animation templates. Boolean: Holds a Boolean value. Boolean2d: Holds two Boolean values. ColorRGB: Contains red, green, and blue color values. ColorRGBA: Contains red, green, blue, and alpha color values. Coords2d: Defines two coordinate values. FloatKeys: Contains an array of floating-point values. FrameTransformMatrix: Holds the transformation matrix for a parent Frame template. Frame: A frame-of-reference template that defines a hierarchy. Header: The .X file header that contains version numbers. IndexedColor: Contains an indexed color value. Material: Contains material color values. Matrix4x4: Holds a 4x4 homogenous matrix container. Mesh: Contains a single mesh's data. MeshFace: Holds a mesh's face data. MeshFaceWraps: Contains the texture wrapping for mesh faces. MeshMaterialList: Contains the material for face-mapping values. MeshNormals: Holds normals used for mesh data. MeshTextureCoords: Holds texture coordinates used for mesh data. MeshVertexColors: Holds vertex color information used for mesh vertices. Patch: Defines a control patch. PatchMesh: Contains a patch mesh (much like the Mesh template). Quaternion: Holds a quaternion value. SkinWeights: Contains an array of weight values mapped to a mesh's vertices.
Used in skinned meshes. TextureFilename: Contains the texture file name to use for a material. TimedFloatKeys: Contains an array of FloatKeys templates. Vector: Holds a 3D coordinate value. VertexDuplicationIndices: Informs you which vertices are duplicates of other vertices. XSkinMeshHeader: Used by skinned meshes to define the number of bones contained
in a mesh. 在rmxfguid.h中定义了各个模版的宏,例如: /* {3D82AB44-62DA-11cf-AB39-0020AF71E433} */ DEFINE_GUID(TID_D3DRMMesh, 0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); 每个模版名加上前缀TID_D3DRM就是宏定义名。
访问.X文件:\\\\\\\\\\\\\\\\\访问任何X文件首先要调用DirectXFileCreate函数创建一个IDirectXFile接口。 IDirectXFile *pDXFile = NULL; HRESULT Result = DirectXFileCreate(&pDXFile);//用&pDXFile返回指向接口的指针。用SUCCEEDED或者
FAILED宏判断返回值是否有效。
注册一个定制ro标准模版:\\\\\\\\\\\\\你可以把X文件中的模版移除,直接在代码里定义那些模版。IDirectXFile接口支持这样的特性。需要调
用IDirectXfile::RegisterTemplates函数。 HRESULT IDirectXfile::RegisterTemplates( LPVOID pvData, // 一个定义模版数据的缓存,应该精确无误。 DWORD cbSize); // pvData缓存的字节数。 可以如下定义一个模版数据的缓存: char *Templates = " "xof 0303txt 0032 \ //标准X文件头。 template CustomTemplate { <4c944580-9e9a-11cf-ab43-0120af71e433> DWORD Length; array DWORD values[Length]; }"; 之后在用RegisterTemplates将其注册: pFile->RegisterTemplates(Templates, strlen(Templates)); 注册标准模版: 首先需要在代码中包含rmxfguid.h和rmxftmpl.h。rmxfguid.h定义了各个标准模版的GUDI,rmxftmpl.h以
2进制数据形式定义了标准模版数据的缓存和其字节数。然后调用RegisterTemplates将其注册: pFile->RegisterTemplates(D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
打开X文件:\\\\\\\\\\\\\\\创建完IDirectXFile接口,注册模版之后需要打开X文件,枚举其数据对象。调用
IDirectXfile::CreateEnumObject函数。 HRESULT IDirectXfile::CreateEnumObject(LPVOID pvSource, // .X filename DXFILELOADOPTIONS dwLoadOptions, // Load options LPDIRECTXFILEENUMOBJECT* ppEnumObj); // Enum interface 当调用CreateEnumObject函数,用pvSource指定一个文件的名字,用ppEnumObj返回一个枚举对象接口指
针。用dwLoadOptions指定load操作方式。当指定DXFILELOAD_FROMFILE值,告诉DirectX从磁盘载入一个
文件。还有DXFILELOAD_FROMRESOURCE,DXFILELOAD_FROMMEMORY和DXFILELOAD_FROMURL分别表示从一个资
源,内存缓冲和Internet上加载X文件。当从Internet加载文件时,需要为其指定完整的网址。 下面代码从磁盘加载X文件: // Filename = filename to load ("test.x" for example) IDirectXFileEnumObject *pEnum; pFile->CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pEnum); Filename指向一个有效的文件名,pEnum返回一个枚举对象接口指针。 |