为了在您的 Android 应用程序中使用 OpenGL ES 绘制图形,您必须为它们创建一个视图容器。一种更直接的方法是同时实现 GLSurfaceView
和 GLSurfaceView.Renderer
。 GLSurfaceView
是使用 OpenGL 绘制的图形的视图容器,而 GLSurfaceView.Renderer
控制在该视图中绘制的内容。有关这些类的更多信息,请参阅 OpenGL ES 开发者指南。
GLSurfaceView
只是将 OpenGL ES 图形集成到您的应用程序中的一种方法。对于全屏或接近全屏的图形视图,这是一个合理的选择。希望在其布局的一小部分中集成 OpenGL ES 图形的开发者应该查看 TextureView
。对于真正的 DIY 开发者,也可以使用 SurfaceView
构建 OpenGL ES 视图,但这需要编写相当多的额外代码。
本课程介绍如何在简单的应用程序活动中完成 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 图形创建活动
使用 OpenGL ES 的 Android 应用程序与任何其他具有用户界面的应用程序一样,都具有活动。与其他应用程序的主要区别在于您在活动的布局中放置的内容。虽然在许多应用程序中您可能会使用 TextView
、Button
和 ListView
,但在使用 OpenGL ES 的应用程序中,您还可以添加 GLSurfaceView
。
以下代码示例显示了使用 GLSurfaceView
作为其主视图的活动的最小实现
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
的基本代码最少,因此对于快速实现,通常只需在使用它的活动中创建一个内部类
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);
此设置可防止 GLSurfaceView
框架在您调用 requestRender()
之前重新绘制,这对于此示例应用程序来说效率更高。
构建渲染器类
使用 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); } }
就是这样!上面的代码示例创建了一个简单的 Android 应用程序,使用 OpenGL 显示黑屏。虽然此代码没有做任何非常有趣的事情,但通过创建这些类,您已经奠定了开始使用 OpenGL 绘制图形元素所需的基础。
注意:您可能想知道为什么这些方法具有 GL10
参数,而您正在使用 OpengGL ES 2.0 API。这些方法签名只是为了 2.0 API 而重复使用,以使 Android 框架代码更简单。
如果您熟悉 OpenGL ES API,那么您现在应该能够在您的应用程序中设置 OpenGL ES 环境并开始绘制图形。但是,如果您需要更多帮助来开始使用 OpenGL,请继续学习接下来的课程以获取更多提示。