Direct3D中使用网格模型的实现方法

来源:互联网 发布:竞彩足球对阵数据 编辑:程序博客网 时间:2024/05/24 06:49
   Complicated geometry is usually modeled using 3-D modeling software and saved to a file. An example of this is the .x file format. Microsoft? Direct3D? uses meshes to load the objects from these files. Meshes are somewhat complicated, but Microsoft? Direct3DX contains functions that make using meshes easier. The Meshes sample project introduces the topic of meshes and shows how to load, render, and unload a mesh.

  复杂的几何模型通常是由3D建模软体创建并保存到文件中。例如.x文件就是这样的一种格式,Microsoft Direct3D使用的网格模型都是载入这些文件中的对象。即使模型有些复杂,但在Microsoft Direct3D中包含的函式建立使用它是非常容易,本例子就是介绍网格模型如何从载入渲染得到我们所需的效果,并且如何对其进行释放。

  This tutorial shows how to load, render, and unload a mesh using the following steps.

  这个指南展示如何载入、渲染、并释放一个网格模型所需要的步骤:

  Step 1: Loading a Mesh Object

  第一步:载入一个网格模型对象

  A Microsoft? Direct3D? application must first load a mesh before using it. The Meshes sample project loads the tiger mesh by calling InitGeometry, an application-defined function, after loading the required Direct3D objects.

  一个Microsoft Direct3D的应用程式在使用网格模型对象之前必须进行初始化,本例中,调用InitGeometry函式用于载入一个老虎的网格模型,这是一个应用程式定义的函式,在载入必要的Direct3D对象(系统初始化)后调用。

  A mesh needs a material buffer that will store all the materials and textures that will be used. The function starts by declaring a material buffer as shown in the following code fragment.

  一个网格模型需要材质缓冲,将存储要使用的材质以及纹理。函式开始先声明一个材质缓冲如同以下的代码片段:

  LPD3DXBUFFER pD3DXMtrlBuffer;

  The following code fragment uses the D3DXLoadMeshFromX method to load the mesh.

  下面这部分使用D3DXLoadMeshFromX的方法来载入网格模型。

  // 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;

  The first parameter that D3DXLoadMeshFromX accepts is a pointer to a string that tells the name of the Microsoft DirectX? file to load. This sample loads the tiger mesh from Tiger.x.

  第一个参数D3DXLoadMeshFromX 从一个指向字符串的指针获得需要Microsoft DirectX载入的文件名,本例中从Tiger.x文件中载入老虎模型。

  The second parameter tells Direct3D how to create the mesh. The sample uses the D3DXMESH_SYSTEMMEM flag, which is equivalent to specifying both D3DXMESH_VB_SYSTEMMEM and D3DXMESH_IB_SYSTEMMEM. Both of these flags tell Direct3D to put the index buffer and vertex buffer for the mesh in system memory.

  第二个参数告诉Direct3D如何创建网格模型。本例使用D3DXMESH_SYSTEMMEM标记,哪相当于指定了D3DXMESH_VB_SYSTEMMEMD3DXMESH_IB_SYSTEMMEM这两个。这两个标记告诉Direct3D将网格模型的索引缓冲(index buffer)和顶点缓冲(vertex buffer)存放于系统存储器。

  The third parameter is a pointer to a Direct3D device that will be used to render the mesh.

  第三个参数是一个指针,指向Direct3D设备,这也是将用于模型渲染。

  The fourth parameter is a pointer to an ID3DXBuffer object. This object will be filled with information about neighbors for each face. This information is not required for this sample, so this parameter is set to NULL.

  第四个参数是指向一个ID3DXBuffer对象的指针,这个对象将填满关于相邻每一个面的信息。这个信息在本例中并不需要,因此此参数设置为NULL

  The fifth parameter also takes a pointer to a ID3DXBuffer object. After this method is finished, this object will be filled with D3DXMATERIAL structures for the mesh.

  第五个参数也同样指向一个ID3DXBuffer对象,在这个函式完成之后,这个对象将填满模型的D3DXMATERIAL结构数据。

  The sixth parameter is a pointer to the number of D3DXMATERIAL structures placed into the ppMaterials array after the method returns.

  第六个参数指向一个整形变量,当函式返回时保存D3DXMATERIAL结构的数量于ppMaterials列队中。

  The seventh parameter is the address of a pointer to a mesh object, representing the loaded mesh.

  第七个参数返回一个指向网格模型对象的地址,返回所载入的模型数据。

  After loading the mesh object and material information, you need to extract the material properties and texture names from the material buffer.

  在载入模型对象和材质信息后,你需要从材质缓冲中筛选出材质属性和纹理名称。

  The Meshes sample project does this by first getting the pointer to the material buffer. The following code fragment uses the ID3DXBuffer::GetBufferPointer method to get this pointer.

  这是本例工程所做的第一步,取得指向材质缓冲,下面部分代码展示了如何通过ID3DXBuffer::GetBufferPointer函式来取得指针数据。

  D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();

  The following code fragment creates new mesh and texture objects based on the total number of materials for the mesh.

  下面的代码片段创建新的模型和根据材质中模型所统计的纹理对象。

  g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];

  g_pMeshTextures = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];

  For each material in the mesh the following steps occur.

  为模型中每一个材质执行下面的步骤。

  The first step is to copy the material, as shown in the following code fragment.

  第一步,拷贝材质,代码如下:

  g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

  The second step is to set the ambient color for the material, as shown in the following code fragment.

  第二步,为材质设置环境颜色,代码如下:

  g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

  The final step is to create the texture for the material, as shown in the following code fragment.

  最后一步,为材质创建纹理贴图,代码如下:

  // Create the texture.

  if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,

  d3dxMaterials[i].pTextureFilename,

  &g_pMeshTextures[i] ) ) )

  g_pMeshTextures[i] = NULL;

  }

  After loading each material, you are finished with the material buffer and need to release it by calling IUnknown::Release.

  在载入每一个材质之后,你完成材质缓冲并需要释放它调用IUnknown::Release

  pD3DXMtrlBuffer->Release();

  The mesh, along with the corresponding materials and textures are loaded. The mesh is ready to be rendered to the display, as described in Step 2: Rendering a Mesh Object.

  模型连同相应的材质和纹理都已载入,模型已经准备好用于显示渲染,接下来我们看看第二步:渲染一个模型对象。

  Step 2: Rendering a Mesh Object

  第二步:渲染一个网格模型对象

  In step 1 the mesh was loaded and is now ready to be rendered. It is divided into a subset for each material that was loaded for the mesh. To render each subset, the mesh is rendered in a loop. The first step in the loop is to set the material for the subset, as shown in the following code agment.

  在第一步里,模型已经载入并准备好用于渲染,模型载入后,它是以每一个材质分开存放在一个子集中,需要对每个子集进行渲染,模型是在一个循环中渲染。第一步,在循环里为子集设置材质,参看下面代码片段:

  g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );

  The second step in the loop is to set the texture for the subset, as shown in the following code fragment.

  第二步,在循环里为子集设置纹理,参看下面代码片段:

  g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
原创粉丝点击