iOS OpenGL ES屏幕旋转,而后台应用程序栏可见
我的应用程序使用iOS OpenGL ES屏幕旋转,而后台应用程序栏可见,ios,ipad,glkit,screen-rotation,Ios,Ipad,Glkit,Screen Rotation,我的应用程序使用GLKit使用opengles渲染3D场景 除了一件事外,一切都很好。当我在iPad上启动我的应用程序并显示背景应用程序栏(双击“主页”按钮),然后更改设备的方向时,场景被错误地更新(最后渲染的图像只是拉伸以填充新的矩形) 我找到了原因。当后台应用程序栏出现时,GLKViewController的暂停将自动设置为YES(应用程序代理接收-applicationWillResignActive:),并且在关闭此栏之前不会进行渲染 我在Apple guides()中发现,在收到-ap
GLKit
使用opengles
渲染3D场景
除了一件事外,一切都很好。当我在iPad上启动我的应用程序并显示背景应用程序栏(双击“主页”按钮),然后更改设备的方向时,场景被错误地更新(最后渲染的图像只是拉伸以填充新的矩形)
我找到了原因。当后台应用程序栏出现时,GLKViewController的
暂停
将自动设置为YES
(应用程序代理接收-applicationWillResignActive:
),并且在关闭此栏之前不会进行渲染
我在Apple guides()中发现,在收到-applicationWillResignActive:
后,应用程序应停止GL渲染或将被终止。所以看起来一切正常,除了旋转后的不良渲染:)
我检查了一些OpenGL游戏。当该条显示时,它们也变为“暂停”,但在设备旋转时以某种方式正确更新暂停的场景。他们是如何实现这一点的?实现委托方法(如果您还没有这样做的话)
-(void)应用程序将进入前台
,并从那里取消启动GLKViewController
根据我从你的问题中了解到的情况,你可以暂停游戏,但也可以用这种方法调整glView的大小,但如果看不到任何代码,也很难真正看到发生了什么 tl;dr:您可能只需要将
GLKView
的contentMode
设置为UIViewContentModeRedraw
首先,我不认为你的应用程序实际上进入了后台,我认为它只是变得不活动。applicationWillResignActive
和applicationidentinterbackground
委托方法之间的区别。假设应用程序仅处于非活动状态,请使用以下命令,以防它实际置于后台,请参见下文
苹果的文档说,当调用应用程序willresignative
时,你应该“降低OpenGL ES的帧速率”,而不是说OpenGL ES调用是不允许的,这只发生在应用程序进入后台之后
这意味着
GLKit
的GLKView
/GLKViewController
在这方面可能有点过分热心。要解决此问题,您需要确保:
GLKView
的contentMode
设置为UIViewContentModeRedraw
GLKView
的drawRect
方法即使在应用程序处于非活动状态但帧已更改时也会绘制帧,但是在应用程序处于后台时不会绘制帧(即使用OpenGL ES调用)drawRect
方法甚至不会被调用,因此您可能不必真正担心glkView:drawInRect
委托方法中的OpenGL ES调用。但是,在您的情况下不会调用此函数的原因是视图不会失效。没有失效的原因有两个:
GLKViewController
中定期使视图无效的主帧循环由paused
属性暂停GLKView
contentMode
可能是默认的“UIViewContentModesCaletFill”GLKView
drawRect
方法可能甚至没有查看paused
属性,因此仅更改contentMode
就足够了
如果应用程序确实进入后台,我将提出以下解决方案。由于不允许在后台运行时使用OpenGL ES调用,因此解决方案非常简单: 在进入后台之前,执行所有需要执行的OpenGL ES调用以支持所需内容 也就是说,在
应用程序中,将执行以下操作:
暂停游戏循环(通过设置GLKViewController
的paused
完成)
暂停渲染循环(通过设置GLKViewController
的paused
完成)
获取当前方向状态的当前帧缓冲区
使用与旋转方向状态相对应的帧缓冲区和视口再次渲染当前游戏状态,并抓取该帧缓冲区
此外,您需要将GLKView
的contentMode
设置为UIViewContentModeRedraw
,以便在视图的框架因方向更改而更改后,实际调用drawRect
方法
最后,在GLKView
的drawRect
方法中,您需要检查paused
是否为YES
或NO
在NO
情况下是否正常渲染,在YES
案例中,使用applicationwillresignative
中保存的一个帧缓冲区,并使用常规UIKit
调用将其绘制到视图中
我不确定这个黑客解决方案与GLKit
的集成程度如何,您可能需要一些子类化。GLKViewController
在进入前台时自动取消暂停。当后台应用程序栏可见时,应用程序处于“后台”状态,这次我需要GLKView
更新。@kpower我想我现在明白你的问题了。问题是,当应用程序正在运行时,您双击了home按钮。如果有控制渲染循环的计时器,则“是”,在DiEnterBackground期间使其无效,而不是willresignactive。我刚刚在模拟器中测试了我的一个项目,当应用程序栏打开时,动画确实会暂停,但是当我旋转虚拟ipad时,框架会用新的asp