《OpenGL ES应用开发实践指南:Android卷》—— 1.3 初始化OpenGL

本节书摘来自华章出版社《OpenGL ES应用开发实践指南:Android卷》一 书中的第1章,第1.3节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.3 初始化OpenGL

下一步就是使用一个特殊的类GLSurfaceView初始化OpenGL。GLSurfaceView会处理OpenGL初始化过程中比较基本的操作,如配置显示设备(display)以及在后台线程中渲染;渲染是在显示设备中一个称为“surface”的特定区域完成的,有时也称为视口(viewport)。
GLSurfaceView类也使得处理标准Android Activity生命周期变得容易了;在Android里,任何Activity都可以创建(create)和销毁(destroy),并且在用户切换到其他Activity时暂停(pause),在切换回来时继续(resume)。根据这个生命周期,在Activity被暂停的时候,我们需要释放OpenGL的资源;GLSurfaceView为此提供了很多辅助方法。
在EDBurnette所写的《Hello, Android》里,你可以学到更多关于Activity生命周期的内容。
screenshot

纹理视图
在幕后,GLSurfaceView实际上为它自己创建了一个窗口(window),并在视图层次(View Hierarchy)上穿了个“洞”,让底层的OpenGL surface显示出来。对于大多数使用情况,这就足够了;但是,GLSurfaceview与常规视图(view)不同,它没有动画或者变形特效,因为GLSurfaceView是窗口(window)的一部分。
从Android 4.0 Ice Cream Sandwich开始,Android提供了一个纹理视图(TextureView),它可以渲染OpenGL而不用创建单独的窗口或打洞了,这就意味着,这个视图像一个常规窗口一样,可以被操作,且有动画和变形特效。但是,TextureView类没有内置OpenGL初始化操作,要想使用TextureView,一种方法是执行自定义的OpenGL初始化,并在TextureView上运行,另外一种方法是把GLSurfaceView的源代码拿出来,把它适配到TextureView上。

1.3.1 创建GLSurfaceView实例

打开前面自动生成的Activity类FirstOpenGLProjectActivity。按下“Ctrl+Shift+T”快捷键,“Open Type”对话框就会弹出来,然后输入“FirstOpenGLProjectActivity”,当那个类显示出来时,就选择它。
Eclipse键盘快捷键
在Mac或者Linux平台上,快捷键可能与Windows平台不同;比如,快捷键“Ctrl+Shift+O”,在Windows平台上,它是用来组织和查找新的Java 导入(import)的;在Mac平台上就是。可以通过菜单“Help→Key Assist”选择按键辅助功能查看各个平台的键绑定。
现在看起来没有多少代码:
screenshot

我们给这个Activity添加一个GLSurfaceView实例,这样就可以初始化OpenGL。让我们在类的顶部加入如下两个新的成员变量:
screenshot

我们需要导入GLSurfaceView类,因此,按“Ctrl+Shift+O”快捷键组织导入,并把这个新类放到代码里;每次加入一个新的类引用,并且它需要被导入时,我们都要做这一步。我们将用rendererSet记住GLSurfaceView是否处于有效状态。让我们从代码中移除setContentView()的调用,并加入如下代码初始化glSurfaceView:
screenshot

1.3.2 检查系统是否支持OpenGL ES 2.0

因为我们只为2.0版本写代码,我们要做的下一件事就是检查系统是否实际支持OpenGL ES 2.0。让我们添加如下几行代码到onCreate()函数中:
screenshot

首先,我们需要Android ActivityManager的一个引用,用它获取设备配置信息,然后,取出reqGlEsVersion变量检查OpenGL ES版本号。如果版本号为0×20000或后续版本,我们就可以使用 OpenGL ES 2.0的API了。
但是这段代码实际上不能在模拟器上工作,因为GPU模拟部分有缺陷;为了使代码在模拟器上正常工作,我们要按如下代码修改那个检查条件:
screenshot

这段代码测试当前设备是不是模拟器,如果是,就假定它支持OpenGL ES 2.0。要确保程序能运行,模拟器一定要配置OpenGL ES 2.0,参见1.1.1节。

1.3.3 为OpenGL ES 2.0配置渲染表面

下一步就是配置渲染表面(rendering surface),添加如下几行代码:
screenshot

如果设备支持OpenGL ES 2.0,我们就通过调用setEGLContextClientVersion(2)配置这个surface视图;然后调用setRenderer()传进自定义Renderer类的一个新实例,稍后,我们会看到如何创建这个Renderer类,同时这段代码通过设置rendererSet为true记住渲染器(renderer)已经设置过了。当surface创建或者发生变化的时候,以及要绘制一幅新帧时,渲染器都会被GLSurfaceView调用。
如果设备不支持OpenGL ES 2.0,怎么办呢?也可以添加一个支持OpenGL ES 1.0的回退的渲染器,但是,这种情形现在已经很少见了,可能不值得付出这样的努力。根据Android开发者统计板,仅有大约9%的设备只支持OpenGL ES 1.1,这个数字还在随着时间不断缩减。如果一个设备不支持OpenGL ES 2.0,公开发布的应用应该在这个设备的应用程序市场中被隐藏起来,在14.1.6节中,我们会学到这点。
我们需要添加另外一个调用把GLSurfaceView加入到这个activity中,并把它显示到屏幕上,在onCreate()函数结尾处,用如下代码替换旧的调用setContentView():
screenshot

1.3.4 处理Android Activity生命周期的事件

我们还需要处理Android Activity生命周期的事件,否则,如果用户切换到另外一个应用,应用就会崩溃;加入如下方法让这个Activity类变得完整:
screenshot

这些方法非常重要,有了它们 ,这个surface视图才能正确暂停并继续后台渲染线程,同时释放和续用OpenGL上下文。如果它没有做这些,应用程序可能会崩溃,并被Android终止;我们还要保证渲染器也设置了,否则调用这些方法也会引起程序崩溃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用NDK和OpenGL ES 3.0来绘制一个三角形可以分为以下几个步骤: 1. 首先,创建一个安卓项目,并配置NDK环境。 2. 在项目的jni目录下,创建一个C/C++源文件triangle.c。 3. 在triangle.c文件中,引入相关的头文件,包括<jni.h>和<GLES3/gl3.h>。 4. 在triangle.c文件中,实现一个JNI函数,用于绘制三角形。函数的参数为Surface对象。 5. 在JNI函数中,通过EGL和GLES初始化OpenGL环境,并创建一个EGLSurface用于后续的绘制操作。 6. 在JNI函数中,创建一个顶点数组和顶点缓冲,并将顶点数据存入顶点缓冲。 7. 在JNI函数中,编写着色器代码,包括顶点着色器和片段着色器,并编译和链接它们。 8. 在JNI函数中,通过glClearColor()函数设置清空屏幕时的颜色。 9. 在JNI函数中,通过glClear()函数清空屏幕,并启用深度测试。 10. 在JNI函数中,通过glViewport()函数设置视口大小。 11. 在JNI函数中,通过glUseProgram()函数使用着色器程序。 12. 在JNI函数中,通过glVertexAttribPointer()函数设置顶点数据的属性,并启用顶点属性。 13. 在JNI函数中,通过glDrawArrays()函数绘制三角形。 14. 在JNI函数中,通过eglSwapBuffers()函数交换绘制的缓冲区。 15. 在JNI函数中,清理OpenGL环境,并释放资源。 16. 在Java层的MainActivity中,通过JNI调用C/C++函数进行绘制。 以上是绘制一个三角形的大致步骤。具体的细节和代码实现可以参考相关的OpenGL ES 3.0和NDK的文档和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值