2012-05-22 26 views
2

我是圖形編程新手,需要爲我們創建的演示添加渲染後端。我希望你們能指引我正確的方向。畫一堆由CUDA/OpenCL生成的元素?

簡短版本:有沒有什麼辦法可以爲OpenGL發送不同元素的數據數組,而不必爲每個元素明確地發出繪圖命令?

長版本:我們有一個CUDA程序(最終是OpenCL),它會爲我們計算一堆物體的一堆數據。然後我們需要使用例如OpenGL來渲染這些對象。

CUDA內核可以生成我們的頂點,並且使用OpenGL互操作,它可以在OpenGL VBO中推送這些頂點,而不必將數據傳回主機設備內存。但問題是,我們有一堆(超過一百萬是我們的目標)不同的對象。看起來我們最好的選擇是分配一個VBO並將每個對象的頂點放入其中。然後我們可以用該VBO內的每個元素的偏移量和長度來調用glDrawArrays。

然而,每個對象可具有可變數目的頂點的(雖然在場景中的總的頂點可以被界定。)我想避免必須從CUDA傳送開始的索引和長度的列表 - > CPU的每一幀,特別是考慮到這些繪圖命令直接回到GPU。

有沒有辦法用數據打包一個緩衝區,以便我們只能向OpenGL發出一個調用來渲染緩衝區,並且它可以渲染緩衝區中的許多不同的元素?

(但願我也給予了足夠的信息,以避免這裏XY問題。)

+1

定義「元素」。你說你正在使用'glDrawArrays'命令來渲染它。你渲染GL_TRIANGLE_STRIP,GL_TRIANGLES或其他東西嗎?你渲染了什麼原始的東西?此外,如果您在一次繪製調用中渲染它們,則不會在對象之間進行任何狀態更改。 –

+0

GL_TRIANGLE_STRIP此刻(試圖繪製2D [甜甜圈]的片段,如[本圖]中所示)(http://arstechnica.com/business/2011/04/web-browser-market-share-modern-browser-edition /))。但是我們想把它推廣到在未來中繪製任意元素。 – int3h

回答

0

也許不是最佳的,但你可以做一個單一的glDrawArray你的整個緩衝區...

  • 如果你使用GL_TRIANGLES,你可以用零填充你的緩衝區,並且只在你的內核中寫入所需的頂點。這樣,緩衝區中的「空白」區域將被繪製爲0區域多邊形(=退化多邊形 - >根本不繪製)
  • 如果使用GL_TRIANGLE_STRIP,則可以執行相同的操作,但必須重複第一個頂點,以便在(0,0,0)和您的網格之間生成一個假三角形。

這似乎矯枉過正,但: - 你必須要能夠反正 處理儘可能多的頂點 - 退化三角形不使用填充率,所以他們幾乎是免費的(頂點着色器仍然計算,雖然)

一個可能更好的解決方案是使用glDrawElements代替:在您的內核中,您還可以爲整個緩衝區生成一個索引列表,這將完全跳過緩衝區的區域。

3

一種方法是擺脫理解這些作爲單個對象並使它們成爲用單個繪製調用繪製的單個大對象。問題是,它是什麼數據區分對象彼此,這意味着你在glDrawArrays/glDrawElements的個別調用之間改變了什麼?

如果是簡單的東西,比如顏色,那麼提供這個額外的頂點屬性可能會更容易。通過這種方式,您可以使用單個繪圖調用將所有對象渲染爲一個單獨的大對象,並使用單獨的子對象(現在確實只存在於概念上)正確着色。附加屬性的內存成本可能非常值得。

如果它稍微複雜一些(如紋理),您仍然可以使用額外的每個頂點屬性對其進行索引,它可以是紋理數組中的索引(因爲應該支持紋理數組CUDA/OpenCL-capable硬件)或紋理座標到單個大紋理(所謂紋理圖集)的特定子區域中。

但是,如果這些對象之間的差異更復雜一些,作爲不同的着色器或其他東西,則可能確實需要呈現單個對象並進行單獨的繪製調用。但是你仍然不需要一直往CPU中循環。通過使用ARB_draw_indirect擴展(這是GL 4.0以後的核心,我認爲,但可能在GL 3硬件(因此CUDA/CL-硬件)上支持,不知道),您可以將參數提供給glDrawArrays/glDrawElements調用從一個額外的緩衝區(您可以像使用其他GL緩衝區一樣使用CUDA/CL編寫)。因此,您可以在GPU上組合每個單獨對象的偏移長度信息,並將它們存儲在單個緩衝區中。然後你將你的glDrawArraysIndirect循環偏移到這個單獨的draw-indirect-buffer中(各個對象之間的偏移現在是不變的)。


但如果發放多次抽獎的唯一理由要求就是要渲染的對象爲單GL_TRIANGLE_STRIP S或GL_TRIANGLE_FAN S(或神提防,GL_POLYGON S),您可能希望只使用一個重新考慮一堆GL_TRIANGLES,以便您可以在一次繪製調用中渲染所有對象。使用三角形條帶可能節省的時間和內存很可能會因多次繪製調用的開銷而變得過重,特別是在繪製許多小三角形條帶時。如果你真的想使用小條或者粉絲,你可能需要引入退化三角形(通過重複頂點)來隔離它們,即使是用一次繪製調用來繪製。或者您可以查看GL 3.1引入的glPrimitiveRestartIndex函數。

+0

ARB_draw_indirect看起來像我一直在尋找的東西!謝謝!我需要確保我們的平臺支持擴展(我們最終希望瞄準WebCL,看起來它不支持它,但我們可能能夠改變它...) 如果這不起作用,我會研究退化的三角形(如果你有任何關於尋找更多信息的指針,請張貼它們,如果你不介意的話)。 – int3h

+0

我也會研究glPrimitiveRestartIndex,但是好像你只能指定一個單一索引。有沒有辦法用緩衝區/數組驅動它?所以你仍然需要多個電話+知道抵消。 – int3h

+0

@ int3h那麼首先將它分成多個繪製調用的原因是什麼?如果真的只是因爲使用了三角形條或者扇子(不管怎樣,原始重啓和degerate三角形都不會給你買任何東西),那麼爲什麼不使用一個簡單的三角形集合來繪製整個東西呢?呼叫?這樣,您不必擔心任何偏移量或長度,因爲您可以將整個緩衝區作爲列表繪製爲三角形。當然,你知道單個平局的三角形不需要以任何方式連接。 –

相關問題