1、背景
本文我们基于最基础,最简单的OpenGL API,最终实现三角形的绘制(基于OpenGL 1.0 Java接口)。本文只对OpenGL相关接口使用进行介绍,深入原理后续逐步剖析。
2、Android OpenGL环境搭建
Android为我们提供了SurfaceView,可以在一个新启的单独线程中可以重新绘制画面,GLSurfaceView在SurfaceView的基础上绑定了OpenGL相关环境。工作中我们用到这两个控件主要是播放视频,预览摄像头画面,今天我们使用GLSurfaceView调用OpenGL相关接口进行绘制。
首先,GLSurfaceView的创建和普通View没区别:GLSurfaceView view = new GlSurfaceView(context);
接着,我们需要为GLSurfaceView设置渲染器GLSurfaceView.Renderer
:view.setRenderer(renderer)
。
GLSurfaceView.Renderer
是一个接口,要实现这个接口需要实现三个方法:
public class MyRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl) {
}
这三个方法的调用时机:
- onSurfaceCreated是GLSurfaceView被创建时,调用线程是GL线程;
- onSurfaceChanged是GLSurfaceVIew大小发生改变时,比如收到虚拟按键隐藏显示等影响导致大小发生改变;
onDrawFrame是真正的执行,GLSurfaceView可以通过
setRenderMode
设置渲染模式,有两种渲染模式:- RENDERMODE_WHEN_DIRTY:脏渲染,命令渲染,只有surface被创建时或者我们主动调用
requestRender
时才会触发onDrawFrame
方法回调; - RENDERMODE_CONTINUOUSLY:持续渲染,GL线程会持续的调用
onDrawFrame
进行绘制。
- RENDERMODE_WHEN_DIRTY:脏渲染,命令渲染,只有surface被创建时或者我们主动调用
接下来我们实现这三个接口就可以进行具体绘制了。
3、绘制步骤
3.1 onSurfaceCreated
在onSurfaceCreate
中做一些一次性操作:
- 设置清屏色:
gl.glClearColor(0f, 0f, 0f, 1f);
,代表整个背景的颜色,最小0,最大1,四个参数分别代表R、G、B、A分量; - 启用顶点缓存:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
,glEnableClientState 和 glDisableClientState 启用或禁用单个客户端功能。默认情况下,禁用所有客户端功能,我们这里会用到顶点缓存,所以需要手动开启。
3.2 onSurfaceChanged
onSurfaceChange
回调时拿到了实际渲染窗口大小,可以:
- 设置视口大小:
gl.glViewport(0, 0, width, height);
设置投影矩阵:
- 设置投影矩阵:
gl.glMatrixMode(GL10.GL_PROJECTION);
- 加载单位矩阵,重置投影矩阵:
gl.glLoadIdentity();
- 设置平截头体:
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
,前四个参数代表近平面(左右下上),后面两个参数分别代表近平面Z坐标值。
- 设置投影矩阵:
3.3 onDrawFrame
每次绘制时我们要做一些事情:
- 清除颜色缓冲区和深度缓冲区:
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
- 加载模型视图矩阵:
gl.glMatrixMode(GL10.GL_MODELVIEW);
- 加载单位矩阵,重置模型视图矩阵:
gl.glLoadIdentity();
- 设置摄像机/眼睛坐标:
GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0f, 1f, 0f);
分别代表摄像机XYZ坐标、朝向XYZ坐标、朝上XYZ坐标 - 设置绘制颜色:
gl.glColor4f(1f, 0f, 0f, 1f);
,这里我们设置为红色 - 设置三角形顶点集合:
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,buffer);
,第一个参数代表每个点多少个type,第二个参数代表每个点表达数据类型,第三个参数步幅,这里是0,buffer是java.nio.Buffer,存放顶点坐标数据 - 绘制三角形:
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
3.4 效果展示
用到的顶点坐标:
float[] vertexCoords = {
0.2f,0f,0f,
0.6f,0f,0f,
0.4f,0.5f,0f
}
4、总结
本文介绍了Android系统提供的GLSurfaceView的用法及绘制一个最基本的图像:三角形用到的API:设置清屏色、启用顶点缓存、设置视口、设置投影矩阵等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。