Direct3D9 教程05:使用Mesh模型

复杂的几何形状常常使用 3-D 建模软件构造模型并保存为文件。一个例子就是 .x 文件格式。 Microsoft Direct3D 使用 Mesh 对象从文件装载这些物体。 Mesh 对象稍微有点复杂,但是 Microsoft Direct3DX 包含的函数使应用 Mesh 对象变的简单。 Meshed 例程介绍关于 Mesh 的话题并展示如何装载,演示,以及卸载一个 Mesh 对象。
 
本指南使用以下步骤说明如何装载,演示,以及卸载一个 Mesh 对象:
 
·第一步:装载一个 Mesh 对象
·第二步:演示一个 Mesh 对象
·第三步:卸载一个 Mesh 对象
注意: Methes 示例程序的路径为:
(SDK root)/Samples/Multimedia/Direct3D/Tutorials/Tut06_Meshes.
 
注意:除了 Meshes 工程中的示例代码不创建材值与光照以外,此工程的示例代码与 Lights 工程几乎完全一样。“使用 Mesh 模型”指南仅仅关注于有关于 Mesh 对象的独特代码,而并不重复有关设置 Microsoft Direct3D ,处理 Microsoft Windows 消息,演示,或清理的工作。关于这些工作的信息,见:指南一:创建设备
 
本指南使用自定义顶点和顶点缓冲区显示几何物体。关于选择一个自定义顶点格式并执行顶点缓冲的更多信息,见:指南二:演示顶点
 
本指南采用矩阵进行几何变换。关于矩阵和变换的更多信息,参见:指南三:使用矩阵
 
本指南使用纹理覆盖 Mesh 模型的表面。关于装载和使用纹理的更多信息,参见:指南五:使用纹理映射
 
第一步:装载一个Mesh对象
 
在使用之前, Microsoft Direct3D 应用程序必须先装载一个 Mesh 对象。 Meshes 例程通过调用 InitGeometry ,一个该程序自定义的函数,装载一只虎的 Mesh 模型,当然这是在已经装载了必需的 Direct3D 对象以后。
 
一个 Mesh 对象需要用一个材质缓冲保存所有将要用到的材质与纹理。所以该函数最初定义了一个材质缓冲,如以下代码段所示:
 
LPD3DXBUFFER pD3DXMtrlBuffer;
 
以下代码段使用 D3DXLoadMethFromX 函数装载 Mesh 对象。
 
// Load the mesh from the specified file.
if( FAILED( D3DXLoadMeshFromX( "tiger.x", D3DXMESH_SYSTEMMEM,
                               g_pd3dDevice, NULL,
                               &pD3DXMtrlBuffer, &g_dwNumMaterials,
                               &g_pMesh ) ) )
    return E_FAIL;
 
D3DXLoadMeshFromX 接受的第一个参数是一个指向字符串的指针告诉 Microsoft Direct3D 要装载的文件。本例程从 Tiger.x 读取一只虎的 Mesh 模型。
 
第二个参数通知 Direct3D 如何创建 Mesh 对象。本示例采用 D3DXMESH_SYSTEMMEM 标记,它等于同时指定 D3DXMESH_VB_SYSTEMMEM D3DXMESH_IB_SYSTEMMEM ,这两个参数告诉 Direct3D Mesh 对象的索引缓冲区和顶点缓冲区都放到系统内存中。
 
第三个参数是指向将被用于绘制 Mesh 对象的 Direct3D 设备的指针。
 
第四个参数是一个指向 ID3DXBuffer 对象的指针。这个对象装入关于各个面相邻与否的信息。在本例程中此信息是不需要的,所以这个参数被设为 NULL
 
第五个参数同样取得一个指向 ID3DXBuffer 的指针。在函数执行完以后,此对象将被填入该 Mesh 对象使用的 D3DXMATERIAL 结构。
 
第六个参数是一个指针,指向函数执行结束后,返回的置入 ppMaterials 队列中的 D3DXMATERIAL 结构数目。
 
