本篇文章属于 使用 OpenGL ES 进行图形绘制 这个系列的第一篇文章,主要内容是介绍在 Android 应用使用 OpenGL ES 时需要配置的开发环境和整体流程说明。
要在 Android 应用中使用 OpenGL ES 绘制图像,我们必须为它们创建一个 View 容器。一种比较直接的方法是实现 GLSurfaceView 类和 GLSurfaceView.Renderer 类。其中 GLSurfaceView 是一个视图容器,它用来存放使用 OpenGL 绘制的图形,而 GLSurfaceView.Renderer 则用来控制在该视图内容的绘制(渲染器)。关于这两个类的更多信息,可以阅读 OpenGL ES 开发手册。
Note: GLSurfaceView 是一个 View container,用来存放绘制的图像。
GLSurfaceView.Renderer 是用来控制 View 中绘制的内容的渲染器。
使用 GLSurfaceView 是一种将 OpenGL ES 集成到应用中的方法之一。对于一个全屏的或者接近全屏的图形 View,使用它是一个理想的选择。开发者如果希望把 OpenGL ES 的图形集成在布局的一小部分里面,那么可以考虑使用 TextureView。对于喜欢自己动手实现的开发者来说,还可以通过使用
SurfaceView 搭建一个 OpenGL ES View,但这将需要编写更多的代码。
下面将展示如何在一个 Activity 中完成 GLSurfaceView 和 GLSurfaceView.Renderer 的最简单直接的实现。
1. 1 在 Manifest 配置文件中声明使用 OpenGL ES
为了让应用能够使用 OpenGL ES 2.0 接口,我们必须将下列声明添加到 Manifest 配置文件当中:
<!--0x00020000 代表使用 OpenGL ES 2.0 接口-->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
如果应用要使用纹理压缩(Texture Compression),则必须声明对纹理压缩格式的支持,这样确保应用仅安装在可以兼容的设备上:
<!--纹理压缩格式格式声明-->
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
纹理压缩通过减少内存需求并更有效地利用内存带宽,可以显着提高 OpenGL 应用程序的性能。更多关于纹理压缩的内容可以阅读 OpenGL 开发手册 。
1.2 为 OpenGL ES 图形创建一个 Activity
使用 OpenGL ES 的 Android 应用跟其它类型的应用主要的区别体现在 Activity 布局内容上的差异。通常我们会使用 TextView、Button等已经封装好的控件。而如果使用 OpenGL ES 的我们就得依赖 GLSurfaceView 来自己实现了。
所以最简单的使用方式是直接创建一个 GLSurfaceView 实例,并把它作为 ContentView 设置到 Activity 中。
public class OpenGLSample01Activity extends AppCompatActivity {
GLSurfaceView mGLSurfaceView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("OpenGLSample01");
// Create a GLSurfaceView instance and set it
// as the ContentView for this Activity.
mGLSurfaceView = new MyGLSurfaceView(this);
setContentView(mGLSurfaceView);
}
}
OpenGL ES 2.0 需要Android 2.2(API Level 8)或更高版本的系统,所以确保你的Android项目的 API 版本满足该要求。
1.3 构建一个 GLSurfaceView 对象
GLSurfaceView 是一种比较特殊的 View,我们可以在该 View 中绘制 OpenGL ES 图形,不过它自己并不做太多和绘制图形相关的任务。绘制对象的任务是由你在该 View 中配置的 GLSurfaceView.Renderer 所控制的。因此在实际开发中不建议直接使用 GLSurfaceView 来创建实例。
事实上,GLSurfaceView 的核心代码非常简短,你可能会直接创建一个未经修改的 GLSurfaceView 实例,不过请不要这么做,因为我们需要继承该类来捕捉触控事件,这方面知识会在 响应触摸事件 中做进一步的介绍。
class MyGLSurfaceView extends GLSurfaceView {
private final MyGLRenderer mRenderer;
public MyGLSurfaceView(Context context){
super(context);
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);
mRenderer = new MyGLRenderer();
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(mRenderer);
}
}
另一个对于 GLSurfaceView 的可选选项是将渲染模式设置为:GLSurfaceView.RENDERMODE_WHEN_DIRTY,其含义是仅在你的绘制数据发生变化时才在视图中进行绘制操作:
// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
如果选用这一配置选项,那么除非调用了 requestRender(),否则 GLSurfaceView 不会被重新绘制,这样做可以让应用的性能及效率得到提高。
1.4 构建一个渲染器类
在一个使用 OpenGL ES 的应用中,必定少不了 GLSurfaceView.Renderer 类的实现。该类会控制和其相关联的 GLSurfaceView 的绘制行为和内容,Renderer 这个类中有三个方法会被系统调用,所以需要实现下面三个方法:
- onSurfaceCreated():调用一次,用来配置 View 的 OpenGL ES 环境。
- onDrawFrame():每次重新绘制View时被调用。
- onSurfaceChanged():如果View的几何形态发生变化时会被调用,例如当设备的屏幕方向发生改变时。
下面是一个非常基本的 OpenGL ES 渲染器的实现,它仅仅在GLSurfaceView 中画一个黑色的背景:
public class MyGLRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
}
通过上述代码,我们完成一个完整的 OpenGL ES 简单使用场景,程序运行起来会是一个黑色的背景。
下面来简单回顾一下在应用中使用 OpenGL ES 的整个流程:
- 在 Manifest 中对使用 OpenGL ES 进行声明
- 给 OpenGL ES 绘制的图像创建 Activity
- 创建一个 GLSurfaceView 对象并设置到 Activity 中
- 创建一个 Renderer 类实现绘制逻辑,并设置到 GLSurfaceView
文章中所有的代码示例都已放在 Github 上,可以去项目 OpenGL-ES-Learning 中查看 。
通过基于上面的内容,相信你对于如何使用 OpenGL 绘制图形有了基本的认识和铺垫。当然,这些都是相当基础的知识,如果你对 OpenGL ES 接口很熟悉,那么你现在就可以在应用中构建一个 OpenGL ES 的环境并绘制图形了。如果你希望获取更多关于 OpenGL 的内容,请继续看后面的内容。
-
OpenGL ES 定义图形形状
学习如何在 OpenGL 中定义图形形状 -
OpenGL ES 绘制形状(Shape)
学习如何在应用中利用 OpenGL 绘制形状。 -
OpenGL ES 运用投影与相机视角
学习如何通过投影和相机视角,获取图形对象的一个新的透视效果。 -
OpenGL ES 添加视图动作
学习如何对一个 OpenGL 图形对象添加基本的运动效果。 -
OpenGL ES 响应触摸事件
学习如何与 OpenGL 图形进行基本的交互。