为了在您的 Android 应用程序中使用 OpenGL ES 绘制图形,您必须为它们创建一个视图容器。一种更直接的方法是同时实现 GLSurfaceView 和 GLSurfaceView.Renderer。 GLSurfaceView 是使用 OpenGL 和 GLSurfaceView 绘制的图形的视图容器。渲染器控制在该视图中绘制的内容。有关这些类的更多信息,请参阅 OpenGL ES 开发人员指南。
GLSurfaceView 只是将 OpenGL ES 图形整合到您的应用程序中的一种方式。对于全屏或接近全屏的图形视图,这是一个合理的选择。希望将 OpenGL ES 图形合并到他们的一小部分布局中的开发人员应该看看 TextureView。对于真正的自己动手的开发人员,也可以使用 SurfaceView 构建 OpenGL ES 视图,但这需要编写相当多的额外代码。
本课说明如何在简单的应用程序活动中完成 GLSurfaceView 和 GLSurfaceView.Renderer 的最小实现。
在Manifest文件中声明使用 OpenGL ES
为了你的应用能够使用OpenGL ES 2.0 API,你必须在你的Manifest文件中添加如下申明:
<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 Graphics创建Activity
使用 OpenGL ES 的 Android 应用程序与具有用户界面的任何其他应用程序一样具有活动。与其他应用程序的主要区别在于您在活动布局中放置的内容。虽然在许多应用程序中您可能会使用 TextView、Button 和 ListView,但在使用 OpenGL ES 的应用程序中,您还可以添加 GLSurfaceView。 以下代码示例显示了使用 GLSurfaceView 作为其主要视图activity的最小实现:
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)
}
}
注意:OpenGL ES 2.0 需要 Android 2.2(API 级别 8)或更高版本,因此请确保您的 Android 项目以该 API 或更高版本为目标。
创建一个GLSurfaceView对象
GLSurfaceView 是一种专门的视图,您可以在其中绘制 OpenGL ES 图形。它本身并没有做太多事情。对象的实际绘制在您在此视图上设置的 GLSurfaceView.Renderer 中控制。事实上,这个对象的代码非常简单,您可能想跳过扩展它而只创建一个未修改的 GLSurfaceView 实例,但不要那样做。您需要扩展此类以捕获触摸事件,这在响应触摸事件课程中有所介绍。 GLSurfaceView 的基本代码很少,因此为了快速实现,通常只在使用它的活动中创建一个内部类:
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)
}
}
GLSurfaceView 实现的另一个可选添加是使用 GLSurfaceView.RENDERMODE_WHEN_DIRTY 设置将渲染模式设置为仅在绘图数据发生更改时绘制视图:
// Render the view only when there is a change in the drawing data
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
此设置可防止重绘 GLSurfaceView 框架,直到您调用 requestRender() 为止,这对于此示例应用程序来说效率更高。
创建一个Renderer类
在使用 OpenGL ES 的应用程序中实现 GLSurfaceView.Renderer 类或Renderer渲染器是事情开始变得有趣的地方。此类控制在与其关联的 GLSurfaceView 上绘制的内容。 Android 系统调用渲染器中的三种方法来确定在 GLSurfaceView 上绘制什么以及如何绘制:
- onSurfaceCreated() - 调用一次以设置视图的 OpenGL ES 环境。
- onDrawFrame() - 每次重绘视图时调用。
- onSurfaceChanged() - 如果视图的几何形状发生变化,例如当设备的屏幕方向发生变化时调用。
这是 OpenGL ES 渲染器的一个非常基本的实现,它只是在 GLSurfaceView 中绘制黑色背景:
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)
}
}
这里的所有都是它的!上面的代码示例创建了一个使用 OpenGL 显示黑屏的简单 Android 应用程序。虽然这段代码没有做任何有趣的事情,但通过创建这些类,您已经奠定了开始使用 OpenGL 绘制图形元素所需的基础。
注意:当您使用 OpengGL ES 2.0 API 时,您可能想知道为什么这些方法有一个 GL10 参数。这些方法签名只是为 2.0 API 重用,以保持 Android 框架代码更简单。
如果您熟悉 OpenGL ES API,您现在应该能够在您的应用程序中设置 OpenGL ES 环境并开始绘制图形。但是,如果您在开始使用 OpenGL 时需要更多帮助,请继续学习下一课以获得更多提示。