3D模型(.x)
2D游戏中的精灵和建筑的都是美术们预先画好的图片,那么3D中是什么呢?答案是‘模型’,是3DMAX或是MAYA做出来3D模型,模型中存储了顶点的位置、面的组成、顶点的纹理坐标、材质和贴图等等我们需要的信息。一般的3D游戏都有自己的模型格式,D3D也有一种模型格式,那就是.x文件。 D3D已经为我们做好.x文件的支持,所以使用起来非常的方便,只需要简单的几条函数就可以把一个模型渲染出来了。如果
·
2D游戏中的精灵和建筑的都是美术们预先画好的图片,那么3D中是什么呢?答案是‘模型’,是3DMAX或是MAYA做出来3D模型,模型中存储了顶点的位置、面的组成、顶点的纹理坐标、材质和贴图等等我们需要的信息。一般的3D游戏都有自己的模型格式,D3D也有一种模型格式,那就是.x文件。
D3D已经为我们做好.x文件的支持,所以使用起来非常的方便,只需要简单的几条函数就可以把一个模型渲染出来了。如果你不去写3D导出插件,那么我们可能永远也不需要了解.x的文件格式,但是我们必须了解.x是怎么做出来的:
1、 在3DMAX中建立模型。
2、 导出为*.3ds格式。
3、 使用D3D提供的conv3ds.exe工具就可以把*.3ds格式的文件转化成.x文件。
(conv3ds.exe在Dx8sdk中有提供,在本回的例子程序包中也有一份^_^)
OK,现在.x文件也有了,开始写程序吧。
先要使用D3D给我们提供的模型接口定义一个模型的指针出来。
LPD3DXMESH g_pMesh = NULL; // 模型对象指针
D3DMATERIAL8* g_pMeshMaterials = NULL; // 模型的材质数组(一个模型可以有多个材质)
LPDIRECT3DTEXTURE8* g_pMeshTextures = NULL; // 模型的纹理数组(一个模型可以有多个纹理)
DWORD g_dwNumMaterials = 0L; // 材质的数量(等于纹理数量)
一、 接着就是从.x文件读入我们的模型。
// 材质缓冲
LPD3DXBUFFER pD3DXMtrlBuffer;
// 读入tiger.x到我们的模型
if( FAILED( D3DXLoadMeshFromX(
"Tiger.x", // [输入].x文件名
D3DXMESH_SYSTEMMEM, // [输入]使用系统内存
g_pd3dDevice, // [输入]d3d设备指针
NULL, // 不用管
&pD3DXMtrlBuffer, // [输出]获取模型的材质缓冲
&g_dwNumMaterials, // [输出]材质的数量
&g_pMesh ) ) ) // [输出]模型对象指针
{
return E_FAIL;
}
三、遗憾的是D3DXMESH并没有为什么提供模型的材质和纹理管理,所以必须自己做这件事情。
// 获取材质指针
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer-> GetBufferPointer();
g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];
g_pMeshTextures = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];
for( DWORD i=0; i<g_dwNumMaterials; i++ )
{
// 把需要的材质拷贝到我们的材质对象中
g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
// 为材质设置环境色
g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
// 创建对应的纹理
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,
d3dxMaterials[i].pTextureFilename,
&g_pMeshTextures[i] ) ) )
{
g_pMeshTextures[i] = NULL;
}
}
// 释放缓冲
pD3DXMtrlBuffer->Release();
四、一切准备就绪,渲染吧。要注意,在.x文件被读入时,模型是被切分了的,每一个材质对应一部分的模型。
// 根据材质的数量我们的模型被切分了,每个材质对应一部分
// 所以渲染的时候也要分几个部分渲染
for( DWORD i=0; i<g_dwNumMaterials; i++ )
{
// 为这一部分设置材质
g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
// 渲染这一部分
g_pMesh->DrawSubset( i );
}
很快,程序运行的结果也出来了:
一切都弄好了,是不是感到不可思议的简单?我也是这样认为,不过实际上很少看到有商业的游戏直接使用.x文件,大多数都是自己写插件,我也写过一个,不过对于大家入门来 说, .x 已经足够了。没有必要所有人都去写游戏引擎吧,你说对不对?了解3D的基本实现原理后,我想以后你去做真正的3D游戏时,心里就不会一点底都没有了。
D3D已经为我们做好.x文件的支持,所以使用起来非常的方便,只需要简单的几条函数就可以把一个模型渲染出来了。如果你不去写3D导出插件,那么我们可能永远也不需要了解.x的文件格式,但是我们必须了解.x是怎么做出来的:
1、 在3DMAX中建立模型。
2、 导出为*.3ds格式。
3、 使用D3D提供的conv3ds.exe工具就可以把*.3ds格式的文件转化成.x文件。
(conv3ds.exe在Dx8sdk中有提供,在本回的例子程序包中也有一份^_^)
OK,现在.x文件也有了,开始写程序吧。
先要使用D3D给我们提供的模型接口定义一个模型的指针出来。
LPD3DXMESH g_pMesh = NULL; // 模型对象指针
D3DMATERIAL8* g_pMeshMaterials = NULL; // 模型的材质数组(一个模型可以有多个材质)
LPDIRECT3DTEXTURE8* g_pMeshTextures = NULL; // 模型的纹理数组(一个模型可以有多个纹理)
DWORD g_dwNumMaterials = 0L; // 材质的数量(等于纹理数量)
一、 接着就是从.x文件读入我们的模型。
// 材质缓冲
LPD3DXBUFFER pD3DXMtrlBuffer;
// 读入tiger.x到我们的模型
if( FAILED( D3DXLoadMeshFromX(
"Tiger.x", // [输入].x文件名
D3DXMESH_SYSTEMMEM, // [输入]使用系统内存
g_pd3dDevice, // [输入]d3d设备指针
NULL, // 不用管
&pD3DXMtrlBuffer, // [输出]获取模型的材质缓冲
&g_dwNumMaterials, // [输出]材质的数量
&g_pMesh ) ) ) // [输出]模型对象指针
{
return E_FAIL;
}
三、遗憾的是D3DXMESH并没有为什么提供模型的材质和纹理管理,所以必须自己做这件事情。
// 获取材质指针
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer-> GetBufferPointer();
g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];
g_pMeshTextures = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];
for( DWORD i=0; i<g_dwNumMaterials; i++ )
{
// 把需要的材质拷贝到我们的材质对象中
g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
// 为材质设置环境色
g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
// 创建对应的纹理
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,
d3dxMaterials[i].pTextureFilename,
&g_pMeshTextures[i] ) ) )
{
g_pMeshTextures[i] = NULL;
}
}
// 释放缓冲
pD3DXMtrlBuffer->Release();
四、一切准备就绪,渲染吧。要注意,在.x文件被读入时,模型是被切分了的,每一个材质对应一部分的模型。
// 根据材质的数量我们的模型被切分了,每个材质对应一部分
// 所以渲染的时候也要分几个部分渲染
for( DWORD i=0; i<g_dwNumMaterials; i++ )
{
// 为这一部分设置材质
g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
// 渲染这一部分
g_pMesh->DrawSubset( i );
}
很快,程序运行的结果也出来了:

一切都弄好了,是不是感到不可思议的简单?我也是这样认为,不过实际上很少看到有商业的游戏直接使用.x文件,大多数都是自己写插件,我也写过一个,不过对于大家入门来 说, .x 已经足够了。没有必要所有人都去写游戏引擎吧,你说对不对?了解3D的基本实现原理后,我想以后你去做真正的3D游戏时,心里就不会一点底都没有了。
更多推荐
所有评论(0)