技术文章 > C#+DIRECT3D9.0开发实例之月亮绕着地球转

C#+DIRECT3D9.0开发实例之月亮绕着地球转

2020-07-04 00:39

文档管理软件,文档管理系统,知识管理系统,档案管理系统的技术资料:

一、建立空窗体

新建一个工程,添加引用,并导入名称空间。

加入一个设备对象变量:

private Microsoft.DirectX.Direct3D.Device device = null;

添加初始化图形函数,并在这里面对设备对象进行实例化:
[code]
csharp
public void InitializeGraphics()
{
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Flip;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, presentParams);
}
[/code]
当程序执行时,需要绘制场景,代码在这个函数里:
[code]
csharp
public void Render()
{
// 清空设备,并准备显示下一帧。
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black , 1.0f, 0);
// 设置照相机的位置
SetupCamera();
//开始场景
device.BeginScene();
if(meshLoaded)
{
mesh.Render(meshLoc);
}
device.EndScene();
//显示设备内容。
device.Present();
}
[/code]
设置照相机的位置:
[code]
csharp
private void SetupCamera()
{
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 1000.00f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f ,0.0f, 20.0f), new Vector3(0.0f,0.0f, 0.0f), new Vector3(0,1,0));
}
[/code]
现在改变主函数,调用我们写的初始化函数,并显示场景:
[code]
csharp
[STAThread]

static void Main()
{
using (Form1 EarthForm = new Form1())
{
EarthForm.InitializeGraphics();
EarthForm.Show();

while(EarthForm.Created)
{
EarthForm.Render();
Application.DoEvents();
}
EarthForm.Dispose();
}
[/code]
运行程序,会显示一个空的窗体。

二、加入地球:

在这一步里需创建一个3D网格对象,来作为要显示的地球,为此,在工程中新加入一个类Earth,此类可以包含所创建的网格对象的信息。

加入一些相关变量,含义见注释:
[code]
csharp
public class Earth : BaseEarth
{
private Material[] mMaterials; //保存材质
private Texture[] mTextures; //保存纹理
private Matrix locationOffset; //用来保存网格对象的相对位置
private Mesh mMesh = null; //三角形网格对象
private Device meshDevice; //需要显示在哪个设备上。
}
[/code]
在构造函数中,把Device设备拷贝到私有成员变量,这样就可以在这个类的其它方法内使用它,另外就是把位置变量进行赋值:
[code]
csharp
public Earth(ref Device device, Matrix location): base(ref device)
{
meshDevice = device;
locationOffset = location;
}
[/code]
下面这个函数是装入.X文件。
[code]
csharp
public bool LoadMesh(string meshfile)
{
ExtendedMaterial[] mtrl;
try
{
// 装载文件
mMesh = Mesh.FromFile(meshfile, MeshFlags.Managed, meshDevice, out mtrl);
// 如果有材质的话,装入它们
if ((mtrl != null) && (mtrl.Length > 0))
{
mMaterials = new Material[mtrl.Length];
mTextures = new Texture[mtrl.Length];

// 得到材质和纹理

for (int i = 0; i < mtrl.Length; i++)
{
mMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
{
//前面得到的纹理的路径是相对路径,需要保存的是绝对路径,通过应用程序路径可以获得
mTextures[i] = TextureLoader.FromFile(meshDevice, @“..\..\“ + mtrl[i].TextureFilename);
}
}
}
return true;
}
catch
{
return false;
}
}
[/code]
在这个方法内,使用Mesh.FromFile()这个方法,从给定的文件名中找到.X文件,并装入相关数据,一旦数据格式设置完成,可以从此文件中找到材质和贴图信息,并把它存放在数组中,并通过文件路径,得到纹理文件文件的路径,最后返回真值,如果整个过程出现错误,返回假值。

下面这个Render()方法,是把此对象,即地球显示在设备对象上,此方法较简单,通过变形操作来得到网格对象的X,Y,Z坐标,接着设置网格对象的材质和纹理,最后,将每个材质和纹理应用到每个网格。
[code]
csharp
public void Render(Matrix worldTransform)
{
/把位置变为世界坐标
meshDevice.Transform.World = Matrix.Multiply(locationOffset, worldTransform);
//绘制网格
for (int i = 0; i < mMaterials.Length; i++)
{
meshDevice.Material = mMaterials[i];
meshDevice.SetTexture(0, mTextures[i]);
mMesh.DrawSubset(i);
}
}
[/code]
现在回到窗体代码中,添加引用网格对象的相关变量:
[code]
csharp
private Earth mesh = null;
private Matrix meshLoc;
private bool meshLoaded = false;
[/code]
在图形初始化函数中,需要对网格对象进行初始化。加入下面的代码:
[code]
csharp
meshLoc = Matrix.Identity;
meshLoc.M41 = 2.0f;
mesh = new Earth(ref device, meshLoc);
if (mesh.LoadMesh(@“..\..\earth.x“))
{
meshLoaded = true;
}
[/code]
代码第一句把网格对象的位置定为原点,接着偏移X轴2个单位,接下来从文件中得到此.X文件。如果成功设置,meshLoaded置为真。注意,这里有一个.X文件,在源代码中有此文件。

在设置相机的函数中,加入一盏灯光:
[code]
csharp
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Direction = new Vector3(0, -1, -1);
device.Lights[0].Update();
device.Lights[0].Enabled = true;
[/code]
此灯光较简单,仅为一个直射型白光灯。

最后,在Render()方法中,调用网格对象的Render()方法,以显示地球。

[img]http://image.21tx.com/image/20051025/32798.jpg[/img]