** DirectX9 3D ** ** 快速上手 ** ** 8
**
By sssa2000
5/4/2005
**
**
上一次中途结束了本来应该讲到的控制 Mesh 的细节程度的方法的,这一次补上。
我们这里使用的是简单的方法,并没有涉及到场景剔出等等复杂的方法,我这里主要还是用 DX9 提供给我们的类库, progressive meshe 。
progressive meshes 主要的优点就是允许我们控制顶点和面的数目,这样我们就可以灵活的控制 mesh 细节的显示程度。
和 Mesh 一样, progressive meshe 也都是继承自 BaseMesh 这个类。比较重要的属性主要有 2 个 NumberFaces 和 NumberVertices 。从字面我们就可以看出两个属性的含义。
有了前面的基础在使用 progressive mesh 上也变得十分的简单,首先我们需要声明一个 progressive mesh 的变量,然后我们看看 progressive mesh 的构造函数:
public ProgressiveMesh (
Mesh mesh ,
GraphicsStream adjacency ,
GraphicsStream vertexWeights , // 顶点的权值,越高越不容易被剔出,如果设为 null 就全部被设为 1
int minValue , // 设定被简化的最小值
MeshFlags options
);
以下就是核心的代码:
private void LoadMesh(string file)
{
ExtendedMaterial[] mtrl;
GraphicsStream adj;
// Load our mesh
using(Mesh mesh = Mesh.FromFile(file, MeshFlags.Managed, device,
out adj, out mtrl))
{
// If we have any materials, store them
if ((mtrl != null) && (mtrl.Length > 0))
{
meshMaterials = new Material[mtrl.Length];
meshTextures = new Texture[mtrl.Length];
// Store each material and texture
for (int i = 0; i < mtrl.Length; i++)
{
meshMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) &&
(mtrl[i].TextureFilename != string.Empty))
{
// We have a texture, try to load it
meshTextures[i] = TextureLoader.FromFile(device,
@"..\..\" + mtrl[i].TextureFilename);
}
}
}
// Clean our main mesh
using(Mesh tempMesh = Mesh.Clean(mesh, adj, adj))
{
// Create our progressive mesh
progressiveMesh = new ProgressiveMesh(tempMesh, adj,
null, 1, MeshFlags.SimplifyVertex);
// Set the initial mesh to the max
progressiveMesh.NumberFaces = progressiveMesh.MaxFaces;
progressiveMesh.NumberVertices = progressiveMesh.MaxVertices;
}
}
}
其实这里大部分代码和前面的关于 Mesh 那一节的代码差不多,关于 progressiveMesh ,微软的 SDK 也有一个例子,不过那个例子太过于庞大,大部分都是在处理 UI 方面,真正涉及到 progressiveMesh 的部分还是很少的。
以下是代码的事例图和完整代码:
这个例子里可以切换线框渲染模式和实体作色模式。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace progressiveMesh
{
///
1<summary>
2
3/// Summary description for Form1.
4
5/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Device device = null ;
private ProgressiveMesh progressiveMesh = null ;
private Material[] meshMaterials;
private Texture[] meshTextures;
private Microsoft.DirectX.Direct3D.Font font = null ;
private float cameraPos = 8.0f;
private const int MoveAmount = 2;
///
1<summary>
2
3/// Required designer variable.
4
5/// </summary>
private System.ComponentModel.Container components = null ;
private float angle = 0.0f;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this .SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true );
}
///
1<summary>
2
3/// We will initialize our graphics device here
4
5/// </summary>
public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true ;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true ;
// Create our device
device = new Device(0, DeviceType.Hardware, this , CreateFlags.SoftwareVertexProcessing, presentParams);
// Load our mesh
LoadMesh(@"..\..\SprintRacer.x");
// Create our font
font = new Microsoft.DirectX.Direct3D.Font(device, new System.Drawing.Font
("Arial", 14.0f, FontStyle.Bold | FontStyle.Italic));
}
private void LoadMesh( string file)
{
ExtendedMaterial[] mtrl;
GraphicsStream adj;
// Load our mesh
using (Mesh mesh = Mesh.FromFile(file, MeshFlags.Managed, device,
out adj, out mtrl))
{
// If we have any materials, store them
if ((mtrl != null ) && (mtrl.Length > 0))
{
<span style="ms