我的应用使用GLKit
使用OpenGL ES
渲染3D场景。
一切正常,除了一件事。当我在iPad中启动我的应用程序并显示后台应用程序栏(单击双击“主页”按钮)然后更改设备的方向时,场景会被错误更新(最后渲染的图像只是拉伸以填充新的矩形)。
我找到了原因。当后台应用栏显示时,GLKViewController's
paused
会自动设置为YES
(应用代理接收-applicationWillResignActive:
),并且在此栏关闭之前不会进行渲染。
我在Apple指南(OpenGL ES Programming Guide for iOS / Implementing a Multitasking-aware OpenGL ES Application)中发现,在收到-applicationWillResignActive:
申请后,应停止GL渲染或终止。所以似乎一切都好,除了旋转后的坏渲染:)
我检查了一些OpenGL游戏。当显示此栏时,它们也会“暂停”,但不知何故正确更新设备旋转时暂停的场景。他们是如何实现这一目标的?
答案 0 :(得分:2)
tl; dr:您可能只需要将GLKView
的{{1}}设置为contentMode
首先,我不认为您的应用程序实际进入后台,我认为它只会变为非活动状态。 UIViewContentModeRedraw
和applicationWillResignActive
委托方法之间的区别。假设应用程序仅处于非活动状态,请使用以下内容,以防它实际放入后台,请参阅下文。
Apple文档说,当applicationDidEnterBackground
被调用时,你应该“降低OpenGL ES帧率”,而不是不允许OpenGL ES调用,只有在应用程序进入后台后才会发生。
这意味着applicationWillResignActive
的{{1}} / GLKit
在这方面可能有点过分热心。要修复它,您需要确保:
GLKView
的{{1}}设置为GLKViewController
GLKView
的{{1}}方法确实也会绘制框架,但不会当应用程序在后台时绘制框架(即使用OpenGL ES调用)。但是,我的假设是,当应用程序在后台时,contentMode
方法甚至不会被调用,因此您可能不必担心{{1}中的OpenGL ES调用委托方法。然而,在您的情况下不调用此函数的原因是视图不会失效。不被无效的原因有两个:
UIViewContentModeRedraw
中的主框架循环定期使视图无效,暂停GLKView
属性。drawRect
drawRect
可能是默认的'UIViewContetModeScaleToFill'由于glkView:drawInRect
GLKViewController
方法可能甚至没有查看paused
属性,只更改GLKView
可能已经足够了。
如果应用程序确实进入后台,我会建议以下解决方案。由于您不允许在后台运行时使用OpenGL ES调用,因此解决方案非常简单:
在您进入后台之前,您需要执行所有OpenGL ES调用以支持您想要的内容。
也就是说,在contentMode
中执行以下操作:
GLKView
的{{1}})drawRect
的{{1}})此外,您需要将paused
的{{1}}设置为contentMode
,以便在视图的框架因方向更改而更改后实际调用applicationWillResignActive
方法
最后,在GLKViewController
的{{1}}方法中,您需要检查paused
案例中的GLKViewController
是paused
还是GLKView
。正常渲染,在contentMode
情况下,使用UIViewContentModeRedraw
中保存的一个帧缓冲区,并通过常规drawRect
调用将其绘制到视图中。
我不确定这个hackish解决方案与GLKView
的集成程度如何,您可能需要一些子类化。
答案 1 :(得分:0)
实施委托方法(如果你还没有这样做)
-(void)applicationWillEnterForeground
并从那里取消暂停GLKViewController
。
从我对你的问题的理解,你可以保持游戏暂停,但也可以在这个方法中调整glView的大小,但是没有看到任何代码也很难真正看到正在发生的事情。