[問題] OpenGL的VBO

看板C_and_CPP作者 (揪嚕嚕)時間15年前 (2010/04/01 01:21), 編輯推噓19(19077)
留言96則, 4人參與, 最新討論串1/1
遇到的問題: (題意請描述清楚) 在我的程式中,存在數個獨立的物件要繪出來 是不是代表要畫多少物件就要有多少個vertex buffer?? 也就是說應該要這樣 GLuint g_VertexBufferID[K]; GLuint g_IndexBufferID[K]; glGenBuffersARB( ANI_TYPE_COUNT, g_VertexBufferID); glGenBuffersARB( ANI_TYPE_COUNT, g_IndexBufferID); 還是只要宣告一個就好 GLuint g_VertexBufferID; GLuint g_IndexBufferID; glGenBuffersARB( 1, &g_VertexBufferID); glGenBuffersARB( 1, &g_IndexBufferID); 另外 因為物件每個影格的點座標都會改變 所以是否存在更快的寫法來取代我現在的版本? (事實上應該說 我不知道我寫的流程是不是對的 各個function的呼叫順序是否正確) 繪製的行為如下: for( i = 0 ; i < K ; ++i ){ glBindBufferARB( GL_ARRAY_BUFFER_ARB, g_VertexBufferID[i]); glBufferDataARB( GL_ARRAY_BUFFER_ARB, vsize[i], vertex[i], GL_STREAM_DRAW); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VERTEX), 0); glNormalPointer( GL_FLOAT, sizeof(VERTEX), (void *)noffset); glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, g_IndexBufferID[i]); glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, tsize[i], triangle[i], GL_STATIC_DRAW ); for( int j = 0 ; j < 10 ; ++j ){ //每個畫10次 glPushMatrix(); //先作位移 旋轉 等等 glDrawElements( GL_TRIANGLES, triangle_no, GL_UNSIGNED_SHORT,0); glPopMatrix(); } glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); } 最後 我使用了VidMemWatcher3這個工具想要看我程式有沒有用到硬體的支援 以及是否有善用video memory 結果幾乎沒有 只用不到10MB 但是許多簡單的範例(範例是靜態物件) 用VidMemWatcher3看 使用video memory的量都比較多 導致我沒有辦法知道目前寫出來的程式問題在哪邊 或是說 存在更好的工具可以讓我profile哪邊還可以改進的更快... 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux) VC++ 6.0 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.134.30.224 ※ 編輯: windkey 來自: 220.134.30.224 (04/01 01:22)

04/01 01:35, , 1F
K有多大? 純看這些code我會猜bottle neck在draw call太
04/01 01:35, 1F

04/01 01:35, , 2F
多..
04/01 01:35, 2F

04/01 01:36, , 3F
其實多個物件, 用同樣的VBO也無所謂, 只是分開來基本上
04/01 01:36, 3F

04/01 01:37, , 4F
video memory..既然你那十次call都是畫同一塊VBO,當然不
04/01 01:37, 4F

04/01 01:37, , 5F
會多 但是那十次push/pop 旋轉/位移 是十倍的draw call
04/01 01:37, 5F

04/01 01:37, , 6F
更容易管理, VB/IB的data也不用糾在一起, 也不需要一次
04/01 01:37, 6F

04/01 01:37, , 7F
一大塊VRam, 所以能分當然分著沒什麼不好@_@"
04/01 01:37, 7F

04/01 01:38, , 8F
K=1~7
04/01 01:38, 8F

04/01 01:38, , 9F
推h大上面說的, 也抱歉斷到推文....orz
04/01 01:38, 9F

04/01 01:40, , 10F
事實上 K算小 10只是範例 改成50 FPS就會降到20以下了
04/01 01:40, 10F

04/01 01:42, , 11F
所以你的VB data量很大?? 你的K那層迴圈會不斷重覆執行
04/01 01:42, 11F

04/01 01:42, , 12F
嗎?_?
04/01 01:42, 12F

04/01 01:42, , 13F
試著把draw call的數量減少吧 比如說把transform matrix
04/01 01:42, 13F

04/01 01:42, , 14F
存成texture丟進去GPU 再在vertex shader裡面取出來算
04/01 01:42, 14F

04/01 01:43, , 15F
現在支援vertex texture fetch的硬體應該不少了
04/01 01:43, 15F

04/01 01:45, , 16F
會 這迴圈在renderscene裡面 迴圈之前是設定點座標
04/01 01:45, 16F

04/01 01:46, , 17F
每個時間點點座標都在變化
04/01 01:46, 17F

04/01 01:46, , 18F
小弟我在猜, 原po不會是每個frame都bufferData K次吧@_@
04/01 01:46, 18F

04/01 01:47, , 19F
如果用shader的話 應該就完全不用VBO了??
04/01 01:47, 19F

04/01 01:47, , 20F
如果你每個frame draw都需要重新bufferData, 這樣很難快
04/01 01:47, 20F

04/01 01:48, , 21F
把點座標在GPU裡面直接算出來跟render了
04/01 01:48, 21F

04/01 01:48, , 22F
的起來, 因為光是system memory(AP)->system memory(
04/01 01:48, 22F

04/01 01:48, , 23F
driver) -> video memory 這條路就慢到瘋掉了....@_@"
04/01 01:48, 23F

04/01 01:49, , 24F
那要看mesh是不是每個frame都有更新的必要啊(比方說non-
04/01 01:49, 24F

04/01 01:49, , 25F
你的座標如果都要重新算重新render, 比如n+1個scene是
04/01 01:49, 25F

04/01 01:49, , 26F
linear transformation)
04/01 01:49, 26F

04/01 01:49, , 27F
第n個scene的vertex重算出來的, 這樣我想得到的就是利用
04/01 01:49, 27F

04/01 01:50, , 28F
transform feedback, 減少system memory傳遞這段@@"
04/01 01:50, 28F

04/01 01:51, , 29F
只是, 除非你的object自體mesh就在變形, 不然應該不用做
04/01 01:51, 29F

04/01 01:51, , 30F
到這種程度吧?? 又或者如果不是所有data都需要full
04/01 01:51, 30F

04/01 01:51, , 31F
update, 就bufferSubData, 但是能避免還是要避免....
04/01 01:51, 31F

04/01 01:53, , 32F
其實就算是non-linear transform 還是可以丟進GPU去算XD
04/01 01:53, 32F

04/01 01:53, , 33F
當然要看演算法裡每個vertex之間變動的相關性啦 如果每
04/01 01:53, 33F

04/01 01:54, , 34F
個vertex的移動是獨立的 就丟進GPU去算吧..
04/01 01:54, 34F

04/01 01:55, , 35F
兩位都回答的太精準 不該如何是好XD
04/01 01:55, 35F

04/01 01:56, , 36F
object是隨著時間mesh deformation沒錯
04/01 01:56, 36F

04/01 01:57, , 37F
vertex的移動就是要靠方法算出來(放在迴圈前)
04/01 01:57, 37F

04/01 01:57, , 38F
理論上可以丟近GPU去算 不過我還不會(遮臉) 現只會VBO
04/01 01:57, 38F

04/01 01:57, , 39F
deformation的演算法很複雜嗎?每個vertex之間是獨立嗎?
04/01 01:57, 39F

04/01 01:58, , 40F
如果vertex不會增減, 像h大說的各自跑, 那就用GPU直接算
04/01 01:58, 40F

04/01 01:58, , 41F
把能夠拆進GPU算的都丟進GPU去算 儘量讓CPU做的事最少化
04/01 01:58, 41F

04/01 01:58, , 42F
有需要就transform feedback也能每個stage存下新的data
04/01 01:58, 42F

04/01 01:59, , 43F
不經過memory; 其他deform小弟就不會了, GS解決得了嗎@@
04/01 01:59, 43F

04/01 02:00, , 44F
GS只能解決到primitive的層級 如果deformation演算法是
04/01 02:00, 44F

04/01 02:00, , 45F
加兩個字, 不經過system memory, 總之像h大說的, 大量
04/01 02:00, 45F

04/01 02:00, , 46F
要計算一大群vertex之間相關的資料來作變動 那就沒辦法
04/01 02:00, 46F

04/01 02:01, , 47F
vertex data盡力塞給GPU跑, 能不動CPU就不動, 能不動
04/01 02:01, 47F

04/01 02:01, , 48F
system memory就不動orz
04/01 02:01, 48F

04/01 02:02, , 49F
假設用到GPU 那這套東西 有可能porting到mobile phone嗎
04/01 02:02, 49F

04/01 02:02, , 50F
當然到mobile phone就會一次只畫一兩個物件之類的
04/01 02:02, 50F

04/01 02:02, , 51F
借問h大, 小弟學藝不精, 那Tessellation行嗎@_@"
04/01 02:02, 51F

04/01 02:03, , 52F
要在mobile phone上跑就是OpenGL ES了吧?? 你得確定你需
04/01 02:03, 52F

04/01 02:03, , 53F
請問GS是??
04/01 02:03, 53F

04/01 02:03, , 54F
要的feature 你的target device都支援, 而且效能可接受.
04/01 02:03, 54F

04/01 02:04, , 55F
Tessellation是拿一個primitive來計算出一堆新的..
04/01 02:04, 55F

04/01 02:04, , 56F
你不能在一個primitive裡改變另一個primitive的資料,所
04/01 02:04, 56F

04/01 02:04, , 57F
以不行。
04/01 02:04, 57F

04/01 02:05, , 58F
不過, 寫ES 2.0寫vertex shader是OK, 但沒有強迫device
04/01 02:05, 58F

04/01 02:05, , 59F
支援vertex texture, 而且ES 2.0印象中也未納入
04/01 02:05, 59F

04/01 02:05, , 60F
GPU的重點在於「平行化」這意味著你每個單元處理的事是
04/01 02:05, 60F

04/01 02:05, , 61F
獨立的
04/01 02:05, 61F

04/01 02:05, , 62F
所以如果演算法是「根據一群單元的值,來對整群單元變動
04/01 02:05, 62F

04/01 02:06, , 63F
就很難丟進GPU裡去算..
04/01 02:06, 63F

04/01 02:06, , 64F
transform feedback, 這我真的不會keep前一次draw的
04/01 02:06, 64F

04/01 02:06, , 65F
vb data結果了....orz
04/01 02:06, 65F

04/01 02:07, , 66F
小弟我始終搞不懂Tess那塊Orz 謝h大的說明....<(_ _)>
04/01 02:07, 66F

04/01 02:07, , 67F
演算法簡單 可以套用在GPU上
04/01 02:07, 67F

04/01 02:09, , 68F
不, 演算法是一回事, 你要實現演算法時用到的GL(ES)
04/01 02:09, 68F

04/01 02:09, , 69F
我是覺得這程式有點像沒mesh的partical system
04/01 02:09, 69F

04/01 02:09, , 70F
feature在你的target device上有沒有良好支持才是重點:)
04/01 02:09, 70F

