一、建立空窗體
新建一個工程,添加引用,並導入名稱空間。
加入一個設備對象變量:
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文件,並裝入相關數據,一旦數據格式設置完成,可以從此文件中找到材質和貼圖信息,並把它存放在數組中,並通過文件路徑,得到紋理文件文件的路徑,最後返回真值,如果整個過程出現錯誤,返回假值。