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

Joh*_*ohn 5 macos cocoa quartz-2d

我有一个简单的游戏,将2D图形渲染到帧缓冲区(不使用任何OpenGL).我打算使用CVDisplayLink来获得干净的帧速率,但是Web上的大多数示例都涉及OpenGL或QuickTime.

到目前为止,我有一个NSView的子类:

@interface GameView : NSView {
@private
    CVDisplayLinkRef displayLink;
}

- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime;
@end
Run Code Online (Sandbox Code Playgroud)

我设置了CVDisplayLink回调:

CVDisplayLinkSetOutputCallback(displayLink, MyDisplayLinkCallback, self);
Run Code Online (Sandbox Code Playgroud)

我有回调函数:

CVReturn MyDisplayLinkCallback (CVDisplayLinkRef displayLink,
                                const CVTimeStamp *inNow,
                                const CVTimeStamp *inOutputTime,
                                CVOptionFlags flagsIn,
                                CVOptionFlags *flagsOut,
                                void *displayLinkContext)
{
    CVReturn error = [(GameView*)displayLinkContext getFrameForTime:inOutputTime];

    return error;
}
Run Code Online (Sandbox Code Playgroud)

我陷入困境的部分是如何getFrameForTime:在GameView中绘制图形上下文.我的第一个猜测是以你想要的方式进行绘图drawRect:

- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
    CGContextRef ctxCurrent = [[NSGraphicsContext currentContext] graphicsPort];

    //.. Drawing code follows
}
Run Code Online (Sandbox Code Playgroud)

不过ctxCurrentnil我想我明白-通常有一些设置在之前出现这种情况drawRect:,使您的视图当前上下文.我认为这是我缺少的部分.如何获取我的视图的上下文?

或者我是否以错误的方式解决这个问题?

Rob*_*ger 2

您可以将绘图代码保留在其中\xe2\x80\x91drawRect:,然后MyDisplayLinkCallback()将 ivar 设置为当前时间并调用\xe2\x80\x91display您的视图。这将迫使您的视图立即重绘。

\n\n

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

\n