04/01 02:10, , 71F
我了解V大你說的 但是當跑到mobile device的時候
04/01 02:10, 71F

04/01 02:11, , 72F
我想不會有人關注這顯示出來要多精美 因此就算用vertex
04/01 02:11, 72F

04/01 02:12, , 73F
array畫 我想也是可以的 不支援的就退化 能支援當然就
04/01 02:12, 73F

04/01 02:12, , 74F
有更好的效能
04/01 02:12, 74F

04/01 02:13, , 75F
如果你演算法真的很簡單 控制變數才十來個的話
04/01 02:13, 75F

04/01 02:13, , 76F
而在desktop上 當然就要有更好的方法來顯示
04/01 02:13, 76F

04/01 02:13, , 77F
也不用放進texture了 直接當變數丟進去就好XD
04/01 02:13, 77F

04/01 02:16, , 78F
good idea 所以我可以考慮在desktop版本用vertex texture
04/01 02:16, 78F

04/01 02:16, , 79F
然後movile device版本用變數丟進去
04/01 02:16, 79F

04/01 02:17, , 80F
如果控制變數很少 兩個版本都可以用變數丟進去啊
04/01 02:17, 80F

04/01 02:17, , 81F
desktop硬體能吃的變數量絕對是比mobile多的XD
04/01 02:17, 81F

