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