我正在做一個OpenGL實驗,以找到最經常/最有效的方式來非常頻繁地向glBufferData添加新數據。向glBufferData添加新點的最佳方法是什麼?
要做到這一點,我寫了一個小的2D繪圖程序,只需在移動鼠標時不斷添加點。
全功能如下:
void addPoint(double x, double y)
{
glBindBuffer(GL_ARRAY_BUFFER, pointVertBuffObj);
if (arrayOfPointCapacity < numOfPoints + 1) {
U32 size = (arrayOfPointCapacity + 8) * sizeof(Point2);
Point2 *tmp = (Point2*)realloc(arrayOfPoints, size);
arrayOfPoints = tmp;
arrayOfPointCapacity += 8;
}
arrayOfPoints[numOfPoints].x = x,
arrayOfPoints[numOfPoints].y = y;
U32 offset = numOfPoints * sizeof(Point2);
glBufferData(GL_ARRAY_BUFFER, numOfPoints * sizeof(Point2), arrayOfPoints, GL_DYNAMIC_DRAW);
numOfPoints++;
}
有新的數據每個我補充一點時間來重置glBufferData看來絕對是瘋了。我想過使用glBufferData
來分配大量點並將這些點設置爲glBufferSubData
。當緩衝區的大小變得太小時,我再次調用glBufferData
增加緩衝區的大小,並將現有的點複製回來。
理想情況下,我寧願避免將點數據存儲在計算機內存中,並將所有內容都保存在GPU內存中。但是當我調整緩衝區大小時,我必須將數據從緩衝區複製回CPU,然後調整緩衝區的大小,最後將數據從CPU複製回緩衝區。所有這些,似乎也是低效的。
有什麼想法?什麼是最佳做法?
你有一個「調整緩衝區大小是做這些事情的推薦方法」的源代碼?或者僅僅是你的建議? (不是一件壞事,因爲你是專家) – 2014-09-18 19:33:08
很好的回答(像往常一樣thx)。現在,我不明白你的第二條評論「這不是OpenGL的工作原理」。是的,它可以使用類似glMapBuffer的東西交換,我想這就是你的意思,但這個過程似乎效率低下。現在我喜歡你的第三個選項(glCopyBufferSubData),但是當你做這個副本時,你可能會同時得到兩個大的緩衝區:舊的和新的大小合適的。如果兩者都很大,那麼正如我所說的,GPU必須對它們進行管理,直到完成複製,此時可以釋放第一個緩衝區。我不知道孤兒。聽起來不錯。 – user18490 2014-09-18 19:33:33
@ BenVoigt:這不是OpenGL的建議,而是實現頁面內存分配器的一個很好的實踐。我在此提及有關內存分配器主題的大量出版物。最後歸結爲每個OpenGL對象都可以交換到主機內存的事實。因此,有效的內存塊粒度(這是您的程序「感覺」的)是主機系統頁面大小或GPU分頁大小中的較大者。即使GPU頁面更小,因爲內存事務發生在主機頁面上,這就是你最終得到的結果。 – datenwolf 2014-09-18 21:49:38