04/01 02:19, , 82F
我....先去弄懂shader那邊好了....感謝各位
04/01 02:19, 82F

04/01 02:23, , 83F
記得看一下GL_MAX_VERTEX_UNIFORM_COMPONENTS是幾個XD
04/01 02:23, 83F

04/01 02:23, , 84F
現在的硬體 就算是mobile應該至少也有32以上(吧
04/01 02:23, 84F

04/01 02:24, , 85F
其實我的nb連VBO都不支援 我很苦惱shader怎辦XD
04/01 02:24, 85F

04/01 02:27, , 86F
ESSL規定至少 gl_MaxVertexUniformVectors 要 128....:)
04/01 02:27, 86F

04/01 02:28, , 87F
算component再乘以4, 所以妥當啦.... (誤~~~~有誤嗎XD)
04/01 02:28, 87F

04/01 02:30, , 88F
NB太舊左轉樓下nb-shopping(大誤XD) 先用桌機插卡頂囉:)
04/01 02:30, 88F

04/01 12:15, , 89F
學shading language前建議先學整個rendering pipeline比較
04/01 12:15, 89F

04/01 12:16, , 90F
容易上手,最好是可以實作出一個software renderer。這樣
04/01 12:16, 90F

04/01 12:16, , 91F
各個shader要做什麼事應該都會很清楚,剩下就只是語法 XD
04/01 12:16, 91F

04/01 12:30, , 92F
Software Renderer(抖) (搬出Mesa....以下省略數百字XD)
04/01 12:30, 92F

04/01 12:30, , 93F
GS = Geometry shader, DX10 硬體才有
04/01 12:30, 93F

04/01 12:31, , 94F
不過, 推pipeline最好能了解, 只會用有時候好像不夠Orz
04/01 12:31, 94F

04/01 12:32, , 95F
沒有要做到Mesa那麼完整啦XD 能夠像OpenGL glBegin、End
04/01 12:32, 95F

04/01 12:33, , 96F
塞頂點進去能輸出polygon就可以了
04/01 12:33, 96F
文章代碼(AID): #1BiuItmq (C_and_CPP)