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,不通過,看下效果,沒繪製出來。

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章