三维游戏模型的导入

时间:2021-04-22 16:29:26

老爹,你最辉煌的时刻是何时?

是全日本时代吗?

而我...

就是现在了!

 

    在direct3D中,一般采用.X文件来储存网格数据。.X文件是微软定义的3D模式文件格式,其中包括网格的纹理、动画以及用户定义对象的一些数据等。.X文件通常并未储存具体的纹理数据,它只包含纹理贴图的文件名,所以,我们常常会发现,X文件会和一些图片文件放在一起。

    在3ds  MAX中,可以下载使用panda插件来导出.X格式的文件。

     用ID3DXMesh接口中的D3DXCreateMesh()克用于创建一个Direct3D网格模型对象。

1  HRESULT  D3DXCreateMesh(
2   __in   DWORD NumFaces,
3   __in   DWORD NumVertices,
4   __in   DWORD Options,
5   __in   const LPD3DVERTEXELEMENT9 *pDeclaration,
6   __in   LPDIRECT3DDEVICE9 pD3DDevice,
7   __out  LPD3DXMESH *ppMesh
8 );

文件模型载入3步

1通过X文件载入网格模型

 HRESULT  D3DXLoadMeshFromX(
  __in   LPCTSTR pFilename,    //指向我们加载的.X文件的磁盘路径和文件名的字符串
  __in   DWORD Options,//表示创建网格时的附加选项
  __in   LPDIRECT3DDEVICE9 pD3DDevice,//direct3d设备的指针
  __out  LPD3DXBUFFER *ppAdjacency,//用于保存加载网格的邻接信息,也就是包含每个多边形周围的多边形信息的缓冲区的内存地址
  __out  LPD3DXBUFFER *ppMaterials,//用于保存网格的所有子集的材质
  __out  LPD3DXBUFFER *ppEffectInstances,//用于储存网格模型的特殊效果,通常设置为null
  __out  DWORD *pNumMaterials,//用于储存所有子集的材质的数目
  __out  LPD3DXMESH *ppMesh//指向从文件生产的direct3d网格模型指针的地址  
);

  

2载入文理和材质

当我们加载x文件之后,需要遍历整个D3DXMETERIAL结构类型的数组,用于取出保存早ID3DXBuffer接口对象中的材质信息。由于X文件中并未储存具体的文理数据,它只包含纹理贴图的文件名,因此需要我们自己根据该文件名创建对应的纹理对象。

 1     // 从X文件中加载网格数据
 2     LPD3DXBUFFER pAdjBuffer  = NULL;
 3     LPD3DXBUFFER pMtrlBuffer = NULL;
 4 
 5     D3DXLoadMeshFromX(L"miki.X", D3DXMESH_MANAGED, g_pd3dDevice, 
 6         &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
 7 
 8     // 读取材质和纹理数据
 9     D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer(); //创建一个D3DXMATERIAL结构体用于读取材质和纹理信息
10     g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
11     g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];
12 
13     for (DWORD i=0; i<g_dwNumMtrls; i++) 
14     {
15         //获取材质,并设置一下环境光的颜色值
16         g_pMaterials[i] = pMtrls[i].MatD3D;
17         g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
18 
19         //创建一下纹理对象
20         g_pTextures[i]  = NULL;
21         D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
22     }
23 
24     SAFE_RELEASE(pAdjBuffer)
25     SAFE_RELEASE(pMtrlBuffer)

  

3绘制网格模型

用ID3DXMesh接口中的DrawSubset方法绘制网格中的每个子集。由于绘制的地方较多,对于每个部分的绘制,我们需要专门对其进行材质和纹理的设置,然后进行绘制。一般会采用一个for循环绘制

 1 g_pd3dDevice->BeginScene();                     // 开始绘制
 2     
 3             //--------------------------------------------------------------------------------------
 4             // 【Direct3D渲染五步曲之三】:正式绘制
 5             //--------------------------------------------------------------------------------------
 6 
 7     // 用一个for循环,进行网格各个部分的绘制
 8     for (DWORD i = 0; i < g_dwNumMtrls; i++)
 9     {
10         g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
11         g_pd3dDevice->SetTexture(0, g_pTextures[i]);
12         g_pMesh->DrawSubset(i);
13     }