頂點緩沖對象(Vertex Buffer Objects, VBO)管理這個內存,它會在GPU內存(通常被稱為顯存)中儲存大量頂點。使用VBO的好處是我們可以一次性的發送一大批數據到顯卡上,而不是每個頂點發送一次。
頂點數組對象(Vertex Array Object, VAO)可以像頂點緩沖對象那樣被綁定,任何 隨后的頂點屬性調用 都會儲存在這個VAO中。說白了就是緩存glVertexAttribPointer()函數的結果。
這樣的好處就是,當配置頂點屬性指針時,你只需要將那些調用執行一次,之后再繪制物體的時候只需要綁定相應的VAO就行了。
索引緩沖對象(Element Buffer Object,EBO,也叫Index Buffer Object,IBO)
EBO也是一個緩沖,它專門儲存索引,OpenGL調用這些頂點的索引來決定該繪制哪個頂點。
下面記錄一下glVertexAttribPointer 函數的圖解。
glVertexAttribPointer(index,size,type,normalized,stride,pointer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
- 第一個參數指定我們要配置的頂點屬性。對應
layout(location = 0)
定義了position頂點屬性的位置值(Location)。它可以把頂點屬性的位置值設置為0
。因為我們希望把數據傳遞到這一個頂點屬性中,所以這里我們傳入0
。 - 第二個參數指定頂點屬性的大小。頂點屬性是一個
vec3
,它由3個值組成,所以大小是3。 - 第三個參數指定數據的類型,這里是GL_FLOAT(GLSL中
vec*
都是由浮點數值組成的)。 - 第四個參數定義我們是否希望數據被標准化(Normalize)。如果我們設置為GL_TRUE,所有數據都會被映射到0(對於有符號型signed數據是-1)到1之間。我們把它設置為GL_FALSE。
- 第五個參數叫做步長(Stride),它告訴我們在連續的頂點屬性組之間的間隔(多少字節數)。由於下個組位置數據在3個
float
之后,我們把步長設置為3 * sizeof(float)
。要注意的是由於我們知道這個數組是緊密排列的(在兩個頂點屬性之間沒有空隙)我們也可以設置為0來讓OpenGL決定具體步長是多少(只有當數值是緊密排列時才可用)。一旦我們有更多的頂點屬性,我們就必須更小心地定義每個頂點屬性之間的間隔。 - 最后一個參數的類型是
void*
,所以需要我們進行這個奇怪的強制類型轉換。它表示位置數據在緩沖中起始位置的偏移量(Offset)。由於位置數據在數組的開頭,所以這里是0。