我正在创建一个应用程序,它将NSOpenGLView子类化为一些OpenGL绘图。现在我想添加一个覆盖控件,类似于QuickTime X.我尝试的第一件事是将NSOpenGLCPSurfaceOrder
设置为-1并使我的窗口不透明。它确实有效,但我失去了窗帘,所以不是一个可行的解决方案。
然后我通过调用[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,并且如果变量为true,则使我的[drawRect:rect]
仅调用OpenGL绘图方法。结果是一个非常闪烁和杂乱的动画,所以没有运气。
如何将CAOpenGLLayer与异步动画或CVDisplayLink一起使用?会有帮助吗?
编辑另一件可能有用的信息:我已经使用[setNeedsDisplay:YES]
而我的视图没有图层支持,因此我可以轻松地在图层支持和非图层支持之间切换,我没有上述任何问题,所以它肯定与我的视图层支持。只需拨打[setWantsLayer:YES]
即可获得一切。
答案 0 :(得分:0)
所以我用CVDisplayLink替换了我的NSTimer对象,一切顺利。虽然我实际上并不理解为什么。似乎请求一个支持层打破了垂直同步,但它没有解释随时出现的drawRect
随机调用。
此外,如果vsync与支持NSOpenGLView的层和/或CAOpenGLLayer一起使用,我真的很想。我找不到任何官方信息。