2012-02-15 57 views
0

我正在開發一個個人項目,與許多XNA項目一樣,它的起始地形位移貼圖用於生成一個在Device.DrawIndexedPrimitives()調用中呈現的頂點集合。用於地形編輯器的XNA VertexBuffer

我已經更新到自定義VertexDeclaration,但我現在無法訪問該代碼,所以我會發布稍微老一點的,但範例相同的(?)代碼。

我定義VertexBuffer爲:

VertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); 
VertexBuffer.SetData(vertices); 

其中「頂點」的定義是:

VertexPositionNormalTexture[] vertices

我也得到了在每個更新換兩隻指數緩衝區()迭代。在Draw()電話,我設置GraphicsDevice緩衝區:

Device.SetVertexBuffer(_buffers.VertexBuffer); 
Device.Indices = _buffers.IndexBuffer; 

忽略我希望是什麼的代碼無關的線條,我有一個邊界形狀內進行檢查,以確定是否頂點是在一定半徑範圍內的方法鼠標光標的位置,並根據按下哪個鍵來升高或降低頂點位置。我的問題是VertexBuffer.SetData()只在容器類的初始化時被調用一次。

修改VertexPositionNormalTexture[]陣列的頂點位置不會反映到屏幕上,儘管頂點位置的值會發生變化。我相信這與VertexBuffer.SetData()調用相關,但在修改頂點數組後,您不能簡單地使用頂點數組調用SetData()

後重新檢查IndexBuffer如何(在Update()時間2個緩衝區,交換和傳遞到SetData())處理,我想這應該是處理VertexBuffer操作的方式,但工作的呢?有更合適的方法嗎?我在這裏看到另一個類似問題的參考,但鏈接到源代碼是在MegaUpload,所以...

我會嘗試我的VertexBuffer.Swap()想法了,但我也看到引用DynamicVertexBuffer,想知道增益有?性能據說會受到影響,但對於地形編輯器來說,如果我可以動態地操作頂點數據,我並不認爲這是一個過大的折衷。

我可以發佈更多的代碼,但我認爲這可能是缺乏對如何設置設備緩衝區或數據流式傳輸給他們的理解。

編輯:下面提出的解決方案是正確的。我會很快發佈我的代碼。

回答

1

第一:我假設你沒有增加或減少地形的頂點。如果你不是,你根本不需要改變索引緩衝區。

第二:在識別簡單地編輯您的頂點數組不會改變屏幕上顯示的內容時您是正確的。 VertexBuffer與它所創建的頂點完全分離,並且不保留對它們原始數組的引用。這是設置數據時頂點的「快照」。

我不確定你所做的一些假設。您可以在,據我所知,隨時調用VertexBuffer.SetData()。如果你沒有改變你的地形中的頂點數量,只有它們的位置,這是很好的。每次更改頂點位置時,只需重新設置緩衝區中的數據即可。 [注意:如果我錯了,只能將緩衝區中的數據設置一次,那麼只需用新緩衝區替換緩衝區的舊實例並在其上設置數據即可。不過,我認爲你不需要,除非你已經改變了頂點的數量]

雖然,調用SetData對於大型緩衝區來說相當昂貴。您可以考慮將您的地形「分塊」成許多較小的緩衝區,以避免在更改地形時設置數據所需的開銷。

我對DynamicVertexBuffer類瞭解不多,但我不認爲這是最佳的(即使聽起來像這樣)。我認爲它更多地用於粒子頂點。雖然我可能是錯的。絕對研究它。

出於好奇,爲什麼你需要兩個索引緩衝區?如果你的頂點是相同的,爲什麼你會使用每幀不同的索引?

編輯:您創建VertexBuffer的代碼使用BufferUsage.WriteOnly。好的做法是使BufferUsage與GraphicsDevice相匹配。如果你沒有設置設備的BufferUsage,你可能只想使用BufferUsage.None。如果你喜歡,試試並檢查性能差異。

+0

我使用兩個索引緩衝區,以適應LOD頂點激活/停用。這也很好地說明了你所說的關於SetData是一個相當昂貴的操作。我把我的地形看作象限,有很多層次的子四邊形,所以這對我的頂點緩衝區來說可能是一個很好的範例。無論如何,我正在嘗試您提出的一些建議,並會在明天報告。 – 2012-02-17 04:35:09

+1

將頂點/索引緩衝區劃分爲小節還允許您選擇性渲染地形的某些部分,並更改特定節的LOD。通過計算攝像機的分段距離和(sectionPosition - cameraPosition)的點積與攝像機的前向矢量的距離,可以在攝像機後面剔除緩衝區,並在遠處設置較低的LOD。 – 2012-02-17 17:44:52