恩,在之前我们所有的复习中,我都是以一个正方形为模型进行渲染演示的,当然,我们的游戏中不可能就几个几何图形在渲染绘制出来,我们也不可能去一个顶点一个顶点的设置我们的人物场景.

那可是要多少个面组成的啊,一般的差点的引擎服务器也能支持700-1000多点人物模型,而优质的引擎服务器通常能够支持2000-4000个点,我们当然可以理解,这些模型都是由3D美术设计师制作之后交由我们使用的。那么模型中包含了什么?我们怎么进行使用呢?接下来某志就这些方面来说明。

首先,模型是一个存储了顶点位置,面的促成,顶点UV坐标,材质,贴图等我们需要信息的文件。通常3D美术设计师现在使用的模型制作工具是3D MAX或MAYA,其中3D MAX默认的导出文件是*.3ds格式。

而在D3D中,也有一个现成的模型格式,那就是*.x格式。

我们可以通过DXSDK中的conv3ds.exe文件将3ds文件转换为.x文件。当然也有相应的插件。

我们使用文本文档或记事本打开我们的.x文件,可以看到其中仅仅一些如下的代码段,之后就全是相关记录的数据了。

template VertexDuplicationIndices {
 <b8d65549-d7c9-4995-89cf-53a9a8b031e3>
 DWORD nIndices;
 DWORD nOriginalVertices;
 array DWORD indices[nIndices];
}

我们很容易可以看出这是一个类似结构的声明,其中包含的仅仅是一些识别号,顶点数据,UV值等信息。而实际上.x文件就是由这些组成的。和我们自己定义的东西其实也没有什么区别。

我们接下来就使用这个文件进行我们的渲染工作,之后就可以获得类似于CS,魔兽一样的人物咯。

不过值得注意的是,由于.x格式结构中,由于存储的东西我们无法自行定义,所以它拥有比较多的冗杂信息,在实际的游戏制作工程中很少直接使用,通常各个公司都会使用相应的插件来对导出文件信息进行控制,而我手头没有这些东西,学习者还是使用默认的.x文件比较方便。

首先,我们需要使用D3D给我们提供的模型接口定义一个模型指针。

LPD3DXMESH g_pMesh                  = NULL;  // 模型对象的指针
D3DMATERIAL8* pD3DXMtrlBuffer       = NULL;  // 模型材质数组指针
LPDIRECT3DTEXTURE8* g_pMeshTextures = NULL;  // 模型纹理数组指针
DWORD g_dwNumMaterials              = 0;     // 模型材质的数量
LPD3DXBUFFER g_MtrlBuffer           = NULL;  // 模型材质的缓冲

值得注意的我们的一个模型可能拥有多块纹理和材质。 相关信息初始化完毕后,我们开始从.x文件读入模型的信息, 我们使用该函数:D3DXLoadMeshFromX 其声明如下:

HRESULT D3DXLoadMeshFromX(        
    LPCTSTR pFilename,  //X文件路径和文件名
    DWORD Options,  //指定生成多边形网格属性
    LPDIRECT3DDEVICE9 pDevice, //Direct3D设备指针
    LPD3DXBUFFER* ppAdjacency, //存储临近多边形信息的内存地址,填NULL即可
    LPD3DXBUFFER* ppMaterials, //存储材质的内存地址
    LPD3DXBUFFER* ppEffectInstances,//存储模型特殊效果的内存地址,一般填NULL即可
    DWORD* pNumMaterials, //存储材质数目的内存地址
    LPD3DXMESH* ppMesh  //存储生成的多边形网格的内存地址
);
if( FAILED( D3DXLoadMeshFromX( "XXX.x",    
   D3DXMESH_SYSTEMMEM,
                     g_pd3dDevice,
                     NULL,
   &pD3DXMtrlBuffer,
                     NULL,
   &g_dwNumMaterials,
                    &g_pMesh ) ) )
     {
         return E_FAIL;
     }