1. 程式人生 > >OpenGL ES中的頂點陣列、頂點屬性、緩衝區物件

OpenGL ES中的頂點陣列、頂點屬性、緩衝區物件

什麼是頂點資料?

在計算機中圖元的位置是通過x,y,z,w來儲存或顏色資料是通過RGBA的陣列格式儲存的,然後通過多個點來進行圖元裝配和光柵化出圖形.比如三角形3個點使用X,Y,Z表示如下:

  GLfloat vertex[]={
            0.0f,1.0f,1.0f, //x,y,z
            1.0f,0.5f,1.0f,
            0.0f,0.5f,1.0f            
            }

頂點屬性陣列

頂點屬性陣列物件就是儲存在應用程式緩衝區的頂點資料,又分兩種方式來分配和儲存頂點屬性陣列:結構陣列和資料結構,結構陣列就是所有頂點資料使用一個數組來儲存資料,把位置、顏色、法線、紋理UV座標等資料放進一個數組結構中.陣列結構就是把每個資料通過不同的陣列結構存放頂點資料.結構陣列的效率要高於陣列結構,因為在通過結構陣列的方式訪問頂點資料是按照在記憶體中的順序來訪問的.缺點是修改了其中的資料必須重新更新已經儲存在緩衝區中資料的跨距.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define VERTEX_POS_INDX 0
#define VERTEX_POS_SIZE 3

#define VERTEX_COLOR_INDX 1
#define VERTEX_COLOR_SIZE 4

#define VERTEX_ATTRIB_SIZE (VERTEX_POS_SIZE+VERTEX_COLOR_SIZE)

GLfloat vertex[]={
                        0.0f,1.0f
,1.0f, //x,y,z
1.0f,0.0f,0.0f,1.0f, //RGBA 1.0f,0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f, 0.0f,0.5f,1.0f, 0.0f,0.0f,1.0f,1.0f } //設定頂點位置屬性資料陣列 glVertexAttribPointer(VERTEX_POS_INDX,VERTEX_POS_SIZE,GL_FLOAT,GL_FALSE,VERTEX_ATTRIB_SIZE*sizeof(GLfloat),vertex); //設定顏色屬性資料陣列 glVertexAttribPointer(VERTEX_COLOR_INDX,VERTEX_COLOR_SIZE,GL_FLOAT,GL_FALSE,(VERTEX_ATTRIB_SIZE*sizeof
(GLfloat),vertex+VERTEX_POS_SIZE));
//啟用頂點陣列資料 glEableVertexAttribArray(VERTEX_POS_INDE); glEnableVertexAttribArray(VERTEX_COLOR_INDE); //根據頂點資料繪製三角形 glDrawArrays(GL_TRIANGLES,0,3); //禁用頂點陣列資料 glDisableVertexAttribArray(VERTEX_POS_INDE); glDisableVertexAttribArray(VERTEX_COLOR_INDE);

頂點緩衝區物件

簡單點說就是把圖形頂點資料和索引資料快取在圖形裝置記憶體GPU中,改善每次繪製圖形都要複製應用程式中的頂點資料.緩衝區頂點資料物件分為兩種:1.圖元索引資料(GL_ELEMENT_ARRAY_BUFFER)和頂點資料(GL_ARRAY_BUFFER).

使用緩衝衝區頂點物件的步驟:

1. 分配緩衝區物件:glGenBuffer
2. 繫結緩衝區物件:glBindBuffer,第一次呼叫為分配空間,以後呼叫都是使用緩衝區物件.
3. 儲存資料到緩衝區物件: glBufferData
4. 刪除緩衝區物件:glDeleteBuffers,在不需要使用緩衝區物件的時候刪除.

拿上邊三角形的頂點陣列資料來說,程式碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
......................

GLunit buffer[2];
glGenBuffer(2,&buffer);
//繫結頂點資料到緩衝區物件
glBindBuffer(GL_ARRAY_BUFFER,buffer[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertex),vertex,GL_STATIC_DRAW);
//繫結頂點索引資料到緩衝區物件
GLShort indices[3]={0,1,2};
glBindBuffer(GL_ELEMENTS_ARRAY_BUFFER,buffer[1]);
glBufferData(GL_ELEMENTS_ARRAY_BUFFER,sizeof(GLShort)*3,indices,GL_STATIC_DRAW);

//使用緩衝區物件
glBindBuffer(GL_ARRAY_BUFFER,buffer[0]);
glEnableVertexAttibArray(VERTEX_POS_INDX);
glVertexAttribPointer(VERTEX_POS_INDX,VERTEX_POS_SIZE,GL_FLOAT,GL_FALSE,(VERTEX_ATTRIB_SIZE*sizeof(GLfloat)),(const void*)0);

glVertexAttribPointer(VERTEX_COLOR_INDX,VERTEX_COLOR_SIZE,GL_FLOAT,GL_FALSE,(VERTEX_ATTRIB_SIZE*sizeof(GLfloat),(cons void*)(VERTEX_POS_SIZE*sizeof(GLfloat)));

................

glDeleteBuffers刪除已經存在的緩衝區物件

頂點陣列物件(VAO)

這個特性是在opengl es3.0 中引入的,提供包含在頂點陣列/頂點緩衝區物件配置之間切換所需要的所有狀態的單一物件.只需要在設定緩衝區資料的時候glGenVertexArrays一個頂點陣列物件ID,然後呼叫glBindVertexArray繫結已經生成陣列物件的ID,在繪製圖元的時候呼叫glBindVertexArray切換相應緩衝區內的資料並進行繪製.glDeleteVertexArray刪除一個或者多個頂點陣列物件.

對映緩衝區物件

應用程式設定緩衝區物件資料呼叫glBufferData的時候,可以將緩衝區物件資料儲存對映到應用程式的記憶體地址空間,優點:減少應用程式的記憶體佔用,只需要儲存資料的一個副本.避免資料複製步驟通過映射出的GPU儲存緩衝區物件的記憶體地址.
呼叫glMapBufferRange返回緩衝區儲存資料範圍的指標,出現錯誤則反悔NULL,glUnmapBuffer取消之前緩衝區對映.

著色器中如何關聯頂點資料

  • 在頂點著色器原始碼中使用layout(location=N) in限定符來獲取頂點屬性的值