2011-12-18 64 views
0

我正在创建一个子类NSOpenGLView来完成一些OpenGL绘图的应用程序。现在我想添加一个覆盖控制,类似于QuickTime X.我尝试的第一件事是将NSOpenGLCPSurfaceOrder设置为-1,并使我的窗口不透明。它确实有效,但我失去了窗户阴影,所以不是一个可行的解决方案。图层支持NSOpenGLView +动画计时器=奇怪的绘图行为?

我再发通过调用[setWantsLayer:YES]并增加我的控制盒作为一个子视图我NSOpenGLView子层支持。它的工作,但我注意到性能大幅下降。我做了一些研究,发现这一点:

我使用一个NSTimer对象调用的方法每秒[timerFired:] 60倍。完美的作品。我在这个方法中做的唯一的事情就是调用[self setNeedsDisplay:YES],因为当使用层次支持的OpenGLView时,需要重载[drawRect:rect]方法并在那里执行所有的OpenGL绘图。问题:[drawRect:rect]经常被调用,虽然定时器没有触发。

起初我以为“当然是这样,它吸引了NSOpenGLView,所以它可能是由窗口管理器或一些被称为”。因此删除了我的计时器对象,以确定它在[timerFired:]调用之间的调用方式。结果:它根本没有被调用,至少在没有调整窗口大小或拖动窗口的时候没有。

接下来我尝试了我的计时器时间间隔。结果,直到每秒55次,[drawRect:rect]被称为每秒60到70次之间,并且从每秒59次的计时间隔起,[drawRect:rect]被称为每秒100到120次。

我怀疑这个高度不可预测的方式在我的画被称为导致的性能损失,无论是作为不均匀或有很多的OpenGL图纸,没有足够的时间堵塞该线程将被执行的东西。我还读过层支持的OpenGLViews不能与vsync一起工作,尽管我无法证实这一点。

有没有人有解释?有没有人有关于如何在定时器触发时绘制我的OpenGL的想法?

我已经尝试过天真的方法并添加了一个布尔变量,在我的[timerFired:]中设置为true,并且使得我的[drawRect:rect]只调用OpenGL绘图方法(如果变量为true)。结果是一个非常闪烁和结构的动画,所以没有运气。

如何在异步动画或CVDisplayLink中使用CAOpenGLLayer?会帮助吗?

编辑这可能是有用的信息,另一件事:我已经使用[setNeedsDisplay:YES]没有我的观点是层的支持,所以我可以很容易地层支持,而不是层支持之间切换,并且我没有任何上面描述的问题,所以它肯定与我的观点是层层支持。只需拨打[setWantsLayer:YES]就可以了。

回答

0

所以我用CVDisplayLink替换了我的NSTimer对象,一切都很顺利。虽然我实际上不明白为什么。这似乎是要求一个支持层破坏垂直同步,但它不能解释随机调用drawRect,这是从无处不在。

此外,我真的想如果VSYNC可与支持NSOpenGLView和/或与CAOpenGLLayer层。我找不到任何官方信息。