)Managed DirectX +C# 開發(入門篇)(八)

來源:互聯網
上載者:User
第七章 頂點緩衝 一、索引緩衝3D物體中的三角形經常會有許多共用頂點。如果用兩個三角形組合為一個長方形,有兩個點被重複使用,當要表現一個更精細更複雜的模型的時候,重複的頂點數將會變得很大。的立方體,僅有八個頂點,但是當用三角形列表示它的時候,所有的點都被重複使用。索引緩衝就是一塊儲存了頂點資料索引的緩衝。緩衝中的索引為32位或16位的整數。比如,當使用索引0,1,6來繪製一個三角形時,會通過索引映射到相應的頂點來渲染映像。以下為建立一個索引緩衝的程式碼範例:int numberVerts = 8;short[] indices = {    0,1,2, // Front Face     1,3,2, // Front Face     4,5,6, // Back Face     6,5,7, // Back Face     0,5,4, // Top Face     0,2,5, // Top Face     1,6,7, // Bottom Face     1,7,3, // Bottom Face     0,6,1, // Left Face     4,6,0, // Left Face     2,3,7, // Right Face     5,2,7 // Right Face }; Mesh mesh = new Mesh(numberVerts * 3, numberVerts, MeshFlags.Managed,                     CustomVertex.PositionColored.Format, device); using(VertexBuffer vb = mesh.VertexBuffer){    GraphicsStream data = vb.Lock(0, 0, LockFlags.None);     data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, 0x00ff00ff));    data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, 0x00ff00ff));     vb.Unlock();} using (IndexBuffer ib = mesh.IndexBuffer){    ib.SetData(indices, 0, LockFlags.None);} 頂點和索引緩衝有相似的地方,一個頂點緩衝是一塊連續的儲存了頂點資料的記憶體。同樣的,一個索引緩衝是一塊連續的儲存了索引資料的記憶體。使用頂點和索引緩衝儲存資料是因為它們能被放置在顯存中。渲染顯存中的資料要比渲染系統記憶體中的資料快的多。 二、索引緩衝執行個體下面為一使用索引緩衝的例子,顯示一個旋轉的正方體; 相關代碼如下:首先,定義物件變數;private VertexBuffer vb = null;         private IndexBuffer ib = null;在圖形的初始化函數中執行個體化對象:public void InitializeGraphics()         {……     vb = new VertexBuffer(typeof(CustomVertex.PositionColored), 8, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);              vb.Created += new EventHandler(this.OnVertexBufferCreate);              OnVertexBufferCreate(vb, null);               ib = new IndexBuffer(typeof(short),indices.Length,device,Usage.WriteOnly,Pool.Default);              ib.Created += new EventHandler(OnIndexBufferCreated);              this.OnIndexBufferCreated(ib,null);}對於IndexBuffer()建構函式,相關參數說明如下:?    indices.Length —— 分配給緩衝的位元組大小。假如想得到一個能儲存8個頂點的頂點緩衝,那麼就要在頂點結構中設定這個參數為 8 * sizeof ( Vertex ) 。?     Usage指定關於怎樣使用緩衝的額外資訊。這個值可以是0,沒有標記,或者是下面標記的組合: —— Dynamic:設定這個參數可以使緩衝是動態。Points:這個參數指定緩衝儲存原始點。Softwareprocessing:使用軟體頂點處理Writeonly:指定應用程式只能寫緩衝。它允許驅動程式分配最適合的記憶體位址作為寫緩衝。 Pool —— 緩衝放置在哪一個記憶體池中不使用Dynamic參數建立的緩衝被叫做靜態緩衝。靜態緩衝通常被放置在顯存中,在其中的資料能被很好的處理。然而,對於靜態緩衝,從中讀取和寫入資料是很慢的,因為訪問顯存是很慢的。所以一般用靜態緩衝儲存不需要被經常改變的資料。比如,可以儲存地形和建築物。靜態緩衝應該在應用程式初始化的時候就被填充好,而不是在運行時才做。動態緩衝通常被放在AGP記憶體中,這種記憶體中的資料能被很快的更新。處理動態緩衝中的資料不會比處理靜態緩衝中的資料快,因為這些資料必須在渲染前被轉移到顯存中,動態緩衝的優點是能夠被更迅速地更新。因此,假如需要經常更新緩衝中的資料,那麼就應該使用動態緩衝。比如,對於粒子系統來說,一般應用動態緩衝。 下面看看灌入資料的代碼:private void OnIndexBufferCreated(object sender, EventArgs e)         {              IndexBuffer buffer = (IndexBuffer)sender;              buffer.SetData(indices,0,LockFlags.None);         } 另外在渲染函數中:protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)         {         ……              device.SetStreamSource(0, vb, 0);              device.Indices = ib;              angle += 0.05f;              device.Transform.World = Matrix.RotationYawPitchRoll(angle / (float)Math.PI,angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) ;              device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,8,0,indices.Length / 3);              …….         } 注意,對於頂點緩衝來說,使用的是SetStreamSource()方法,而對於索引緩衝來說,則是設定Indices屬性。因為在同一時間內只可能使用同一種類型的索引緩衝。另外,注意把以前的DrawPrimitives改為了DrawIndexedPrimitives。來看看這個方法的參數如下:public void DrawIndexedPrimitives(PrimitiveType primitiveType,int baseVertex ,int minVertexIndex,int numVertices, int startIndex, int primCount); PrimitiveType:表示要繪製的圖元類型。baseVertex:表示從索引緩衝起點到要使用的第一個頂點索引的位移量。MinVertexIndex:這幾個頂點中最小的頂點索引值。numVertices:是所要使用的頂點數量。startIndex:從數組中的哪一個位置開始讀取頂點。primCount:是要繪製的圖元數量。 當建立完索引緩衝後,如果以後需要獲得相關資訊,可以使用IndexBuffer.Description屬性來得到;  三、深度緩衝 深度緩衝不是用來儲存映像資料,而是用來記錄影素的深度資訊。以便確定哪一個像素最後被繪製出來。因為在3D情境中,經常會發生一個物體把將另一個物體的一部分遮住了。為了使Direct3D能確定物體的前後關係並正確的繪製出來,需要使用深度緩衝。它有時也稱z-buffer或w-buffer,為每一個像素計算深度值並進行深度測試。通過深度測試可以比較得出哪個像素離攝相機更近並將它畫出來。這樣就可以只繪製最靠近攝相機的像素,被遮住的像素就不會被制。深度緩衝的格式決定著深度測試的精確程度。一個24位的深度緩衝比16位的深度緩衝更精確。通常,應用程式在24位元深度緩衝下就能工作的很好,但是Direct3D也同時支援32位的深度緩衝。 四、深度緩衝樣本開啟前面繪製的立方體,在情境中再加入兩個立方體,同時,為了觀察方便,對加入的立方體進行了平移;代碼如下:     device.Transform.World = Matrix.RotationYawPitchRoll(angle / (float)Math.PI,angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) ;              device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,8,0,indices.Length / 3);               device.Transform.World = Matrix.RotationYawPitchRoll(angle / (float)Math.PI,angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f)               * Matrix.Translation(0,1,5);              device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,8,0,indices.Length / 3);                            device.Transform.World = Matrix.RotationYawPitchRoll(angle / (float)Math.PI,angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f)                    * Matrix.Translation(0,-1,-5);              device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,8,0,indices.Length / 3); 執行程式,注意這是沒有加入深入緩衝的效果:下面加入深度緩衝,加入很簡單;只需在建立裝置時,將改變一下參數的屬性:PresentParameters presentParams = new PresentParameters();presentParams.EnableAutoDepthStencil = true;presentParams.AutoDepthStencilFormat = DepthFormat.D16;presentParams.SwapEffect = SwapEffect.Discard;Format current = Manager.Adapters[0].CurrentDisplayMode.Format; 其中EnableAutoDepthStencil表示是否使用深度緩衝。AutoDepthStencilFormat定義精度,常用枚舉格式及含義如下:D32——表示32位元深度緩衝D24S8——表示24位元深度緩衝並保留8位模版緩衝(stencil buffer)?    D24X8——表示24位元深度緩衝?    D24X4S4——表示24位元深度緩衝並保留4位模版緩衝?    D16——表示16位元深度緩衝 現在如果執行程式,還將無法得到正確的結果,在渲染函數中將代碼:device.Clear(ClearFlags.Target , Color.Black , 1.0f, 0);更改為:device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black , 1.0f, 0);現在,再執行程式,結果如下:被過濾廣告現在,三個立方體有明顯的層次感了。轉自:dandancool http://blog.csdn.net/dandancool/archive/2007/06/26/1666576.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.