天天看点

《OpenGL ES应用开发实践指南:Android卷》—— 1.4 创建Renderer类

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

现在要定义一个渲染器,以便我们开始清空屏幕。

让我们快速浏览一下渲染器接口定义的方法:

当surface被创建的时候,glsurfaceview会调用这个方法;这发生在应用程序第一次运行的时候,并且,当设备被唤醒或者用户从其他activity切换回来时,这个方法也可能会被调用。在实践中,这意味着,当应用程序运行时,本方法可能会被调用多次。

在surface被创建以后,每次surface尺寸变化时,这个方法都会被glsurfaceview调用到。在横屏、竖屏来回切换的时候,surface尺寸会发生变化。

当绘制一帧时,这个方法会被glsurfaceview调用。在这个方法中,我们一定要绘制一些东西,即使只是清空屏幕;因为,在这个方法返回后,渲染缓冲区会被交换并显示在屏幕上,如果什么都没画,可能会看到糟糕的闪烁效果。

怎么会有一个未被使用的参数类型gl10呢?它是opengl es 1.0的api(应用程序编程接口)遗留下来的;如果要编写使用opengl es 1.0的渲染器,就要使用这个参数;但是,对于opengl es 2.0,gles20类提供了静态方法来存取。

在后台线程中渲染

glsurfaceview会在一个单独的线程中调用渲染器的方法。默认情况下,glsurfaceview会以显示设备的刷新频率不断地渲染,当然,它也可以配置为按请求渲染,只需要用

glsurfaceview.rendermode_when_dirty作为参数调用glsurfaceview.setrendermode()即可。

既然android的glsurfaceview在后台线程中执行渲染,就必须要小心,只能在这个渲染线程中调用opengl,在android主线程中使用ui(用户界面)相关的调用;两个线程之间的通信可以用如下方法:在主线程中的glsurfaceview实例可以调用queueevent()方法传递一个runnable给后台渲染线程,渲染线程可以调用activity的runonuithread()来传递事件(event)给主线程。

新建渲染器

在同一个包里创建一个各为firstopenglprojectrender的新类,用来实现renderer接口;为了创建这个新类,在包浏览器(package explorer)里,鼠标右键单击“com.firstopenglproject.android”,接着选择“new→class”;在弹出的“new java class”窗口中输入“firstopenglprojectrenderer”作为名字,并单击“finish”按钮。

我们会以下面的代码作为开始,并加入我们的第一个方法onsurfacecreated():

《OpenGL ES应用开发实践指南:Android卷》—— 1.4 创建Renderer类

首先,在onsurfacecreated()中调用glclearcolor(1.0f, 0.0f, 0.0f, 0.0f)设置清空屏幕用的颜色;前三个参数分别对应红色、绿色和蓝色,最后的参数对应一个特殊的分量,称为阿尔法(alpha),它经常用来表示半透明度或透明度。通过把第一个分量设为1,其余设为0,我们把红色设置为最大强度,当屏幕被清空时,它就会显示红色。2.6节会更详细地讨论这个颜色模型。

下一步就是设置视口(viewport)尺寸了,让我们加入如下代码:

《OpenGL ES应用开发实践指南:Android卷》—— 1.4 创建Renderer类

在onsurfacechanged()方法中,调用glviewport(0, 0, width, height)设置了视口尺寸,这就告诉了opengl可以用来渲染的surface的大小。

要用如下代码完成这个渲染器类:

《OpenGL ES应用开发实践指南:Android卷》—— 1.4 创建Renderer类

在ondrawfame()中调用glclear(gl_color_buffer_bit)清空屏幕;这会擦除屏幕上的所有颜色,并用之前glclearcolor()调用定义的颜色填充整个屏幕。

现在测试一下代码,看看会发生什么。按“ctrl+f11”键运行这个程序。你会看到一个空白的红色屏幕,如图1-4所示。

《OpenGL ES应用开发实践指南:Android卷》—— 1.4 创建Renderer类

尝试改变清空的颜色,然后再运行程序看看会发生什么!你应该看到屏幕上的颜色与代码的改动完全匹配。

如果你使用的是模拟器,且程序不工作,而你也检查过模拟器的配置选项“use host gpu”已经被勾选了,那就试试在glsurfaceview.setrenderer()调用之前加入glsurfaceview.seteglconfigchooser(8,8,8,8,16,0)的调用。

继续阅读