Как нарисовать к графическому контексту NSView из обратного вызова CVDisplayLink? - PullRequest
5 голосов
/ 20 июня 2011

У меня есть простая игра, которая отображает 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:, что делает ваш взгляд текущим контекстом.Я думаю, что это та часть, по которой я скучаю.Как мне получить контекст для моего взгляда?

Или я поступаю по этому поводу во всех неправильных направлениях?

Ответы [ 2 ]

2 голосов
/ 20 июня 2011

Вы можете оставить свой код для рисования в ‑drawRect:, а затем в своем MyDisplayLinkCallback() установить ivar на текущее время и вызвать ‑display на вашем виде. Это заставит ваш взгляд немедленно перерисовать себя.

В вашем методе ‑drawRect: просто используйте значение времени ivar, чтобы сделать любой рисунок, необходимый для обновления представления соответствующим образом для текущего кадра анимации.

0 голосов
/ 02 января 2015

Вы должны создать отдельный метод -draw: и вызывать его из своего MyDisplayLinkCallback(), а также из -drawRect:.

Я нашел ответ Роба Кенигера по своему вкусу ипопробовал это;к сожалению, если вы позвоните по номеру -display с помощью функции обратного вызова отображаемой ссылки, ваше приложение может зайти в тупик, когда вы закроете приложение, что заставит вас принудительно выйти из приложения (для меня это случалось чаще, чем нет).

...