我有一个EAGLView
我正在动画中调整大小,动画由一个调用绘图功能的NSTimer
驱动。当我调整EAGLView
的大小时,我需要调整视图的投影以保持内容的宽高比。 draw函数如下所示:
gameView.frame = newFrame;
[gameView setFramebuffer];
[self updateProjection];
/* Drawing to the EAGLView, gameView, here, then... */
[gameView presentFramebuffer];
这样运行,EAGLView的内容似乎在“动画”中“向下”。当我录制它并逐帧查看时,很明显调整了投影,然后在很短的时间后调整视图(少于一个动画帧)。
我怀疑原因是gameView
的框架中的更改正在推迟,同时更新的帧缓冲区正在进入屏幕。我已经尝试使用CATransactions
让帧更新立即生效,但正如我对UIView更改所期望的那样,它什么也没做。我想我可以修改视口并保留EAGLView
全帧,但我担心这可能会让我在其他地方遇到同步问题(例如,更新任何重叠的CALayers)。
这似乎是对问题的合理评估吗?如何防止它 - 也就是说,如何才能最好地确保帧缓冲区表示与EAGLView(和其他CA元素)的实际帧中的更改一致?
谢谢!
答案 0 :(得分:1)
我遇到过与我写的自定义EAGLView
类似的问题。问题是当改变方向时,视图被调整大小并且内容被拉伸,并且只有在动画之后,才显示具有正确比例的场景。
我认为你的问题是同样的,我认为你不能强迫CoreAnimation等待你的视图在渲染动画帧之前更新,因为它的工作方式(CA不知道绘图机制)视图或操作的图层。)
但您可以轻松绕过问题:打开包含视图的 xib 文件,切换到右侧的属性检查器。选择EAGLView
(同样适用于GLKView
),在查看部分下方有模式属性。如果您以编程方式创建视图,请设置contentMode
属性。
此值描述在动画期间如何管理视图内容。在显示缓冲区之前,根据该模式调整旧场景的大小;也许你可以找到一个适合你需要实现的动画的模式。
如果您担心比例, center 内容模式可能会有效,但尚未渲染的场景部分在动画期间会显示为空。
不幸的是,重绘模式无需进行EAGLView
刷新:视图 实际上是重新绘制的,但可能是旧的内容颜色缓冲区。这是在正确的时间填充缓冲区的问题。
您可以尝试调整大小并预渲染一个足够大的帧,以便在启动之前覆盖整个动画;或者您可以尝试将帧渲染到UIImage
,动态替换视图,为其设置动画,EAGLView
返回的位置,但这可能会严重影响性能。
我解决问题的方法就是让EAGLView
足够大。
关于其他CALayer
的混合,据我所知,我没有遇到同步问题; EAGLView
尽可能更新,其他层也更新。如果您正在使用Alpha通道,只需将正确的属性设置为CAEAGLLayer
,并记住每次OpenGL更新场景时混合图层在性能方面可能会很昂贵。