多任务,高分辨率和其他iOS特性
Multitasking, High Resolution, and Other iOS Features
多任务的OpenGL ES应用程序
OpenGL ES应用程序移入后台后必须执行其他工作。如果某个应用无法正确处理这些任务,则iOS可能会终止该应用。此外,一个应用可能想要释放OpenGL ES资源,以便使这些资源可用于前置应用。
后台应用程序可能无法在图形硬件上执行命令
iOS阻止后台app访问图形处理器,这样前台应用可以始终为用户提供出色体验。App不仅在后台执行OpenGL ES调用有可能被终止,还会在app后台时先前提交的命令刷新到GPU时被终止。因此,app必须确保之前提交的命令都已经完成执行,才能移交到后台
如果您使用GLKitView或者ViewController
,并且仅在绘制方法期间提交运行OpenGL ES命令,则app在移交到后台会自动正常运行。GLKViewController
会在App变为非活跃状态时暂停其动画计时器,确保不调用绘图方法
如果不使用GLKView或者GLKViewController,或者在GLKView绘制方法外提交了OpenGL ES命令,则需要采用以下步骤,确保app不会在后台被终止:
- 在
applicationWillResignActive:
方法中,app停止其动画计时器,将其置于良好状态,然后调用glFinish
函数 - app的
applicationDidEnterBackground
方法中,app删除某些OpenGL ES对象,使其内存或资源可用于前台应用。调用glFinish
函数确保立即删除函数。 - app在结束
applicationDidEnterBackground:
方法后,不得再进入任何新的OpenGL ES
调用。如果调用,则会被iOS终止。 - 在app的
applicationWillEnterForeground:
方法中,重新创建所有对象,然后重启动画计时器
总之,app需要调用glFinish
函数 确保之前提交的命令都已从缓冲区删除并由Open GL ES执行,移至后台,必须避免完全使用OpenGL ES,直到移回前台
在移回后台前,请删除较容易创建的资源
在app移交后台时,无需释放OpenGL ES对象,通常app避免销毁其内容。
因为,如果用户启动另外一个Open GLES应用,你的app处于后台则当前台应用使用的内存超过设备可用内存时,则系统将以静默的方式自动终止你的app,而你无需做其它工作
处理以下两种情况的方法:
- app应该将纹理、模型和其它资源保留在内存中,当应用切换到后台时,切勿浪费大量时间重新创建资源
- app应该丢弃可以快速创建的对象,
可以丢弃的易于创建的最容易想到的目标是app分配的用于保存渲染结果的帧缓冲区。
因为大多数app每次渲染新帧时,都会重新创建帧缓冲区内容,使渲染缓冲区成为易于占用的内存密集型资源,移入后台可以丢弃对象的理想选择
如果您使用GLKitView和view controller,则当您的应用程序移至后台时,GLKViewController类会自动处理其关联的视图的帧缓冲区。如果您为其他用途手动创建帧缓冲区,则应在应用程序移至后台时将其丢弃。无论哪种情况,您都应考虑当时您的应用可以处置哪些其他临时资源。
支持高分辨率显示
默认情况下,GLKitView的contentScaleFactor
属性值和屏幕的scale相匹配,因此其相关联的帧缓冲区配置为以全分辨率显示。参阅Supporting High-Resolution Screens In Views
如果使用Core Animation Layer显示OpenGL ES内容,则默认缩放系数设置为1.0.如果要以Retina屏完整分辨率进行绘制,应改CAEAGLLayer
的scale factor为屏幕的scale factor
当在支持高分辨率显示器的设备时,应改调整app的模型和纹理资源。
许多的OpenGL ES的API调用都是以屏幕像素尺寸。此时如果使用大于1.0的比例因子,则在使用glScissor,glBlitFramebuffer,glLineWidth或glPointSize函数或gl_PointSize着色器变量时,应相应地调整尺寸
支持多方向
类似很多app,OpenGL ES app应支持适合其内容的用户界面方向。可以在app的plist文件中声明支持的方向,或者使用supportedInterfaceOrientations
方法为OpenGL ES内容的视图控制器声明支持的界面方向。参阅View Controller Programming Guide for iOS
默认,GLKViewController
和GLKView
类会自动处理方向更改,当用户将设备旋转到主持的方向时,系统会为方向的更改添加动画效果,并更改视图控制器的View的大小。当其大小更改时,GLKView会相应的调整帧缓冲区和viewport大小。如果需要对此更改做出响应,请在GLKViewController
子类中实现viewWillLayoutSubviews
或viewDidLayoutSubviews
方法,或者在使用自定义GLKView子类时实现layoutSubviews
方法。
如果您使用Core Animation图层绘制OpenGL ES内容,则您的应用程序仍应包含视图控制器以管理用户界面方向。
在外部显示器显示
iOS设备可以连接到外部显示器,外部显示器的分辨率和其内容scale factor与主屏幕的不同,因此,渲染一帧的代码应该调整
在外部显示器进行绘制的过程和在主屏幕几乎相同
- 在外部显示器创建窗口的步骤遵循 iOS多显示器编程指南
- 将适合渲染策略的视图或者视图控制器对象添加到窗口中
- 如果使用GLKit进行渲染,请设置GLKViewController和GLKView(或您的自定义子类)的实例,并使用其rootViewController属性将其添加到窗口中。
- 如果渲染到Core Animation图层,请添加包含图层的视图作为窗口的子视图。要使用动画循环进行渲染,请通过获取窗口的screen属性并调用其
displayLinkWithTarget:selector:
方法来创建针对外部显示优化的显示链接对象。