一、建立空窗體
新建一個工程,添加引用,並導入名稱空間。
加入一個設備對象變量:
private Microsoft.DirectX.Direct3D.Device device = null;
添加初始化圖形函數,並在這裡面對設備對象進行實例化:
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);
}當程序執行時,需要繪制場景,代碼在這個函數裡:
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();
}設置照相機的位置:
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));
}現在改變主函數,調用我們寫的初始化函數,並顯示場景:
[STAThread]
static void Main()
{
using (Form1 EarthForm = new Form1())
{
EarthForm.InitializeGraphics();
EarthForm.Show();
while(EarthForm.Created)
{
EarthForm.Render();
Application.DoEvents();
}
EarthForm.Dispose();
}運行程序,會顯示一個空的窗體。
二、加入地球:
在這一步裡需創建一個3D網格對象,來作為要顯示的地球,為此,在工程中新加入一個類Earth,此類可以包含所創建的網格對象的信息。
加入一些相關變量,含義見注釋:
public class Earth : BaseEarth
{
private Material[] mMaterials; //保存材質
private Texture[] mTextures; //保存紋理
private Matrix locationOffset; //用來保存網格對象的相對位置
private Mesh mMesh = null; //三角形網格對象
private Device meshDevice; //需要顯示在哪個設備上。
}在構造函數中,把Device設備拷貝到私有成員變量,這樣就可以在這個類的其它方法內使用它,另外就是把位置變量進行賦值:
public Earth(ref Device device, Matrix location): base(ref device)
{
meshDevice = device;
locationOffset = location;
}下面這個函數是裝入.X文件。
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;
}
}在這個方法內,使用Mesh.FromFile()這個方法,從給定的文件名中找到.X文件,並裝入相關數據,一旦數據格式設置完成,可以從此文件中找到材質和貼圖信息,並把它存放在數組中,並通過文件路徑,得到紋理文件文件的路徑,最後返回真值,如果整個過程出現錯誤,返回假值。