從教程上看,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;
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