天天看点

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

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

下一步就是使用一个特殊的类glsurfaceview初始化opengl。glsurfaceview会处理opengl初始化过程中比较基本的操作,如配置显示设备(display)以及在后台线程中渲染;渲染是在显示设备中一个称为“surface”的特定区域完成的,有时也称为视口(viewport)。

glsurfaceview类也使得处理标准android activity生命周期变得容易了;在android里,任何activity都可以创建(create)和销毁(destroy),并且在用户切换到其他activity时暂停(pause),在切换回来时继续(resume)。根据这个生命周期,在activity被暂停的时候,我们需要释放opengl的资源;glsurfaceview为此提供了很多辅助方法。

在edburnette所写的《hello, android》里,你可以学到更多关于activity生命周期的内容。

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

纹理视图

在幕后,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上。

打开前面自动生成的activity类firstopenglprojectactivity。按下“ctrl+shift+t”快捷键,“open type”对话框就会弹出来,然后输入“firstopenglprojectactivity”,当那个类显示出来时,就选择它。

eclipse键盘快捷键

在mac或者linux平台上,快捷键可能与windows平台不同;比如,快捷键“ctrl+shift+o”,在windows平台上,它是用来组织和查找新的java 导入(import)的;在mac平台上就是。可以通过菜单“help→key assist”选择按键辅助功能查看各个平台的键绑定。

现在看起来没有多少代码:

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

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

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

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

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

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

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

首先,我们需要android activitymanager的一个引用,用它获取设备配置信息,然后,取出reqglesversion变量检查opengl es版本号。如果版本号为0×20000或后续版本,我们就可以使用 opengl es 2.0的api了。

但是这段代码实际上不能在模拟器上工作,因为gpu模拟部分有缺陷;为了使代码在模拟器上正常工作,我们要按如下代码修改那个检查条件:

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

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

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

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

如果设备支持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():

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

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

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

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

继续阅读