如何从 CVDisplayLink 回调内部绘制到 NSView 图形上下文?
我有一个简单的游戏,将 2D 图形渲染到帧缓冲区(不使用任何 OpenGL)。我打算使用 CVDisplayLink 来获得干净的帧速率,但是网络上的大多数示例都涉及 OpenGL 或 QuickTime。
到目前为止,我有一个 NSView 的子类:
@interface GameView : NSView {
@private
CVDisplayLinkRef displayLink;
}
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime;
@end
我设置了 CVDisplayLink 回调:
CVDisplayLinkSetOutputCallback(displayLink, MyDisplayLinkCallback, self);
我有回调函数:
CVReturn MyDisplayLinkCallback (CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *displayLinkContext)
{
CVReturn error = [(GameView*)displayLinkContext getFrameForTime:inOutputTime];
return error;
}
我陷入困境的部分是在 getFrameForTime:
中做什么来绘制到GameView 中的图形上下文。我的第一个猜测是以与 drawRect:
相同的方式进行绘图
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
CGContextRef ctxCurrent = [[NSGraphicsContext currentContext] graphicsPort];
//.. Drawing code follows
}
,但 ctxCurrent
是 nil
我想我明白 - 通常有在 drawRect:
之前发生的一些设置使您的视图成为当前上下文。我认为这是我所缺少的部分。如何获取我的视图的上下文?
还是我以错误的方式处理这件事?
I have a simple game that renders 2D graphics to a frame buffer (not using any OpenGL). I was going to use a CVDisplayLink to get a clean framerate, however most examples on the web deal with OpenGL or QuickTime.
So far I have a sub class of NSView:
@interface GameView : NSView {
@private
CVDisplayLinkRef displayLink;
}
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime;
@end
And I set up the CVDisplayLink callback:
CVDisplayLinkSetOutputCallback(displayLink, MyDisplayLinkCallback, self);
And I have the callback function:
CVReturn MyDisplayLinkCallback (CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *displayLinkContext)
{
CVReturn error = [(GameView*)displayLinkContext getFrameForTime:inOutputTime];
return error;
}
The part where I'm stuck is what to do in getFrameForTime:
to draw to the graphics context in the GameView. My first guess was to do the drawing the same way you would in drawRect:
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
CGContextRef ctxCurrent = [[NSGraphicsContext currentContext] graphicsPort];
//.. Drawing code follows
}
But ctxCurrent
is nil
which I think I understand - normally there is some setup that happens before the drawRect:
that makes your view the current context. I think this is the part I'm missing. How do I get the context for my view?
Or am I going about this in all the wrong ways?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以将绘图代码保留在
-drawRect:
中,然后在MyDisplayLinkCallback()
中将 ivar 设置为当前时间并调用-display
你的观点。这将迫使您的视图立即重绘。在您的
-drawRect:
方法中,只需使用时间 ivar 的值来执行任何必要的绘制操作,以适当地更新当前动画帧的视图。You could leave your drawing code in
‑drawRect:
and then in yourMyDisplayLinkCallback()
set an ivar to the current time and call‑display
on your view. This will force your view to immediately redraw itself.In your
‑drawRect:
method, just use the value of the time ivar to do whatever drawing is necessary to update the view appropriately for the current animation frame.您应该创建一个单独的
-draw:
方法,并从MyDisplayLinkCallback()
以及-drawRect:
调用该方法。我发现 Rob Keniger 的回复符合我的喜好,并尝试了它;遗憾的是,如果您从显示链接回调中调用
-display
,那么当您终止应用程序时,您的应用程序可能会陷入死锁,从而导致您强制退出应用程序(对我来说,这种情况经常发生) 。You should create a separate
-draw:
method, and call that from yourMyDisplayLinkCallback()
as well as from-drawRect:
.I found Rob Keniger's response to my liking and tried it out; sadly, if you call
-display
from your display link callback your app may hang in a deadlock when you terminate the app, leaving you to force-quit the app (for me it happened more often than not).