建立自己的3D模型文件的目的和意义我就不罗嗦了。有一些方法可以实现这个目的,我使用了D3DSDK(2004summer)版本达到了这个目的,我的方法和思路如下:
1)将.x档用D3DX的各个函数读出,需要读出的有Frame,FrameTransformMatrix,Mesh,AnimationSet,Animation,AnimationKey;
2)转化为自己需要的文件,这里我建立了4个文件,包括.m档(存放mesh),.f档(存放Frame),.a档(存放AnimationSet)和.z档,存放上面3个文件的索引。这4个文件都可以修改部分属性,以达到共享texture、animation等目的。
3)完成读这4个文档的代码,并建立相应的列表、树什么的
4)Render读出的模型
.m档格式如下(最复杂的就是这个档案):
Mesh个数
{//循环,Mesh个数
Name
NumMaterials
{//循环,NumMaterials个数
MatD3D
TextureFilename
}
FVF
NumFaces
NumVertices
NumBytesPerVertex
true/false //指明是否有SkinInfo
{
NumBones
{//NumBones
BoneName
NumBoneInfluences
vertices
weights
BoneOffsetMatrix
}
}
VertexBufferSize
VertexBuffer
IndexBufferSize
IndexBuffer
.f档保存的是二叉树,文件格式不是很好描述,但是将Frame的二叉树结构和TransformationMatrix写入就可以了。
.a档格式如下:
AnimationSet数量
{//循环
Name
Length
Animation数量
{//循环
Animation名字
TranslationKeys //每一个key都包含时间和转换key
ScaleKeys
RotationKeys
MatrixKeys
}
}
首先要做的事情就是读.x档,伪代码如下:
D3DXFileCreate
RegisterTemplates( D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES )//变量在rmxfguid.h中有声明
CreateEnumObject如果使用了UINCODE,第二个参数改成D3DXF_FILELOAD_FROMWFILE
pD3DXEnum->GetChildren( &dwDatas );
for( DWORD dw = 0; dw < dwDatas; dw ++ ) {
pD3DXEnum->GetChild( dw, &pD3DXData );
ParseObject( pD3DXData );
}
ParseObject(ID3DXFileData *pDataObj)
{
pDataObj->GetType( &Type );
if( Type == Frame ) {
// do something
}
else if( ... ) { ... }
}
ParseObject中有可能还有LoadMesh,这时候不用CreateTexture,只把Texture的文件名保存就可以了。Load完成之后别忘了将Mesh优化(OptimizeInplace)一下,使用D3DXMESHOPT_ATTRSORT参数。
由于文件的格式已经给出,其它的代码其实就是文件的读写,这里就不罗嗦了。Render部分的代码不怎么复杂,就是DrawIndexedPrimitive函数,这里也不罗嗦了。
1)将.x档用D3DX的各个函数读出,需要读出的有Frame,FrameTransformMatrix,Mesh,AnimationSet,Animation,AnimationKey;
2)转化为自己需要的文件,这里我建立了4个文件,包括.m档(存放mesh),.f档(存放Frame),.a档(存放AnimationSet)和.z档,存放上面3个文件的索引。这4个文件都可以修改部分属性,以达到共享texture、animation等目的。
3)完成读这4个文档的代码,并建立相应的列表、树什么的
4)Render读出的模型
.m档格式如下(最复杂的就是这个档案):
Mesh个数
{//循环,Mesh个数
Name
NumMaterials
{//循环,NumMaterials个数
MatD3D
TextureFilename
}
FVF
NumFaces
NumVertices
NumBytesPerVertex
true/false //指明是否有SkinInfo
{
NumBones
{//NumBones
BoneName
NumBoneInfluences
vertices
weights
BoneOffsetMatrix
}
}
VertexBufferSize
VertexBuffer
IndexBufferSize
IndexBuffer
.f档保存的是二叉树,文件格式不是很好描述,但是将Frame的二叉树结构和TransformationMatrix写入就可以了。
.a档格式如下:
AnimationSet数量
{//循环
Name
Length
Animation数量
{//循环
Animation名字
TranslationKeys //每一个key都包含时间和转换key
ScaleKeys
RotationKeys
MatrixKeys
}
}
首先要做的事情就是读.x档,伪代码如下:
D3DXFileCreate
RegisterTemplates( D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES )//变量在rmxfguid.h中有声明
CreateEnumObject如果使用了UINCODE,第二个参数改成D3DXF_FILELOAD_FROMWFILE
pD3DXEnum->GetChildren( &dwDatas );
for( DWORD dw = 0; dw < dwDatas; dw ++ ) {
pD3DXEnum->GetChild( dw, &pD3DXData );
ParseObject( pD3DXData );
}
ParseObject(ID3DXFileData *pDataObj)
{
pDataObj->GetType( &Type );
if( Type == Frame ) {
// do something
}
else if( ... ) { ... }
}
ParseObject中有可能还有LoadMesh,这时候不用CreateTexture,只把Texture的文件名保存就可以了。Load完成之后别忘了将Mesh优化(OptimizeInplace)一下,使用D3DXMESHOPT_ATTRSORT参数。
由于文件的格式已经给出,其它的代码其实就是文件的读写,这里就不罗嗦了。Render部分的代码不怎么复杂,就是DrawIndexedPrimitive函数,这里也不罗嗦了。