如何从 CVDisplayLink 回调内部绘制到 NSView 图形上下文?

发布于 2024-11-16 13:19:07 字数 1425 浏览 3 评论 0原文

我有一个简单的游戏,将 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
}

,但 ctxCurrentnil 我想我明白 - 通常有在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原野 2024-11-23 13:19:07

您可以将绘图代码保留在 -drawRect: 中,然后在 MyDisplayLinkCallback() 中将 ivar 设置为当前时间并调用 -display你的观点。这将迫使您的视图立即重绘。

在您的 -drawRect: 方法中,只需使用时间 ivar 的值来执行任何必要的绘制操作,以适当地更新当前动画帧的视图。

You could leave your drawing code in ‑drawRect: and then in your MyDisplayLinkCallback() 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.

江湖正好 2024-11-23 13:19:07

您应该创建一个单独的 -draw: 方法,并从 MyDisplayLinkCallback() 以及 -drawRect: 调用该方法。

我发现 Rob Keniger 的回复符合我的喜好,并尝试了它;遗憾的是,如果您从显示链接回调中调用 -display ,那么当您终止应用程序时,您的应用程序可能会陷入死锁,从而导致您强制退出应用程序(对我来说,这种情况经常发生) 。

You should create a separate -draw: method, and call that from your MyDisplayLinkCallback() 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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文