索引緩沖對象(EBO或IBO )的理解


索引緩沖對象(Element Buffer Object,EBO,也叫Index Buffer Object,IBO)

以一個具體的例子來說明這是個啥東西。

我之前畫過一個四面體,頂點坐標如下:

static GLfloat vertices[] = {
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 0.0f, 1.0f,

    0.0f, 0.0f, 1.0f, 1.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,

    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f,

    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f,

};

可以看到真正獨立的點就4個而已,但是一個一個三角形的存儲,一共會產生8次重復 ,重復就意味着巨大的存儲開銷和性能的浪費,當我們的模型的三角形更多的時候,這個問題會更加的嚴重。一個好的解決方案是,我們只存儲4個頂點,然后指定繪制順序,讓GPU按照指定的順序去繪制就可以了。索引繪制(Indexed Drawing 正是我們解決問題的方案)

 

首先,我們先要定義(不重復的)頂點,和繪制出矩形所需的索引:

static GLfloat vertices[] = {
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f
}
unsigned int indices[] = {
// 注意索引從0開始!
0, 1, 2, // 第一個三角形
0, 2, 3 // 第二個三角形
0, 1, 3 // 第三個三角形
1, 2, 3 // 第四個三角形
};

 下一步我們需要創建索引緩沖對象:

unsigned int mEBO;
glGenBuffers(1, &mEBO); 

 與VBO類似,我們先綁定EBO然后用glBufferData把索引復制到緩沖里。同樣,和VBO類似,我們會把這些函數調用放在綁定和解綁函數調用之間,只不過這次我們把緩沖的類型定義為GL_ELEMENT_ARRAY_BUFFER (vbo的這個地方是GL_ARRAY_BUFFER)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEBO);
giBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),   indices, GL_STATIC_DRAW );

 要注意的是,我們傳遞了GL_ELEMENT_ARRAY_BUFFER當作緩沖目標。最后一件要做的事是用glDrawElements來替換glDrawArrays函數,來指明我們從索引緩沖渲染。使用glDrawElements時,我們會使用當前綁定的索引緩沖對象中的索引進行繪制:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

 我們前面說過VAO內綁定了VBO, VAO同樣也可以綁定EBO. 這樣我們綁定VAO后,內部會自動幫我們綁定到對應的EBO上.

【需要注意的是:索引的存在只是說幫我們節省了頂點數組的size,減少了很多重復,但是該畫的三角形是一個也沒少】

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM