1. 程式人生 > >OpenGL狀態管理和繪製幾何物體之頂點陣列

OpenGL狀態管理和繪製幾何物體之頂點陣列

1. 頂點陣列可以減少函式呼叫次數, 還可以避免冗餘資料

2. 使用頂點陣列對幾何圖形進行渲染需要3個步驟

a. 啟用最多可達8個數組,每個陣列用於儲存不同型別的資料:頂點座標,表面法線,RGBA顏色,輔助顏色,顏色索引,霧座標,紋理座標以及多邊形的邊界標誌

b. 把資料放入陣列中。 即指標

c. 用這些資料繪製幾何圖形。 
	OpenGL通過指標從所有的被啟用的陣列中獲取資料。 

有1個函式呼叫多個數組的功能。 還有混合頂點陣列資料。 (可以每個陣列儲存一種不同型別的資料),也可以把不同型別的資料混合放在同一個陣列中。接下來將通過實際例子說明這些方法。 


一、最基本的建立

1. 啟用陣列
	呼叫glEnableClientState()函式, 啟用被選擇的陣列。 引數有8個可選擇,頂點座標,表面法線,RGBA顏色,輔助顏色,顏色索引,霧座標,紋理座標以及多邊形的邊界標誌。 

	例如:glEnableClientState(GL_NORMAL_ARRAY);

	注意,頂點陣列不可以放在顯示列表中,因為這些資料被儲存在客戶端。
2.  指定陣列的資料
	例如glVertexPointer(size, type, stride, *pointer);
	size是每個頂點的座標數量,必須2,3,4. stride是連續的頂點之間的位元組偏移量。如果stride是0,陣列中的頂點便是緊密相連的。 type是陣列中每個座標的資料型別。 pointer是陣列的指標。 當然可以指定8個型別的陣列,還是頂點座標,表面法線,RGBA顏色,輔助顏色,顏色索引,霧座標,紋理座標以及多邊形的邊界標誌。 

3. 解引用和渲染
在這一步,陣列中的資料被提取,接著傳送到伺服器,然後傳送到圖形管線進行渲染
	
a. 最簡單的是用glArrayElement(); ,會分別呼叫那8個對應的索引。 
static GLint vertices[] =
{
    25, -25, 100, 325, 175, 25, 175, 325, 250, 25, 325, 325
};

//
static GLfloat colors[] =
{
    1.0, 0.2, 0.2, 0.2, 0.2, 1.0, 0.8, 1.0, 0.2,
    0.75, 0.75, 0.75,
    0.35, 0.35, 0.35,
    0.5, 0.5, 0.5
};

void setUpPoints()
{
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    
    glColorPointer(3, GL_FLOAT, 0, colors);
    glVertexPointer(2, GL_INT, 0, vertices);
}

void init(void)
{
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);
    setUpPoints();
    
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();

    glBegin(GL_TRIANGLES);
	// 
    glArrayElement(2);
    glArrayElement(3);
    glArrayElement(5);
    glEnd();

    glPopMatrix();
    
   // glFlush();
    glutSwapBuffers();  
}


b. 解引用陣列元素中的一個列表
glDrawElements();

void setUpPoints()
{
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    
    glColorPointer(3, GL_FLOAT, 0, colors);
    glVertexPointer(2, GL_INT, 0, vertices);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    
    glDrawElements(GL_LINE_STRIP, 4, GL_UNSIGNED_BYTE, oneIndices);
    glPopMatrix();
   
    glutSwapBuffers();
    
}

注意: 每一個的enable 與資料要對應上, glDrawElement最後一個引數是索引的陣列


c.   glMultiDrawElements(); 其實就是合併了索引
	相當於
  	for (i=0; i<count; i++)
    {
        if(count[i]>0)
            glDrawElements(mode, count[i], type, indices[i]);
    }
d. glDrawRangeElements()
 	這個只是引入了索引值範圍限制。 這可以提高程式的效能。 提取的是有限的陣列。 

e. 解引用一個數組元素序列
	glDrawArrays()
	之前的都可以隨機進行存取,但這個只能按照順序訪問

f. glMultiDrawArrays
	把幾個glDrawArrays在一個函式裡進行呼叫


g. 混合陣列

暫時省略