OpenGL狀態管理和繪製幾何物體之頂點陣列
阿新 • • 發佈:2019-01-02
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. 混合陣列 暫時省略