【Directx3D游戏开发】——网格模型(mesh .x)
来源:互联网 发布:日本买房知乎 编辑:程序博客网 时间:2024/05/12 20:47
这次的笔记包含两个内容:1:简单介绍网格模型 和 .x文件;2、优化Mesh模型已取得更高的渲染效率,用Direct3D去加载一个.X文件。
游戏中的场景和角色都非常复杂,想要手工去填充这些模型的每一个顶点几乎是个不可能的事情。一般是用建模工具去完成,然后导出一个程序可以识别的网格模型。最常用的是3DMax,和Maya。
1:.X模型
X格式是微软提供的一种开放的数据存储格式。.X支持自定义模版结构,可以通过它存储自己的任何一种数据,并不一定使我们的模型数据。当然现在要讨论的是.X格式在Direct3D的应用,DirectX的D3DX库提供丰富的支持函数,使得用户可以轻松的使用.X文件。并且.X文件还支持动画。DirectX Viewer 是一个.X文件的查看器,用于查看模型:
唔之艾瑞莉娅:艾欧尼亚不会灭亡。
.X文件可以用文本格式存储,可以用记事本打开一看究竟,详细参考《Direct3D 游戏看法详解 》,同样可以采用二进制格式存储,并支持自定义文件结构。
2:D3DX库中一些相关接口
a)、ID3DXMesh 派生自ID3DXBaseMesh,包含了网格(Mesh)模型的集合信息,顶点缓存和索引缓存(描述顶点以何种方式组织成三角形)。相关函数:
//获得顶点缓冲区和索引缓冲区的指针HRESULT ID3DXMesh::GetVertexBuffer( LPDIRECT3DVERTEXBUFFER* ppVB ); HRESULT ID3DXMesh::GetIndexBuffer( LPDIRECT3DVERTEXBUFFER* ppVB );//锁定缓冲区,一遍进行读写操作HRESULT ID3DXMesh::LockVertexBuffer( DWORD Flags, BYTE** ppData );HRESULT ID3DXMesh::LockIndexBuffer( DWORD Flags, BYTE** ppData );//完成了相应操作,必须解锁HRESULT ID3DXMesh::UnlockVertexBuffer();HRESULT ID3DXMesh::UnlockIndexBuffer();//更多获取几何信息的方法DWORD GetFVF(); //返回顶点格式DWORD GetNumVertices() //返回顶点缓存中的定点数DWORD GetNumBytesPerVertex(); //返回每个顶点所占的字节数DWORD GetNumFaces(); //返回网格中(三角形)片面的个数。
3、网格(Mesh)结构
一个网格由一个或多个子集组成。一个子集是网格中一组可用相同属性进行绘制的三角形单元。实行指的是材质,纹理,绘制状态。
为了区分不同子集,给每个子集分配了不同的DWORD类型的ID.这些ID被存放在一个DWORD数组里面,也就是属性缓存。属性缓存的第i行与索引缓存中的第i个三角形单元。
访问索引缓存的接口:
DWORD* buffer = NULL;
Mesh->LockAttributeBuffer( lockFlags, &buffer );//读写操作Mesh->UnlockAttributeBuffer();4、绘制整个网格(mesh)模型
只需要简单的去遍历绘制每一个子集:DrawSubset( i );
for(int i = 0; i < numSubsets;i++){//设置材质纹理Device->SetMaterial( Mtrl[i] );Device->SetTexture( 0, textuer[i] );Mesh->DrawSubset( i );}
5、优化:为了可以更加高效的绘制一个网格,需要对网格中的顶点和索引进行重组。有两个有优化函数,只有微小的区别。
HRESULT ID3DXMesh::OptimizeInplace(DWORD Flags, CONST DWORD* pAdjacencyIn,DWORD* pAdjacencyOut,DWORD* pFaceRemap,LPD3DXBUFFER* ppVertexRemap);HRESULT ID3DXMesh::Optimize(DWORD Flags, CONST DWORD* pAdjacencyIn,DWORD* pAdjacencyOut,DWORD* pFaceRemap,LPD3DXBUFFER* ppVertexRemapLPD3DXMESH* ppOptMesh);
从其中的函数名也可以知道它们之间的差别,OptimizeInplace()就在原Mesh模型上优化,Optimize()是输出一个新的模型,源模型并不会改变。
Flag:优化选项,可以是以下常量的组合
D3DXMESHOPT_COMPACT:从网格中移除那些无用的顶点和索引。
D3DXMESHOPT_ATTSORT:依据属性对个三角形进行排序,并生成一个属性表。这样可使DrawSubset更有效率
D3DXMESHOPT_VERTEXCACHE:提供顶点高速缓存的命中率
D3DXMESHOPT_STRIPORDER:对索引进行重组,以使三角形单元链尽可能长
D3DXMESHOPT_IGNOREVERTS:仅对索引进行优化,忽略顶点。
其中D3DXMESHOPT_VERTEXCACHE不能与D3DXMESHOPT_STRIPORDER同时使用。
pAdjacencyIn:输入的未经优化的链接数组指针
pAdjacencyOut:输出的优化后的链接数组指针,大小为ID3DXMesh::GetNumFaces()*3
6、关于IDXBuffer
这是一个COM接口,一种泛型的数据结构,作用是将数据存储在一个连续的内存块中。相关的两个方法:
LPVOID GetBufferPointer(); 返回缓存中的数据起始指针,需要进行指针类型转换。
DWORD GetBufferSize();返回缓存大小,单位为字节。
7、加载Mesh模型(.x文件)四步曲:
一、重文件中加载数据:
//从文件中加载Mesh模型hr = D3DXLoadMeshFromX( XFILE_NAME, D3DXMESH_MANAGED, g_pD3DDevice,&pAdjacentBuffer, &pMaterialBuffer,0, &numMaterials, &g_pMesh );二、读取模型材质,纹理信息:
if( pMaterialBuffer != NULL && numMaterials != NULL ){//获取缓冲区地址D3DXMATERIAL* pMaterials = ( D3DXMATERIAL* )pMaterialBuffer->GetBufferPointer();//复制材质,和加载纹理for(DWORD i = 0;i < numMaterials; i++){pMaterials[i].MatD3D.Ambient = pMaterials[i].MatD3D.Diffuse;//复制材质用于Render()materials.push_back( pMaterials[i].MatD3D );//从文件中加载纹理if( pMaterials[i].pTextureFilename != NULL){IDirect3DTexture9* tex = NULL;hr = D3DXCreateTextureFromFileA( g_pD3DDevice, pMaterials[i].pTextureFilename,&tex );if( FAILED( hr ) ){MessageBox( 0, L"D3DXCreateTextureFromFile() - FAILED ", 0, MB_OK );return E_FAIL;}textures.push_back( tex );}else{//没有材质textures.push_back( NULL );}}}
三、优化网格:
//优化Meshhr = g_pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT |D3DXMESHOPT_COMPACT |D3DXMESHOPT_VERTEXCACHE,(DWORD*)pAdjacentBuffer->GetBufferPointer(),0, 0, 0 );
四、设置相关变换(代码略)
这里!!!完整代码
圣斗士也有倒下的时候
但至少他为我们制造了无数经典的回忆
——致科比布莱恩特,希望早日回归
- 【Directx3D游戏开发】——网格模型(mesh .x)
- 【Directx3D游戏开发】——Directx3D初始化
- 【Directx3D游戏开发】——简单渲染
- DirectX3D游戏开发五 简单模型创建(索引缓存)
- Unity3D学习笔记——游戏组件之Mesh(网格组件)
- Unity3D学习笔记——组件之Mesh(网格)
- Mesh—合并网格提升性能
- 网格(mesh)简化
- DirectX3D游戏开发一 第一个DirectX3D项目
- 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观
- 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观
- 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观
- DirectX3D游戏开发三 绘制流水线
- Unity3D学习笔记——组件之Mesh(网格) - 有情怀的人
- 使用mesh渲染复杂模型(调用.x 文件)
- Mesh网格篇(一)代码生成圆柱Mesh
- 凸面体网格(convex mesh)
- Mesh网格编程(一) 流体
- ubuntu (LAMP)
- 又是一届校赛进行时
- SSDP
- 数据库分页查询语句
- spring mvc ioc getCurrentSession出错: HibernateException: No Session found
- 【Directx3D游戏开发】——网格模型(mesh .x)
- 查看oracle组件的有效性
- Linux中如何设置服务自启动 FAQ: Ubuntu 12.04 64bit /sbin/insserv: No such file or directory
- android 制作9.png图片
- uboot 命令行联想
- 计算控制文件的大小
- poj1014 &&hdu 1059dividing
- Android Application 创建全局变量
- Mac OS 编译第三方库(续)