XNA學習筆記——頂點緩存和索引緩存

從教程上看,XNA一開始沒有使用頂點緩存,不像D3D,一開始用的就是VertexBuffer。不過網上也有人說,D3D也可以不用VertexBuffer,有待學習。在XNA中如果不用VertexBuffer,就如上一個筆記中直接定義頂點,如VertexPositionColor,最後用GraphicsDevice的DrawUserPrimitive方法進行繪製。但是可以使用索引數組(還沒到索引緩存出場)。

   1: private void InitVertices()
   2: {
   3:     vertices3 = new VertexPositionColor[9];
   4:  
   5:     vertices3[0] = new VertexPositionColor(new Vector3(0, 0, 0), Color.Red);
   6:     vertices3[1] = new VertexPositionColor(new Vector3(1, 0, 0), Color.Green);
   7:     vertices3[2] = new VertexPositionColor(new Vector3(2, 0, 1), Color.Blue);
   8:     vertices3[3] = new VertexPositionColor(new Vector3(0, 1, -1), Color.Orange);
   9:     vertices3[4] = new VertexPositionColor(new Vector3(1, 1, 0), Color.Olive);
  10:     vertices3[5] = new VertexPositionColor(new Vector3(2, 1, 0), Color.Magenta);
  11:     vertices3[6] = new VertexPositionColor(new Vector3(0, 2, 0), Color.Yellow);
  12:     vertices3[7] = new VertexPositionColor(new Vector3(1, 2, 1), Color.Tomato);
  13:     vertices3[8] = new VertexPositionColor(new Vector3(2, 2, -1), Color.Plum);
  14:  
  15: }

上面定義了9個頂點,但要繪製8個三角形

   1: private void InitIndices()
   2: {
   3:     indices = new int[24]; 
   4:     
   5:     indices[0] = 0; 
   6:     indices[1] = 3; 
   7:     indices[2] = 1; 
   8:     
   9:     indices[3] = 1; 
  10:     indices[4] = 3; 
  11:     indices[5] = 4; 
  12:     
  13:     indices[6] = 1; 
  14:     indices[7] = 4; 
  15:     indices[8] = 5; 
  16:     
  17:     indices[9] = 1; 
  18:     indices[10] = 5; 
  19:     indices[11] = 2; 
  20:     
  21:     indices[12] = 3; 
  22:     indices[13] = 6; 
  23:     indices[14] = 7; 
  24:     
  25:     indices[15] = 3;
  26:     indices[16] = 7; 
  27:     indices[17] = 4; 
  28:     
  29:     indices[18] = 4; 
  30:     indices[19] = 7; 
  31:     indices[20] = 5; 
  32:     
  33:     indices[21] = 5; 
  34:     indices[22] = 7; 
  35:     indices[23] = 8; 
  36: }

最後

   1: device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, 9, indices, 0, 8); 

------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------

儘管使用索引數組提高了效率,但每次調用Draw函數,頂點都會從系統內存傳遞到顯卡中。通常,大部分數據沒有變化,這意味着每幀重複傳遞了相同的數據。所以可以將頂點數據存儲在顯存中加速程序。從顯存中將頂點數據傳遞到顯卡速度要快得多。

通過創建頂點數組的VertexBuffer,可以將頂點數據複製到顯存中。將頂點存儲到顯存後,就可以調用DrawPrimitives方法 (代替DrawUserPrimitives方法),這個方法從更快的顯存中獲取頂點。

注意:如果頂點幾乎無需更新,那麼這個方法可以極大地提高性能。但當處理被稱爲動態頂點數據(dynamic vertex data)時,這意味着頂點數據更新頻繁,就應使用DynamicVertexBuffer

如果你還想將索引存儲在顯卡中,你應在創建VertexBuffer之後再創建一個IndexBuffer 。

   1: private VertexBuffer vertexBuffer;
   2: private IndexBuffer indexBuffer;
在InitVertices中添加
   1: vertexBuffer = new VertexBuffer(device, VertexPositionColor.SizeInBytes * vertices3.Length, BufferUsage.WriteOnly); 
   2: vertexBuffer.SetData(vertices3, 0, vertices3.Length);

對於第一行的第三個參數,不是特別清楚。第二行就是將頂點數據加入到頂點緩存中

在在InitIndices中添加

   1: indexBuffer = new IndexBuffer(device, typeof(int), indices.Length, BufferUsage.WriteOnly);
   2: indexBuffer.SetData<int>(indices);

同樣第二行將索引數組加入到索引緩存中

   1: public void DrawUsingPresetEffect()
   2: {
   3:     device.VertexDeclaration = vertDeclaration;
   4:     device.Vertices[0].SetSource(vertexBuffer[1], 0, VertexPositionColor.SizeInBytes);
   5:     device.Indices = indexBuffer;
   6:     device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 9, 0, 8);
   7: }

device.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);就如同D3D中的SetStreamSource。對於Vertices[0]不是很理解。GraphicsDevice的Vertices屬性,在SDK中是這樣定義的:Gets the vertex stream collection

   1: public VertexStreamCollection Vertices { get; }

Vertices[0]表示vertex stream 0 (zero) of the graphics device

之後就是設置索引數組device.Indices = indexBuffer

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章