《OpenGL ES 3.x游戏开发(下卷)》一1.2 顶点数组对象
本節書摘來異步社區《OpenGL ES 3.x游戲開發(下卷)》一書中的第1章,第1.2節,作者: 吳亞峰 責編: 張濤,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。
1.2 頂點數組對象
使用了頂點緩沖技術后,繪制效率有了較大的提升。但是還有一點不盡如人意,那就是頂點的位置坐標、法向量、紋理坐標等不同方面的數據每次使用時需要單獨指定,重復了一些不必要的工作。OpenGL ES 3.0考慮到了這一點,提供了一種專門用于解決此問題的對象——頂點數組對象(VAO)。本節將介紹頂點數組對象。
1.2.1 基本知識與案例效果
頂點數組對象的主要功能就是將繪制一個物體時所需的對應于不同方面(如頂點坐標、法向量、紋理坐標)的頂點緩沖及相關設置包裝成一個整體,繪制時直接使用頂點數組對象即可,不必分別使用每個頂點緩沖,這可以進一步提高繪制效率。
了解了頂點數組對象的主要功能后,下面介紹兩個與使用頂點數組對象相關的方法(這兩個方法也是通過GLES30類進行調用),具體內容如下。
- glGenVertexArrays方法
glGenVertexArrays方法主要用于創建新的頂點數組對象,該方法的具體簽名如下。
1 public static void glGenVertexArrays (int n, int[] arrays, int offset)說明
參數n為需要創建的頂點數組對象的數量,參數arrays用來存放創建的n個頂點數組對象的編號,參數offset為arrays數組的偏移量。
- glBindVertexArray方法
創建頂點數組對象之后,就可以用glBindVertexArray方法綁定指定的頂點數組對象,以便對指定的頂點數組對象進行設置或使用,其方法簽名如下。
1 public static void glBindVertexArray (int array)說明
參數array為需要綁定的頂點數組對象的編號。用glBindVertexArray方法綁定頂點數組對象之后,更改頂點數組狀態的后續調用(如glBindBuffer、glVertexAttribPointer、glEnableVertexAttribArray和glDisableVertexAttribArray等)將影響綁定的頂點數組對象。通過綁定不同的頂點數組對象,繪制時應用程序可以快速在不同頂點數組配置之間進行切換(只需一句代碼即可),大大提高了開發效率。
了解了頂點數組對象的一些基本知識以后,下面來了解一下本節案例Sample1_2的運行效果,具體情況如圖1-2所示。
提示
運行本案例時,當手指在屏幕上上下左右滑動時,相應的物體也會繞x軸和y軸旋轉。
1.2.2 案例開發步驟
了解了頂點數組對象的基本知識以及本節案例的運行效果后,就可以進行案例的開發了。由于案例Sample1_2是在案例Sample1_1的基礎上修改而來的,所以這里僅給出相關的修改部分,具體步驟如下。
(1)首先介紹的是用于初始化頂點數組對象的方法initVAO,此方法用于在繪制之前一次性對頂點數組對象進行初始化,其具體代碼如下。
1 public void initVAO(){ 2 int[] vaoIds=new int[1]; //用于存放頂點數組對象編號的數組 3 GLES30.glGenVertexArrays(1, vaoIds, 0); //創建一個頂點數組對象 4 vaoId=vaoIds[0]; //獲取將創建的頂點數組對象編號 5 GLES30.glBindVertexArray(vaoId); //綁定頂點數組對象 6 GLES30.glEnableVertexAttribArray(maPositionHandle); //啟用頂點位置數據數組 7 GLES30.glEnableVertexAttribArray(maNormalHandle); //啟用法向量數據數組 8 GLES30.glEnableVertexAttribArray(maTexCoorHandle); //啟用紋理坐標數據數組 9 //綁定到頂點坐標數據緩沖 10 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferId); 11 //指定頂點位置數據使用對應緩沖 12 GLES30.glVertexAttribPointer(maPositionHandle, 3, GLES30.GL_FLOAT,false,3*4,0); 13 //綁定到頂點法向量數據緩沖 14 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mNormalBufferId); 15 //指定頂點法向量數據使用對應緩沖 16 GLES30.glVertexAttribPointer (maNormalHandle, 3,GLES30.GL_FLOAT, false,3*4,0); 17 //綁定到頂點紋理坐標數據緩沖 18 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mTexCoorBufferId); 19 //指定頂點紋理坐標數據使用對應緩沖 20 GLES30.glVertexAttribPointer(maTexCoorHandle,2,GLES30.GL_FLOAT,false,2*4,0); 21 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0); //綁定到系統默認緩沖 22 GLES30.glBindVertexArray(0); //綁定到系統默認頂點數組對象 23 }提示
上述initVAO方法主要用于創建并初始化頂點數組對象,包括生成VAO,綁定VAO,啟用頂點位置、法向量、紋理坐標數據數組,然后依次將頂點坐標數據、頂點法向量數據以及頂點紋理坐標數據指定到相應的緩沖,最后綁定到系統默認的緩沖以及系統默認的頂點數組對象,此方法在初始化頂點數據時調用一次。
(2)接下來將要介紹的是用于繪制物體的方法drawSelf,該方法與案例Sample1_1中對應的方法有所不同。此處的繪制方法功能更為簡單,省略了在繪制時一一綁定所需的頂點緩沖,并為不同數據(頂點坐標、法向量、紋理坐標)一一指定緩沖的代碼,其具體代碼如下。
1 public void drawSelf(int texId){ 2 GLES30.glUseProgram(mProgram); //指定使用某套著色器程序 3 //將最終變換矩陣傳入渲染管線 4 GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0); 5 //將基本變換矩陣傳入渲染管線 6 GLES30.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0); 7 //將光源位置傳入渲染管線 8 GLES30.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB); 9 //將攝像機位置傳入渲染管線 10 GLES30.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB); 11 GLES30.glBindVertexArray(vaoId); //綁定頂點數組對象 12 GLES30.glActiveTexture(GLES30.GL_TEXTURE0); //激活紋理 13 GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, texId); //綁定紋理 14 GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vCount); //繪制加載的物體 15 GLES30.glBindVertexArray(0); //綁定到系統默認的頂點數組對象 16 }說明
該繪制方法的功能主要為指定使用某套著色器程序,將最終變換矩陣、基本變換矩陣、光源位置及攝像機位置等數據送入渲染管線,并綁定頂點數組對象,激活和綁定紋理,繪制物體之后綁定到系統默認的頂點數組對象。從與案例Sample1_1中的drawSelf方法進行對比可以看出,其代碼更短,開發成本更低,讀者在實際開發中應該盡量選用。
總結
以上是生活随笔為你收集整理的《OpenGL ES 3.x游戏开发(下卷)》一1.2 顶点数组对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Access 2007开发指南(修订版
- 下一篇: Apache Spark机器学习.1.7