C#Direct3D程式設計3D世界中的三角形(轉)
C#Direct3D程式設計3D世界中的三角形(轉)[@more@] 那什麼是真正的3D世界呢?或者說Direct3D的3D模型是什麼樣的呢? Direct3D的模型由World 空間,View 空間和光源組成。World空間就像我們現實生活中的空間一樣,我們可以把物體放在這個空間的任何地方。但僅僅這樣是不夠的。因為現實中,我們是透過眼睛來看事物的,存在的東西不一定我們可以看得到,太遠的東西看不到,被擋住的東西看不到,太近的東西也看不到,在我們視角以外的東西一樣看不到。在Direct3D中用camera來模擬我們的眼睛。 另外還有一個重要概念,transform,變換。在world空間中,我們可以把物體移動,旋轉,這需要透過變換來實現。透過camera來決定我們最終能看到的那些東西時也是經過變換。在Direct3D中,變換是透過4x4的矩陣來實現的。 不是搞演算法的人沒有必要了解矩陣的具體內容,可以透過Maxtrix中的靜態函式來建立矩陣: Matrix.RotationX(), Matrix.RotationY(), Matrix,RotationZ(),建立分別圍繞X,Y,Z軸旋轉的矩陣。 Matrix.Translation()用來建立移動物體的矩陣。 而與camera相關的變換有兩個,View Transform,和Projection Transform.View Transform用來定義camera的資訊。而Projection Transform用來定義我們的可見範圍, 也就是說那些物體會被繪製到螢幕上去。 另外一個很重要的概念就是光源,在真實世界中,沒有光的情況下我們是看不到東西的,即使他存在。而且我們看到的物體的顏色/亮度,與光源的顏色/亮度,與他本身的材質/顏色都有關係。在Direct3D中也是如此,一旦一個物體在我們的可視範圍內,並且沒有被遮擋住,那麼他能否可見,以及什麼顏色/亮度,就由光源,物體的材質來決定了。 下面就開始我們的例子。首先把我們的程式碼中的頂點格式,改成PositionColored格式。注意座標哦,這裡的座標可不是螢幕座標系了,而是World座標系,是左手笛卡爾3D座標系。第一步的程式碼如下: #region Using directives using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; #endregion namespace Exam2 { partial class Form1 : Form { private Device device = null; public Form1() { InitializeComponent(); this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true ); } public void InitializeGraphics() { PresentParameters para = new PresentParameters(); para.Windowed = true; para.SwapEffect = SwapEffect.Discard; device = new Device( 0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, para ); } private void Form1_Paint(object sender, PaintEventArgs e) { device.Clear( ClearFlags.Target, Color.Blue, 0.0f, 0 ); CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[3]; verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f); verts[0].Color = Color.Aqua.ToArgb(); verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f); verts[1].Color = Color.Black.ToArgb(); verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f); verts[2].Color = Color.Purple.ToArgb(); device.BeginScene(); device.VertexFormat = CustomVertex.PositionColored.Format; device.DrawUserPrimitives( PrimitiveType.TriangleList, 1, verts ); device.EndScene(); device.Present(); this.Invalidate(); } } } 執行以下看看,呵呵,什麼也看不到!就是藍色背景的視窗,誰動了我的漂亮的三角形阿? 原因就在我們上面講到的內容裡。我們這裡使用的PositonColored頂點格式,是未經過變換的,沒有任何檢視變換的資訊,Direct3D就認為他們都不可見了。所以…… 我們接下來,就要把我們的漂亮的三角形找回來:加入camera的資訊。 新的程式碼如下: #region Using directives using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; #endregion namespace Exam2 { partial class Form1 : Form { private Device device = null; public Form1() { InitializeComponent(); this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true ); } public void InitializeGraphics() { PresentParameters para = new PresentParameters(); para.Windowed = true; para.SwapEffect = SwapEffect.Discard; device = new Device( 0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, para ); } public void SetupCamera() { device.Transform.Projection = Matrix.PerspectiveFovLH( ( float ) Math.PI / 4, this.Width / this.Height, 1.0f, 100.0f ); device.Transform.View = Matrix.LookAtLH( new Vector3( 0, 0, 5.0f ), new Vector3(), new Vector3( 0, 1, 0 ) ); // device.RenderState.Lighting = false; } private void Form1_Paint(object sender, PaintEventArgs e) { device.Clear( ClearFlags.Target, Color.Blue, 0.0f, 0 ); SetupCamera(); CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[3]; verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f); verts[0].Color = Color.Aqua.ToArgb(); verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f); verts[1].Color = Color.Black.ToArgb(); verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f); verts[2].Color = Color.Purple.ToArgb(); device.BeginScene(); device.VertexFormat = CustomVertex.PositionColored.Format; device.DrawUserPrimitives( PrimitiveType.TriangleList, 1, verts ); device.EndScene(); device.Present(); this.Invalidate(); } } } Matrix.LookAtLH()函式就是設定View Transform的資訊(Camera的資訊)。第一引數,是camera在world 空間的位置;第二個引數,camera在對著那一點(不懂?就好像我們的眼睛,只能盯著一點看,其他的是用餘光來看的),第三個參數列示那個是“上”(也就是我們腦袋指向的方向,我們倒立看東西時,上就是下,我們躺著看東西時,上就是左/右。場外音:你演雜技呢)。程式碼裡的函式,把camera放在了Z軸上,看著座標原點(? 你怎麼老看xx的地方……,沒辦法,不良少年啊),上方向是Y軸。 Matrix.PerspectiveFovLH()函式設定投射變換。第一個引數,視角;第二個引數,可視區的長寬比(我們可視區的介面是矩型,就像camera的取景器),第三個引數是我們最近可以看到的地方,第四個引數,我們最遠可以看到的地方。這樣就描述出來一個四稜錐拄體。所有在這個空間的物體都是可見的
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-952143/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Ruby中的設計模式——《松本行弘的程式世界》設計模式
- 瘋狂的程式設計世界程式設計
- “報錯”是程式設計世界中,最簡單的事情!程式設計
- 3D遊戲的照明設計理論(四):如何在遊戲引擎中照亮遊戲世界3D遊戲引擎
- 程式設計世界的熵增原理程式設計熵
- 程式設計師世界的縮寫程式設計師
- OpenGL基礎圖形程式設計(一)OpenGL與3D圖形世界程式設計3D
- PHP物件程式設計實現3D餅圖 (轉)PHP物件程式設計3D
- 一種新的程式設計思路(中): (轉)程式設計
- 關於VC中的DLL的程式設計 (轉)程式設計
- 一種新的程式設計思路(中)附: (轉)程式設計
- Vector在Java程式設計中的應用 (轉)Java程式設計
- Java中的非同步網路程式設計 (轉)Java非同步程式設計
- 程式設計中的一些感悟(收藏) (轉)程式設計
- 程式設計師的世界盃觀戰指南程式設計師
- 開啟神秘程式設計世界的大門程式設計
- 世界級大牛對程式設計師超實用的程式設計箴言(上)程式設計師箴言
- 世界級大牛對程式設計師超實用的程式設計箴言(下)程式設計師箴言
- Qt程式設計之悲慘世界QT程式設計
- 程式設計師來做設計,世界會怎樣?程式設計師
- linux下c程式設計中的DOS攻擊程式(轉)LinuxC程式程式設計
- 1024程式設計師節:向改變世界的程式設計師致敬程式設計師
- 1024程式設計師節,向改變世界的程式設計師致敬程式設計師
- VB程式設計中的一些經驗 (轉)程式設計
- 淺談Delpih中的windowsAPI程式設計初步(1)(轉)WindowsAPI程式設計
- Linux 程式設計之Bash中的變數(轉)Linux程式設計變數
- 1024程式設計師節,向用程式碼改變世界的程式設計師致敬!程式設計師
- 架空世界設計中的重要性排序:世界觀、人物、情節、要素排序
- 3D遊戲程式設計作業93D遊戲程式設計
- Jive 中的設計模式 (轉)設計模式
- 淺談《怪物獵人:世界》中不同武器中的相似設計思路
- 世界最年輕蘋果程式設計師蘋果程式設計師
- 程式碼世界中的Lambda
- 世界五大計算機程式設計師計算機程式設計師
- Direct3D世界的Hello:高洛德渲染的三角形(轉)3D
- 漫談世界觀敘事設計中的工具鏈
- 多程式程式設計 (轉)程式設計
- 多程式程式設計(轉)程式設計