简而言之,您可能只需要将GLKView
的contentMode
设置为UIViewContentModeRedraw
。
首先,我认为您的应用程序实际上并没有进入后台,我认为它只是变得不活动。区分applicationWillResignActive
和applicationDidEnterBackground
委托方法之间的区别。假设应用程序仅处于非活动状态,则使用以下内容;如果实际上将应用程序放在后台,请参见下文。
苹果文档表示,在调用applicationWillResignActive
时,“应该降低OpenGL ES帧速率”,而不是禁止使用OpenGL ES调用,该情况仅在应用程序进入后台后发生。
这意味着GLKit
的GLKView
/GLKViewController
在这方面可能有些过度热衷。要解决此问题,您需要确保:
GLKView
的contentMode
设置为UIViewContentModeRedraw
。
GLKView
的drawRect
方法确实在应用程序非活动但帧发生更改时绘制帧,但在应用程序位于后台时不要绘制帧(即使用OpenGL ES调用)。
然而,我假设当应用程序在后台运行时,drawRect
方法甚至没有被调用,因此您可能真的不必担心在glkView:drawInRect
委托方法中使用OpenGL ES调用。但是,在您的情况下,这个函数没有被调用的原因是视图没有失效。不被使无效的原因有两个:
GLKViewController
中的主帧循环会定期使视图失效,该循环由paused
属性暂停。
GLKView
的contentMode
可能是默认的“UIViewContetModeScaleToFill”。
由于GLKView
的drawRect
方法可能根本没有查看paused
属性,所以仅更改contentMode
可能已经足够。
如果应用程序实际上确实进入后台,则建议采用以下解决方案。由于在后台运行时不允许使用OpenGL ES调用,因此解决方案非常简单:
在进入后台之前,执行所有需要执行的OpenGL ES调用以支持您想要的功能。
即,在applicationWillResignActive
中执行以下操作:
- 暂停你的游戏循环(通过设置
GLKViewController
的paused
属性)
- 暂停你的渲染循环(通过设置
GLKViewController
的paused
属性)
- 获取当前方向状态下的当前帧缓存
- 使用与旋转方向状态相对应的帧缓存和视口再次呈现当前游戏状态,并获取该帧缓存
此外,您需要将GLKView
的contentMode
设置为UIViewContentModeRedraw
,以便在方向更改后调用drawRect
方法。
最后,在GLKView
的drawRect
方法中,您需要检查paused
是否为YES
或NO
。如果是NO
,则按照正常方式进行渲染;如果是YES
,则使用在applicationWillResignActive
中保存的帧缓存之一,并使用常规的UIKit
调用将其绘制到视图中。
我不确定这种hackish解决方案与GLKit
的集成情况如何,您可能需要进行一些子类化。