opengl 为免费的2D 3D图形api软件库,在android上应用的是一个分支子集 opengl es,可能在平常使用中少有接触到这些个api,一般的app层面操控接触的都是view层面,往下构建一个surface 绘制 合成 送显 又是一门大学问了可参考:Android——图形系统
就我目前的理解,opengl es 在应用的绘制过程以及系统合成部分都会调用到,可以从systrace 看应用进程的opengl追踪
撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/50235511本文来自 【jscese】的博客!
可以跳过android framework的一系列封装,直接在app中使用opengl es的接口 进行编程,可作为学习了解opengl的有效途径。
概念关系
首先要在app控制的进程里面进行图像显示,需要给app一个容器进行显示,由要方便操作者个容器,一般都选择GLSurfaceView,从名字可以看出来这个类必然封装实现了一些opengl相关的方法
有了容器,还需要构建一个renderer ,也可理解为渲染器 用来绘制上面的GLSurfaceView
两者成对使用,并且GLSurfaceView类中就构建了回调接口 Renderer
下面以一个opengl_simple app依次记录说明
AndroidManifest.xml
首先需要添加特殊feature:
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
还有的可能需要添加texture处理,压缩的格式声明之类的,没用到,先不管
整个文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jscese.opengl_simple">
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Opengl">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
构建GLSurfaceView
public class Myglsurfaceview extends GLSurfaceView {
private Myglrender mglrender=null;
public Myglsurfaceview(Context context) {
super(context);
try {
setEGLContextClientVersion(2); //需要指定version
mglrender=new Myglrender();
setRenderer(mglrender); //在构建的GLSurfaceView 构造中就绑定一个renderer
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); //设置上面绑定renderer的绘图模式
}catch (Exception E)
{
E.printStackTrace();
}
}
}
renderer的绘图模式分两种
可以看下源码注释,清晰明了:
/**
* The renderer only renders
* when the surface is created, or when {@link #requestRender} is called.
*
* @see #getRenderMode()
* @see #setRenderMode(int)
* @see #requestRender()
*/
public final static int RENDERMODE_WHEN_DIRTY = 0;
/**
* The renderer is called
* continuously to re-render the scene.
*
* @see #getRenderMode()
* @see #setRenderMode(int)
*/
public final static int RENDERMODE_CONTINUOUSLY = 1;
如果不主动进行设置为 dirty 模式,那么默认就会是continuously 模式,此时会持续不断的进行绘图,占用资源:
构建renderer
上面看到了 GLSurfaceView 绑定了一个renderer ,构建成如下:
public class Myglrender implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
}
需要实现接口的3个回调方法,具体的调用时机以及含义可参考
\frameworks\base\opengl\java\android\opengl\GLSurfaceView.java中的Renderer接口
大体的时机:
onSurfaceCreated() - Called once to set up the view's OpenGL ES environment.
onDrawFrame() - Called for each redraw of the view.
onSurfaceChanged() - Called if the geometry of the view changes, for example when the device's screen orientation changes.
实际第一次的调用顺序 onSurfaceCreated()——> onSurfaceChanged() ——> onDrawFrame()
GL api 调用
上面看到调用方式为 GLES20类直接调用glXXX 函数
类路径:\frameworks\base\opengl\java\android\opengl\GLES20.java
opengl es的等一系列初始化在之前就已经初始化好,这里直接调用静态方法接口即可
这里调用的接口含义:
public void glClearColor(floatred,floatgreen,floatblue,floatalpha)
功能:指定颜色缓冲区的清理值
详细:glClearColor 指明红、绿、蓝、alpha 的值并通过glClear 来清理颜色缓冲区,
被glClearColor 指明的值属于区间[0, 1]。
参数:
red——指明颜色缓冲区被清理时红色的值,初始值为0。
green——指明颜色缓冲区被清理时绿色的值,初始值为0。
blue——指明颜色缓冲区被清理时蓝色的值,初始值为0。
alpha——指明颜色缓冲区被清理时alpha 的值,初始值为0。
RGB - 0.5f, 0.5f, 0.5f 全相等比重 合成即为中等灰色
RGB - 1.0f, 1.0f, 1.0f 即为白色
RGB - 0.0f, 0.0f, 0.0f 即为黑色
public void glViewport(intx,inty,intwidth,intheight)
功能:
设置一个视口
错误:
如果宽、高为负数,将产生GL_INVALID_VALUE
参数:
x——指明视口矩形的左下角x坐标,初始值为0。
y——指明视口矩形的左下角y坐标,初始值为0。
width——指明视口的宽,如果GL上下文首次附于一个surface 则宽、高为这个
surface 大小。
height——指明视口的高,如果GL上下文首次附于一个surface 则宽、高为这个
surface 大小。
这里即为surfaceview的宽高,默认也就是设备的宽高
public void glClear(intmask)
功能:
清理缓冲区,并设置为预设值。
详细:
glClear 设置窗口位面区的值,该值由glClearColor, glClearDepth 和 glClearStencil
等方法选择出。
像素所有权测试、裁剪测试、抖动、颜色缓冲区掩饰将影响glClear 操作,裁剪盒
绑定清理区域。Alpha 功能、混合功能、逻辑操作、建模、纹理映射以及深度缓冲
区会被glClear 操作忽略。
glClear 可以使参数为多个值按位与后的结果,以表明那个缓冲区需要清理。
有如下值:
GL_COLOR_BUFFER_BIT:表明颜色缓冲区。
GL_DEPTH_BUFFER_BIT:表明深度缓冲区。
GL_STENCIL_BUFFER_BIT:表明模型缓冲区。
这里就是清理一次color 缓冲区,而color缓冲区在前面设置了指定的颜色值,所以整个viewport指定的区域会成为:
具体的代码就不贴了。。。 后面继续