1. 程式人生 > >OpenGL加速渲染:頂點陣列的索引模式

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

/glEnd之間呼叫。

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:指向索引陣列首地址