第七个参数是一个 Mesh 对象指针的地址,返回装载的 Mesh 对象。
 
在装载了这个 Mesh 对象和相关材质信息之后,你需要从材质缓冲区中分解出材质属性及纹理名称。
 
Mesh 例程先需要得到材质缓冲区指针才能处理这些事情。以下代码段使用 ID3DXBuffer::GetBufferPointer 函数得到这个指针。
 
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
 
以下代码段创建了一个新的 Mesh 和纹理对象基于 Mesh 对象中材质的最大数目。
 
g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];
g_pMeshTextures = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];
 
对于每个 Mesh 对象里的材质都必须进行以下步骤。
 
第一步是拷贝材质,如以下代码段所示 .
 
g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
 
第二步是设置材值的环境色,见以下代码段。
 
g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
 
最后一步是为该材质创建纹理,如以下代码段。
 
// Create the texture.
if( FAILED( D3DXCreateTextureFromFile(    g_pd3dDevice,
                                       d3dxMaterials[i].pTextureFilename,
                                       &g_pMeshTextures[i] ) ) )
    g_pMeshTextures[i] = NULL;
}
 
装载了每个材质以后,你使用完毕了这个材质缓冲区,必须调用 IUnknown::Release 来释放它。
 
pD3DXMtrlBuffer->Release();
 
现在, Mesh 对象,连同其相应的材质与纹理都已经装载好了。这个 Mesh 物体已准备好呈递到屏幕上,参看 第二步:演示一个 Mesh 对象
 
第二步:演示一个Mesh对象
 
在第一步中, Mesh 对象已经准备号被呈递了。该对象被 Mesh 对象装载的每个材质分成若干个子集。为了绘制每个子集,应该在一个循环中绘制此 Mesh 对象。循环的第一步是为每个子集设置材质,如以下代码段所示:
 
g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
 
循环的第二步是给每个子集设置纹理,如以下代码段所示。
 
g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
 
在给每个子集设置完材质与纹理之后,子集被 ID3DXBaseMesh::DrawSubset 函数所绘制,如以下代码段所示。
 
g_pMesh->DrawSubset( i );
 
DrawSubset 函数带有一个 DWORD 参数用于指定 Mesh 对象的哪个子集被绘制。本例程使这个参数的值每循环一次就被加一。
 
在使用完 Mesh 对象之后,重要的事是要将此 Mesh 对象完全移出内存,参见 第三步:卸载一个 Mesh 对象
 
第三步:卸载一个Mesh对象
 
在任何 Microsoft Direct3D 程序结束前,它有必要解构它使用的所有 DirectX 对象并且使指向它们的指针无效。本例程使用的 Mesh 对象同样需要被解构。当它接收到一个 WM_DESTROY 消息时, Meshes 例程调用 Cleanup ,一个该程序自定义的函数,来处理此事。
 
以下代码段删除材质队列。
 
if( g_pMeshMaterials )
    delete[] g_pMeshMaterials;
 
以下代码解构每个装载过的单独纹理并删除纹理队列。
 
if( g_pMeshTextures )
{
    for( DWORD i = 0; i < g_dwNumMaterials; i++ )
    {
        if( g_pMeshTextures[i] )
            g_pMeshTextures[i]->Release();
    }
delete[] g_pMeshTextures;
 
以下代码段解构 Mesh 对象。
 
Delete the mesh object
if( g_pMesh )
    g_pMesh->Release();
 
本指南已经向你说明了如何装载和绘制 Mesh 对象。这是此区域最后一个指南。如果需要了解一个典型的 Direc3D 应用程序是如何写成的,见: "SDK: DirectX Graphics C/C++ Samples"
 
DirectX 图形接口指南( 1 ~ 7 全文粘贴完毕,Data  2002. 8. 1

 


你可能感兴趣的:(工作,windows,Microsoft,null,delete,Direct3D)