2013-04-16 27 views
2

我正在研究「落砂」風格的遊戲。最佳的設置像素數據的方法?

我已經嘗試了很多方法將沙子畫到屏幕上,但是,每種方式似乎都會以某種形式產生一些問題。事情

名單我已經工作過:

  1. 繪製每個像素單獨地,一個在從一個像素大小的紋理時間。問題:在每次更新約100,000個像素更改後減慢。

  2. 將每個像素繪製爲一個大紋理2d,繪製紋理2d,然後清除數據。問題:使用texture.SetPixel()非常緩慢,甚至在處理舊紋理時,即使在對象上調用處理後,也會導致少量內存泄漏(每秒大約30kb,加起來很快)。我根本無法弄清楚如何阻止它。但總的來說,這是迄今爲止最好的方法。如果有辦法阻止泄漏,我想聽聽。

  3. 從位圖中使用Lockbits。這從位圖的角度來說非常有效,但不幸的是,我仍然不得不將位圖轉換回紋理2d,這會導致幀速率下降到小於1。所以,如果我能找到一種在xna中繪製位圖而不轉換它(或某種東西)的方法,這就有可能工作得很好。

  4. 將每個像素設置爲具有設置像素的紋理2d,將像素的「舊」位置替換爲透明像素,然後用適當的顏色設置新位置。這使完成這項工作所需的像素集數量增加了一倍,並且比使用數字2慢得多。

所以,我的問題是,有沒有更好的想法?或者有關如何修復樣式2或3的想法?

+0

對於#1的迴應:您是否嘗試過批量抽籤,而不是每次抽籤? – 2013-04-17 05:06:31

+0

不,我不這麼認爲,你有方便的鏈接或解釋嗎? (如果你的意思是一起畫相似的紋理,是的,這確實有幫助,但它不是很好。) – Colton

+0

嗯,一個簡單的嘗試開始就是簡單地使用一個'SpriteBatch',並且'繪製'每個像素與一個目的地尺寸爲「1,1」的矩形,以及來自具有所需顏色的非常小的紋理的樣本。如果這仍然很慢,你可以手動完成所有工作,不要使用任何紋理(應該加快速度)。儘管這可能有很多多邊形,但它值得一試。 – 2013-04-17 05:20:24

回答

1

我的直接想法是,你正在拖延GPU管道。 GPU可以有一個流水線落後於您發佈的命令後面的幾個幀。

因此,如果您發出命令來設置紋理上的數據,並且GPU當前正在使用該紋理渲染舊幀,則必須先完成其所有渲染,然後才能接受新紋理數據。所以它等着,殺了你的表現。

解決方法可能是在雙(或甚至三或四)緩衝區排列中使用多個紋理。不要嘗試寫入您剛剛用於渲染的紋理。

另外 - 你可以從線程以外的渲染線程寫入紋理。這可能派上用場,特別是清理紋理。

正如您似乎已經發現的那樣,SetData的大塊實際上更快,而不是發出很多小的SetData調用。確定「塊」的理想尺寸在GPU之間是不同的 - 但它比單個像素大一點。在原始性能方面(如果你忽略了剛纔描述的管道效應),創建紋理比重複使用要慢得多。所以重複使用該紋理。

值得一提的是,「像素精靈」需要向GPU發送的每像素數據量可能是紋理的30倍。

另請參閱this answer,如果您想深入一點,它還有一些更多的細節和一些深入的鏈接。

+0

我認爲線程可能是我下一個最好的選擇。感謝您的智慧......和您的聯繫。 :p – Colton