c#開發環境下用Directx載入3D模型__c#

來源:互聯網
上載者:User

         Direcx一般都是用VC++開發環境,而c#相關的資料比較少,最近做的一個項目中需要用到一個3D模型,而開發環境是visual c#,沒辦法,就四處搜集資料,尋找相關的資料,然後找到了幾篇相關的博文,不過這些博文說的都不太仔細,有些內容又丟失了一些關鍵代碼,這個時候就需要我們自己搜集資料,自己學習來補全這些關鍵代碼了。

廢話少說,我們直接說說步驟吧。

.首先要準備一個3D模型,現在3D模型都是.max或者.obj或者別的格式的,不過因為我用的是Directx9.0開發環境,因此載入3D模型的時候需要把檔案轉換為.X格式,沒有關係,我們可以下載一個3dsMax軟體,然後裝上微軟的panda外掛程式,這個軟體就能把.max格式的3d檔案轉換為.x格式輸出。這一步我們最主要的目的就是為了得到一個.x格式的3D模型。

.接下來就是下載Directx9.0Sdk了,下載完成之後安裝這個開發工具。

.接下來進入項目,建立一個Visual c# winform表單程式,然後點擊確定,我們的編程工作就開始了。

          首先,項目需要用到Directx開發包,因此我們需要給項目添加引用,按右鍵項目,選擇添加引用,然後在引用的對話方塊中選擇瀏覽,這裡引用的位置是:C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0,注意最後的應用的檔案夾是1.0.2902.0,我們引用這裡面的三個檔案:DirectX.dll ,DirectX3D.dll 和DirectX3DX.dll,選擇這三項之後點擊確定,之後就添加了引用,然後我們還需要在表單代碼中添加如下引用:

using Microsoft.DirectX;using Microsoft.DirectX.Direct3D; 
之後我們的引用工作算是完成了。

因為我準備把3D模型顯示在一個控制項上,我選擇了一個Panel控制項放到主視窗上,我們的模型待會兒就會顯示在這個panel上。首先在Form中設定如下幾個全域變數:

#region        //儲存3D檔案        private Mesh mesh = null;                //裝置        private Device device = null;        //材質        private Material[] meshMaterials;private Texture[] meshTextures;                 //擷取當前程式的Debug路徑        string path = System.Windows.Forms.Application.StartupPath;                //角度         private float angle = 0.0f; #endregion

然後寫出我們的初始化圖形裝置的函數:

<span style="font-size:14px;">        //初始化圖形裝置        public void InitializeGraphics()        {            //設定變數            PresentParameters presentParams = new PresentParameters();            //設定在視窗模式下運行            presentParams.Windowed = true;            //設定交換效果為Discard            presentParams.SwapEffect = SwapEffect.Discard;            presentParams.AutoDepthStencilFormat = DepthFormat.D16;            presentParams.EnableAutoDepthStencil = true;            //建立裝置            //因為我顯示在panel1中,所以device中的第三個變數是panel的名字            device = new Device(0, DeviceType.Hardware, panel1,                CreateFlags.SoftwareVertexProcessing, presentParams);            //我的3D檔案在Debug中的Model檔案中,因此temp擷取了3D模型的地址            string temp = path;            temp = temp + "\\Model\\Model.X";            //這個函數用於載入3D模型並且儲存在mesh中            LoadMesh(temp);        }</span>

然後是載入3D模型的LoadMesh(string file) 函數

        private void LoadMesh(string file)        {            ExtendedMaterial[] mtrl = null;            //載入            try            {                mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);                //有材質的話,則載入                if ((mtrl != null) && (mtrl.Length > 0))                {                    //這兩個就是前面定義的全域變數,儲存材質和紋理                    meshMaterials = new Material[mtrl.Length];                    meshTextures = new Texture[mtrl.Length];                    for (int i = 0; i < mtrl.Length; ++i)                    {                        /*當前的temp是Debug下的Model檔案,                        *Model檔案中有儲存紋理和材質的檔案                         */                        string temp = path + "\\Model\\";                        meshMaterials[i] = mtrl[i].Material3D;                        if ((mtrl[i].TextureFilename != null)                            && mtrl[i].TextureFilename != string.Empty)                        {                            meshTextures[i] = TextureLoader.FromFile(device, temp + mtrl[i].TextureFilename);                        }                    }                }            }            catch (Direct3DXException ex)            {                MessageBox.Show(ex.ToString());                return;            }        }



載入模型之後就需要將模型畫出來,因此,還需要一個畫模型的函數:

       //繪製mesh的材質和紋理        private void DrawMesh(float yaw, float pitch, float roll, float x, float y, float z)        {            angle += 0.01f;            device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);            for (int i = 0; i < meshMaterials.Length; ++i)            {                //設定材質                device.Material = meshMaterials[i];                //設定紋理                device.SetTexture(0, meshTextures[i]);                //繪製                mesh.DrawSubset(i);            }        }

最後還差一個攝影燈光的設定了,這個用於燈光的角度:

        //設定網路攝影機        private void SetupCamera()        {            //(float)Math.PI/12設定對象大小            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 12, this.Width / this.Height, 0.80f, 10000.0f);            device.Transform.View = Matrix.LookAtLH(new Vector3(-400, -100, 600.0f), new Vector3(), new Vector3(0, 1, 0));            device.RenderState.Ambient = Color.Black;            device.Lights[0].Type = LightType.Directional;            device.Lights[0].Diffuse = Color.AntiqueWhite;            device.Lights[0].Direction = new Vector3(0, 1, 0);            device.Lights[0].Update();            device.Lights[0].Enabled = true;        }


至此,基本大功告成,最後的是逐步調用這幾個函數,然後顯示出來,我採用panel這個控制項繪畫的時候調用這些函數,如下:

        //panelPaint是我自己起的名字,對應的事件是Paint        private void panelPaint(object sender, PaintEventArgs e)        {            InitializeGraphics();            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0f, 1);            SetupCamera();            device.Present();            device.BeginScene();            // Draw our Mesh            DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);            device.EndScene();            //Render();            device.Present();           // this.Invalidate();        }

最後貼出來一個效果圖:


至此,基本大功告成。不過這裡還有幾個問題要說明:

1.程式編譯過程中或許會遇到一個問題:

混合模式程式集是針對“v1.1.4322”版的運行時產生的,在沒有配置其他資訊的情況下,無法在 4.0 運行時中載入該程式集。

這個問題解決辦法就是開啟檔案中的app.config檔案,注釋掉原來的內容,改成以下內容:

<span style="font-size:14px;"><span style="font-family:'Microsoft YaHei';"><?xml version="1.0"?><configuration>  <startup useLegacyV2RuntimeActivationPolicy="true">    <supportedRuntime version="v4.0"/>  </startup></configuration></span></span>
程式應該就不會有問題了。

2.如果你自己在匯入自己的3D模型的時候,採用3dsmax中匯入的panda控制項轉換模型檔案為.x檔案的時候,有個選項,就是XFileSetting的設定一定要設定為Binary,如果設定為Text的話,Directx在讀入檔案的時候會不識別。截圖如下:

能遇到的問題基本就這些了,這裡附上原始碼連結:

http://download.csdn.net/detail/t46414704152abc/8709251

恩,基本就這樣了。希望能協助到大家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.