在Android上运行OpenGL ES程序需要用到GLSurfaceView控件,GLSurfaceView继承自SurfaceView并实现了GLThread,通过OpenGL ES进行绘制。


OpenGL ES 环境搭建-LMLPHP




  • OpenGL ES1.0是基于OpenGL 1.3的,OpenGL ES1.1是基于OpenGL 1.5的。Android1.0和更高的版本支持这个API规范。OpenGL ES 1.x是针对固定硬件管线的。


  • OpenGL ES2.0是基于OpenGL 2.0的,不兼容OpenGL ES 1.x。Android 2.2(API 8)和更高的版本支持这个API规范。OpenGL ES 2.x是针对可编程硬件管线的。


  • OpenGL ES3.0的技术特性几乎完全来自OpenGL 3.x的,向下兼容OpenGL ES 2.x。Android 4.3(API 18)及更高的版本支持这个API规范。


  • OpenGL ES3.1基本上可以属于OpenGL 4.x的子集,向下兼容OpenGL ES3.0/2.0。Android 5.0(API 21)和更高的版本支持这个API规范。



OpenGL ES 环境搭建-LMLPHP




Android工程中OpenGL ES的版本在AndroidManifest.xml中指定:


0x00020000表示支持OpenGL ES 2.0。



在布局文件中添加GLSurfaceView,

在Activity中初始化GLSurfaceView,

OpenGL ES版本号和AndroidManifest.xml中版本号保持一致,当然我们也可以在设置版本之前判断当前设备是否支持设置的版本,下面的代码判断是支持ES 2.0版本。

setRenderMode方法是设置GLSurfaceView渲染模式,渲染模式有RENDERMODE_WHEN_DIRTY和RENDERMODE_CONTINUOUSLY两种,RENDERMODE_WHEN_DIRTY表示当需要的时候才渲染,只有在调用requestRender或者onResume等方法时才渲染,RENDERMODE_CONTINUOUSLY表示一直渲染。

setRenderMode一定要在setRenderer方法之后调用,另外一般需要在Activity或者Fragment的onPause和onResume生命周期中调用GLSurfaceView的onPause和onResume方法,节省系统资源。




Renderer必须实现GLSurfaceView.Renderer接口,并实现onSurfaceCreated ,onDrawFrame,onSurfaceChanged方法,OpenGL ES的渲染工作由此Renderer实现,MyRenderer的实现如下:

onSurfaceCreated ,onDrawFrame,onSurfaceChanged方法说明如下:

  • onSurfaceCreated:GLSurfaceView创建完成,也代表OpenGL ES环境创建完成,通常情况下在此方法中创建Program及初始化参数。


  • onSurfaceChanged:当Surface发生变化的时候回调,比如竖屏转横屏导致GLSurfaceView大小发生变化,通常情况下在此方法中设置绘制窗口及和GLSurfaceView大小有关系的参数。


  • onDrawFrame:执行OpenGL ES渲染工作,由系统以一定的频率来调用重绘View,当设置GLSurfaceView的渲染模式为GLSurfaceView.RENDERMODE_CONTINUOUSLY或不设置时,系统就会主动回调onDrawFrame()方法, 如果设置为 RENDERMODE_WHEN_DIRTY ,手动调用requestRender(),才会渲染。




OpenGL ES 环境搭建-LMLPHP



在OpenGL ES中Shader和Program是两个非常重要的概念,Program需要Vertex Shader(顶点Shader和Fragment Shader(片段Shader),Renderer的渲染就是在执行Program。


  • Vertex Shader(顶点Shader)处理顶点数据,对于发送给GPU的每一个顶点都要执行一次Vertex Shader,它的作用就是把顶点在虚拟空间中的三维坐标变换为屏幕上的二维坐标,并带有深度信息。


  • Fragment Shader计算每个像素的颜色和其他属性。它通过应用光照值、凹凸贴图,阴影,镜面高光,半透明等处理来计算像素的颜色并输出。




Shader可以以字符串形式存在也可以单独存放在文件中,建议写在assets目录下并以.glsl结尾,因为Android Studio安装GLSL插件可以高亮其代码,便于查找错误。


在assets下创建glsl文件夹,用于存放glsl文件,创建triangle_vertex.glsl文件,保存Vertex Shader代码:

获取你还看不懂这段代码,没关系,你只需要知道这段代码是处理顶点数据即可,GLSL 语言相关知识后面会介绍。

创建triangle_fragment.glsl文件,保存Fragment Shader代码:

上面代码表示顶点区域内绘制为红色,vec4内的值表示r,g,b,a。


将上面2个shader文件编译为Shader,

ShaderType分为GLES20.GL_VERTEX_SHADER和GLES20.GL_FRAGMENT_SHADER,GLES20.GL_VERTEX_SHADER编译Vertex Shader的,GLES20.GL_ FRAGMENT _SHADER编译Fragment Shader。


将Shader链接到program,

最终返回program的句柄,这2步是固定的,因为我们将其封装为工具类GLTools,供以后使用。


使用工具类GLTools创建program:

program的创建放在Renderer的onSurfaceCreated方法中,创建成功后,获取Shader中参数句柄及设置顶点数据。获取Vertex Shader中vPosition句柄:


顶点坐标系统如下图:

OpenGL ES 环境搭建-LMLPHP

顶点坐标轴以屏幕中心为原点(0,0),z轴的正方向为穿透屏幕指向外面。三角形的顶点坐标设置如下:

工具类GLTools中array2Buffer是将顶点数据转换为FloatBuffer,array2Buffer方法定义如下:





创建OpenGL ES绘制窗口通常是在onSurfaceChanged中设置,

  • 第一个参数(x):表示窗口x坐标,屏幕左上角为原点。

  • 第二个参数(y):表示窗口y坐标,(0,0)表示屏幕左上角。

  • 第三个参数(width):表示窗口的宽。

  • 第四个参数(height):表示窗口的高



绘制在onDrawFrame中执行,

GLES20.glUseProgram(mProgramHandle)表示启动当前program,mProgramHandle是上面创建Program返回的句柄。


GLTools.setAttributePointer(vPositionLoc, vertexBuffer, 3)表示将顶点数据设置给program,参数说明情况如下:

  • Location:vPosition的句柄。

  • buffers :生成的顶点数据。

  • pointSize :每个顶点个数,上面顶点的个数是3个。

setAttributePointer为封装的工具类方法:


glDrawArrays方法是绘制,参数说明情况如下:

  • 第一个参数mode,表示绘制的方式,可选择的值有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。

  • 第二个参数表示从数组缓存中的哪一位开始绘制,一般为0。

  • 第三个参数表示绘制顶点的数量。




如果此文章对您有所帮助,欢迎扫码关注订阅号。

OpenGL ES 环境搭建-LMLPHP

本文分享自微信公众号 - 老孟Flutter(lao_meng_qd)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

09-03 20:36
查看更多