文章轉至 OpenGL學習腳印: 使用索引繪圖(index drawing)
通過本節可以瞭解到
索引繪圖使用方法
索引繪圖應用場合
EBO即Element Buffer Objects,用來儲存繪製物體的索引。所謂索引就是對頂點屬性陣列中元素的一個位置標記。使用索引繪圖時,先通過頂點屬性陣列指定資料,然後利用指向這些資料的索引來指示OpenGL完成繪圖。使用索引繪圖的原理如下圖所示(來自VBO Indexing):
![使用索引繪圖(轉)](https://i.iter01.com/images/95336c5b5580b7d83641497745313c6c2a0353ec3bfa173d49c513a8ab40f128.png)
在左邊圖中,沒有使用索引繪製矩形時,要重複指定重疊的頂點資料,V1和V2都重複了,使用了6個頂點屬性資料;右邊的圖中,使用索引繪製時,只需要指定頂點在屬性陣列中的索引即可,使用0,1,2,3代表V0,V1,V2,V3頂點,繪製矩形一共指定了6個索引,使用4個頂點屬性資料。
上面的例子可能看不出有大區別,但是當要繪製的物體包含多個重疊的頂點時,如果每個頂點屬性包括了位置、顏色、紋理座標、法向量等屬性,那麼將會造成很大的額外空間開銷,影響GPU效能。同時,如果需要修改一個頂點處的資料,那麼重複的頂點資料都要被改過來,這個工作也很無趣。因此,使用索引繪製能夠節省儲存空間,而且能靈活應對頂點屬性的改變。
不使用索引也可以繪製矩形,我們使用6個頂點,資料如下:
GLfloat vertices[] = {// 第一個三角形
-0.5f,0.0f,0.0f,1.0f,0.0f,
0.0f,0.5f,0.0f,0.0f,0.0f,
1.0f,0.0f,0.0f,0.5f,0.0f,0.0f,0.0f,1.0f,// 第二個三角形-0.5f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f, -0.5f,0.0f,1.0f,1.0f,0.0f,0.5f,0.0f,0.0f,0.0f,1.0f,0.0f, };
然後在繪製時更新頂點數目即可:
glDrawArrays(GL_TRIANGLES,0,6);
1
1
下面介紹使用索引的繪製方法。我們需要在VBO中儲存頂點屬性資料,這在上一節已經介紹了。另一方面,就是使用EBO儲存索引資料。我們重新指定頂點資料和索引資料如下:
// 指定頂點屬性資料 頂點位置 顏色
GLfloat vertices[] = {
-0.5f,0.0f,0.0f,1.0f,0.0f,0.0f,//
00.5f,0.0f,0.0f,0.0f,1.0f,0.0f,//
10.0f,0.5f,0.0f,0.0f,0.0f,1.0f,//
20.0f, -0.5f,0.0f,1.0f,1.0f,0.0f// 3};//
索引資料GLshort indices[] = {
0,1,2,// 第一個三角形
0,3,1// 第二個三角形
};
建立EBO,並將索引資料傳送到EBO,如下:
glGenBuffers(1, &EBOId);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOId);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);
頂點屬性資料部分無需改動,在繪製物體時需要將glDrawArrays調整為glDrawElements.
APIvoid glDrawElements( GLenum mode,
GLsizei count,
GLenum type,
const GLvoid * indices);
1.引數mode 同glDrawArrays一樣表示繪製的基本圖元型別 GL_POINTS, GL_LINE_STRIP等。
2.引數count表示使用的EBO中索引元素的個數。
3.引數type 表示索引資料的資料型別。必須取 GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, 或者 GL_UNSIGNED_INT 三者之一。
4.indices 表示EBO中索引的偏移量。
這裡需要基本圖元型別為GL_TRIANGLES,使用6個索引,索引型別為GL_UNSIGNED_SHORT, 同時索引資料在EBO中起點處,indices引數為0. 繪製程式碼為:
glDrawElements(GL_TRIANGLES,6, GL_UNSIGNED_SHORT,0);
1
1