上一篇文章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,不通过,看下效果,没绘制出来。