如需在 Android 应用中使用 OpenGL ES 绘制图形,您必须为它们创建一个视图容器。其中一种比较直接的方式是同时实现 GLSurfaceView
和 GLSurfaceView.Renderer
。GLSurfaceView
是使用 OpenGL 绘制的图形的视图容器,而 GLSurfaceView.Renderer
可控制该视图中绘制的图形。如需详细了解这些类,请参阅 OpenGL ES 开发者指南。
GLSurfaceView
只是将 OpenGL ES 图形整合到您应用中的其中一种方式。对于全屏或接近全屏的图形视图,这是一种合理的选择。希望将 OpenGL ES 图形整合到其布局的一小部分中的开发者应该了解下 TextureView
。对于自己动手的真正开发者来说,也可以使用 SurfaceView
构建 OpenGL ES 视图,但这需要编写相当多的其他代码。
本课程介绍了如何在一个简单的应用 Activity 中完成 GLSurfaceView
和 GLSurfaceView.Renderer
的最低实现。
在清单中声明 OpenGL ES 的使用
为了让您的应用使用 OpenGL ES 2.0 API,您必须将以下声明添加到清单中:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
如果您的应用使用了纹理压缩,您还必须声明应用支持哪些压缩格式,以便应用仅在兼容的设备上安装。
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
如需详细了解纹理压缩格式,请参阅 OpenGL 开发者指南。
为 OpenGL ES 图形创建 Activity
使用 OpenGL ES 的 Android 应用的 Activity 与其他任何具有界面的应用相同。这种应用与其他应用的主要区别在于您在 Activity 的布局中添加了哪些内容。在很多应用中,您可以使用 TextView
、Button
和 ListView
;而在使用 OpenGL ES 的应用中,您还可以添加一个 GLSurfaceView
。
以下代码示例展示了使用 GLSurfaceView
作为主要视图的 Activity 的最低实现:
Kotlin
class OpenGLES20Activity : Activity() { private lateinit var gLView: GLSurfaceView public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = MyGLSurfaceView(this) setContentView(gLView) } }
Java
public class OpenGLES20Activity extends Activity { private GLSurfaceView gLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = new MyGLSurfaceView(this); setContentView(gLView); } }
注意:OpenGL ES 2.0 需要 Android 2.2(API 级别 8)或更高版本,因此请确保您的 Android 项目以该 API 或更高级别为目标。
构建 GLSurfaceView 对象
GLSurfaceView
是一种专用视图,您可以在其中绘制 OpenGL ES 图形。它本身并没有很大的作用。对象的实际绘制由您在此视图中设置的 GLSurfaceView.Renderer
控制。实际上,此对象的代码过于单薄,以至于您想要跳过对它的扩展,直接创建一个未经修改的 GLSurfaceView
实例,但请不要这样操作。您需要扩展此类才能捕获触摸事件,这在响应触摸事件课程中有所介绍。
GLSurfaceView
的基本代码很少,因此为了快速实现,通常只在使用它的 Activity 中创建一个内部类:
Kotlin
import android.content.Context import android.opengl.GLSurfaceView class MyGLSurfaceView(context: Context) : GLSurfaceView(context) { private val renderer: MyGLRenderer init { // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2) renderer = MyGLRenderer() // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer) } }
Java
import android.content.Context; import android.opengl.GLSurfaceView; class MyGLSurfaceView extends GLSurfaceView { private final MyGLRenderer renderer; public MyGLSurfaceView(Context context){ super(context); // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2); renderer = new MyGLRenderer(); // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer); } }
GLSurfaceView
实现的另一种可选附加项是使用 GLSurfaceView.RENDERMODE_WHEN_DIRTY
设置将渲染模式设置为仅在绘制数据发生变化时绘制视图:
Kotlin
// Render the view only when there is a change in the drawing data renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
Java
// Render the view only when there is a change in the drawing data setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
该设置可防止系统在您调用 requestRender()
之前重新绘制 GLSurfaceView
帧,这对于此示例应用而言更为高效。
构建渲染程序类
在使用 OpenGL ES 的应用中实现 GLSurfaceView.Renderer
类(或渲染程序)之后,事情就开始变得有趣起来。此类可控制在与之相关联的 GLSurfaceView
上绘制的内容。Android 系统会调用渲染程序中的以下三种方法来确定在 GLSurfaceView
上绘制什么内容以及如何绘制:
onSurfaceCreated()
- 调用一次以设置视图的 OpenGL ES 环境。onDrawFrame()
- 每次重新绘制视图时调用。onSurfaceChanged()
- 当视图的几何图形发生变化(例如当设备的屏幕方向发生变化)时调用。
下面展示了 OpenGL ES 渲染程序一个非常基本的实现,即在 GLSurfaceView
上绘制一个黑色背景:
Kotlin
import javax.microedition.khronos.egl.EGLConfig import javax.microedition.khronos.opengles.GL10 import android.opengl.GLES20 import android.opengl.GLSurfaceView class MyGLRenderer : GLSurfaceView.Renderer { override fun onSurfaceCreated(unused: GL10, config: EGLConfig) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f) } override fun onDrawFrame(unused: GL10) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) } override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) } }
Java
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLES20; import android.opengl.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 打造了一个显示黑屏的简单 Android 应用。虽然此代码并没有做任何有趣的事情,但通过创建这些类,您奠定了开始使用 OpenGL 绘制图形元素所需的基础。
注意:当您使用 OpengGL ES 2.0 API 时,您可能会好奇为何这些方法具有 GL10
参数。这些方法签名可以简单地重用于 2.0 API,以使 Android 框架代码更加简单。
如果您熟悉 OpenGL ES API,现在应该可以在应用中设置 OpenGL ES 环境并开始绘制图形。不过,如果您需要获取更多帮助以开始使用 OpenGL,请继续学习下一课来获取更多提示。