1. 程式人生 > >Android OpenGL ES學習筆記之常用API

Android OpenGL ES學習筆記之常用API

上一篇文章Android OpenGL ES學習筆記之繪製點涉及到了一些API,在這篇文章配合一些例項給大家詳細的講解下,會持續更新。

我這裡有OpenGl ES 的API中文文件,不過不全,可以配合著看
開啟連結
密碼:gjlz

一、緩衝區

在OpenGL ES 中存在著三種緩衝區

- 顏色緩衝區(COLOR_BUFFER) ————也叫幀緩衝區(FRAME_BUFFER),包含了顏色索引或者RGBA顏色資料

- 深度緩衝區(DEPTH_BUFFER) ————儲存每個畫素的深度值,當啟動深度測試時,片段畫素深度值和深度緩衝區深度值進行比較,決定片段哪些畫素點資料可以替換到顏色緩衝區中

- 模板緩衝區 (STENCIL_BUFFER)————與深度緩衝大小相同,通過設定模版緩衝每個畫素的值,我們可以指定在渲染的時候只渲染某些畫素,從而可以達到一些特殊的效果

glClearColor

含義:設定顏色緩衝區的清理值

glClearColor(float red, float green, float blue, float alpha) 指明紅、綠、藍、alpha 的值並通過glClear 來清理顏色緩衝區,被glClearColor 指明的值屬於區間[0, 1]。

glClearDepth

含義:設定深度緩衝區的清理值

glClearDepth(float depth) 方法指明深度值,並通過glClear 來清理深度緩衝區。glClearDepth 指明的值屬於區間[0, 1]。深度值大於預設值的畫素不會被繪製出來

glClearStencil

含義:設定模板緩衝區的清理值

glClearStencil(int s) 方法設定模板緩衝區時的索引值,s 為2m-1,其中m是模板緩衝區中的bit 數。

glClear

含義:清理緩衝區,並設定為預設值。

glClear(int mask) 方法設定模板緩衝區時的索引值,s 為2m-1,其中m是模板緩衝區中的bit 數。

mask的值有以下三種

 - GL_COLOR_BUFFER_BIT:表明顏色緩衝區。

 - GL_DEPTH_BUFFER_BIT:表明深度緩衝區。

 - GL_STENCIL_BUFFER_BIT:表明模型緩衝區。

比如同時清理顏色緩衝區和深度緩衝區,可以這樣寫。

gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);

二、開啟和關閉功能

glEnable

含義:啟用伺服器端GL 功能。

glEnable(int cap)和glDisable (int cap)方法可以啟用和禁止服務端各種功能。
舉例:

 - GL_ALPHA_TEST————如果啟用,將進行alpha 測試

 - GL_DEPTH_TEST————如果啟用,將進行深度 測試

 - GL_BLEND————如果啟用,將引入的值與顏色緩衝區中的值混合

glEnableClientState

含義:啟用客戶端的某項功能。

glEnableClientState(int array) 和glDisableClientState(int array) 啟用或禁用客戶端的單個功能。預設的,所有客戶端功能禁用。

 - GL_VERTEX_ARRAY ——如果啟用,頂點矩陣可以用來寫入

 - GL_COLOR_ARRAY————如果啟用,顏色矩陣可以用來寫入

 - GL_NORMAL_ARRAY—— 如果啟用,  法線矩陣可以用來寫入

 - GL_TEXTURE_COORD_ARRAY——如果啟用,紋理座標矩陣可以用來寫入

 - GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果啟用,點大小矩陣控制大小以渲染點和點sprites。這時由glPointSize 定義的點大小將被忽略,由點大小矩陣提供的大小將被用來渲染點和點sprites。

glEnable和glEnableClientState的區別

這兩者的區別應該說是服務端和客戶端的區別,glEnable和glDisable是管理服務端功能,glEnableClientState 和glDisableClientState是管理客戶端功能。客戶端和服務端是如下定義的

 - 客戶端:計算機上的具體程式,包括它用到的記憶體等等

 - 服務端:計算機顯卡里的OpenGL“模組”,乃至整張擁有OpenGL流水線、硬體實現OpenGL功能的顯示卡

三、深度測試

1、什麼是深度

深度其實就是該畫素點在3d世界中距離攝象機的距離 , 深度值越大,則離攝像機越遠。攝像機可能放在座標系的任何位置,不能簡單地說畫素的z座標越大或越小就是越靠近攝像機。

2、什麼是深度測試

在不使用深度測試的時候,如果我們先繪製一個距離較近的物體,再繪製距離較遠的物體,則距離遠的物體因為後繪製,會把距離近的物體覆蓋掉,這樣的效果並不是我們所希望的。比如下圖中的A、B

這裡寫圖片描述

先繪製A,再繪製B,A就有一部分被B擋住。而有了深度緩衝以後,繪製物體的順序就不那麼重要了,都能按照遠近(Z值)正常顯示

3、啟動深度測試

啟動深度測試需要開啟深度測試功能,呼叫glEnable(GL_DEPTH_TEST)開啟,然後呼叫glDepthFunc(int func)方法指定深度測試模式。func可取以下值:

 - GL10.GL_NEVER:不通過

 - GL10.GL_LESS:如果輸入的深度值小於參考值,則通過

 - GL10.GL_EQUAL:如果輸入的深度值等於參考值,則通過

 - GL10.GL_LEQUAL:如果輸入的深度值小於或等於參考值,則通過

 - GL10.GL_GREATER :如果輸入的深度值大於參考值,則通過

 - GL10.GL_GEQUAL:如果輸入的深度值大於或等於參考值,則通過

 - GL10.GL_ALWAYS:總是通過

通過表示會繪製,否則不繪製。

例子

建立一個頂點陣列

        //頂點陣列
        private float[] mArray = { 0f, 0f, 0.5f };

在onSurfaceChanged裡設定深度值為0.1f

        // Surface建立的時候呼叫
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // 設定清屏顏色為黑色
            gl.glClearColor(0f, 0f, 0f, 0f);
            // 設定深度
            gl.glClearDepthf(0.1f);

            }

然後在onDrawFrame裡繪製

        // 在Surface上繪製的時候呼叫
        @Override
        public void onDrawFrame(GL10 gl) {

            // 清除螢幕 
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);

            // 允許設定頂點 // GL10.GL_VERTEX_ARRAY頂點陣列
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

            //開啟深度測試
            gl.glEnable(GL10.GL_DEPTH_TEST);

            //指定深度測試模式
             gl.glDepthFunc(GL10.GL_GREATER);

            // 設定頂點
            gl.glVertexPointer(1, GL10.GL_FLOAT, 0, mBuffer);

            //設定點的顏色為綠色
            gl.glColor4f(0f, 1f, 0f, 0f);

            //設定點的大小
            gl.glPointSize(80f);

            // 繪製點
            gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

            //關閉深度測試
            gl.glDisable(GL10.GL_DEPTH_TEST);

            // 取消頂點設定
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        }
    }

指定深度測試模式為GL_GREATER,即如果輸入的深度值大於參考值,則通過。這裡0.5>0.1,通過,看下效果

這裡寫圖片描述

把深度設定為1f

        // Surface建立的時候呼叫
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // 設定清屏顏色為黑色
            gl.glClearColor(0f, 0f, 0f, 0f);
            // 設定深度
            gl.glClearDepthf(1f);

            }

此時0.5<1,不通過,看下效果,沒繪製出來。

這裡寫圖片描述