老爹,你最辉煌的时刻是何时?
是全日本时代吗?
而我...
就是现在了!
在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 }