2011-06-17 16 views
3

所以,在寫一個模型裝載機的3D場景我工作的過程中,我決定收拾像這樣的頂點,紋理和正常數據:glVertexAttribPointer,交錯的元素和性能/緩存友好

VVVVTTTNNN 

對於每個頂點,其中V =頂點座標,T = UV座標,N =正常座標。當我傳遞到頂點着色器爲我的場景這個數據,我提出三點glVertexAttribPointer調用,就像這樣:

glVertexAttribPointer(ATTRIB_VERTEX, 4, GL_FLOAT, 0, 10, group->vertices.data); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 

glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, 0, 10, group->normals.data); 
glEnableVertexAttribArray(ATTRIB_NORMAL); 

glVertexAttribPointer(ATTRIB_UV_COORDINATES, 3, GL_FLOAT, 0, 10, group->uvcoordinates.data); 
glEnableVertexAttribArray(ATTRIB_UV_COORDINATES); 

各組指針傳遞的參考起始位置在共享頂點的數據塊,其中該頂點類型開始:對我來說這交錯數據的原因

group->vertices.data == data 
group->uvcoordinates.data == &data[4] 
group->normals.data == &data[7] 

一部分是程序緩存友好和儘量減少數據被髮送到卡上。 (注意:這不是一個現實的性能瓶頸,我正在研究優化,因爲我想了解更多關於編程以解決這些問題的方法。)但是,對於我的生活,我無法想象GL會如何能夠推斷出3個不同的指針指向相同較大數據塊內的偏移位置,並且因此進行必要的優化以避免在數據已經被複制之後複製該數據。此外,由於我只確保系統內存中的數據本地化(並且實際上並沒有任何有關如何在GPU上組織數據的保證),所以我只是真正優化用於訪問任何這些頂點在GL之外。是對的嗎?這些優化大多是無用的,還是以這種方式提供數據有助於最小化向GPU傳輸的數據/在頂點着色器中迭代頂點數據時防止緩存未命中?

回答

3

OpenGL只是一個API,智能在於驅動程序。無論如何,這個問題實際上相當簡單:對於每個頂點屬性,您都有一個起始內存地址,當調用glDrawArrays或glDrawElements時,會查找找到的最大索引。這定義了範圍的上限。

然後你排序頂點屬性的起始地址和每個地址檢查它的範圍是否與任何其他頂點屬性範圍重疊。你找到連續的區域並複製這些區域。

在頂點緩衝區對象的情況下,它更簡單,因爲您已經將東西複製到OpenGL以便處理。

+0

果然,甚至沒有考慮對地址進行排序。對,絕對重要的:維也納國際中心 - 只是對不同的方法感到好奇。謝謝! – 2011-06-17 22:17:32