OpenGL加速渲染:頂點陣列的索引模式
使用頂點陣列時,往往要將所有需要使用的頂點放入陣列中,以便於統一呼叫。
比如一條折線:
GLfloat vPoints[] = { 0.0, 0.0, 0.0, //折線端點0
1.0, 0.0, 0.0, //折線端點1
1.0, 0.0, 0.0, //折線端點1
1.0, 1.0, 0.0 //折線端點2
};
在頂點陣列中,需要對端點1進行2次儲存,因為線段0是由端點0、端點1兩個端點構成,而線段1是由端點1、端點2兩個端點構成,必須順序儲存所有呼叫的點,才可以用glDrawArrays進行統一的呼叫。即glDrawArrays用於一次性將指定記憶體區間的所有點繪製出來,不可以使用索引。
當然,用glArrayElement來訪問單個元素可以避免該問題。但訪問單個元素效率較低。
為了既保證效率,又減少儲存空間,可以使用索引頂點陣列。
索引頂點陣列就是僅儲存所有必要點,然後額外建立一個用於索引的陣列。
同一條折線:
GLfloat vPoints[] = { 0.0, 0.0, 0.0, //折線端點0
1.0, 0.0, 0.0, //折線端點1
1.0, 1.0, 0.0 //折線端點2
};
GLuint indexs[] = { 0,1, //線段0端點0,1
1,2 //線段1端點1,2
};
這樣,就使用2個數組代替了原來的1個數組。
在繪製圖形較少的情況下,這樣做並不一定節省記憶體。但當繪製圖形非常多的時候,這種方式對記憶體的節省會很可觀。
陣列定義完成後,呼叫:
GLfloat vPoints[126];
對每個元素進行賦值。
glEnableClientState(GL_VERTEX_ARRAY); //啟用頂點陣列
glVertexPointer(3, GL_FLOAT, 0, vPoints); //設定頂點陣列屬性
glDrawElements(GL_LINES, 4, GL_UNSIGNED_INT, indexs);
其中,glDrawElements用於呼叫索引來繪製圖形。該函式不需要在glBegin
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
引數:
1. GLenum mode:指定繪製圖元的型別,取值為:GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP,GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP,GL_QUADS, GL_POLYGON
2. GLsizei count:為繪製圖元的數量乘上一個圖元的頂點數。也就是指所有繪製的圖元的頂點數之和。這裡2條線段,共4個頂點,所以這裡為4。在這個例子中這個引數等於索引陣列的元素個數。
3. GLenum type:為索引值的型別,取值為:GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT,GL_UNSIGNED_INT。注意GL_UNSIGNED_BYTE對應的值為unsigned byte,只有8位,其有效值最大僅為255。所以除非所繪圖形的頂點數小於255,否則不要用該值。推薦使用GL_UNSIGNED_INT。
4. const GLvoid *indices:指向索引陣列首地址