CADisplayLink替代的Mac OS X [英] Alternative of CADisplayLink for Mac OS X

查看:1636
本文介绍了CADisplayLink替代的Mac OS X的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

时的iOS有CADisplayLink,在Mac OS X有CVDisplayLink,但我不能找到一种方法来使用它,所有的例子都与OpenGL的。

Is iOS there is CADisplayLink, in Mac OS X there is CVDisplayLink, but I can't find a way to use it, all the examples are related to OpenGL.

我创造了这个自定义的UIView,我想将它转化为一个的NSView

I created this custom UIView and I want to translate it to a NSView

#import "StarView.h"
#import <QuartzCore/QuartzCore.h>

#define MAX_FPS (100.0)
#define MIN_FPS (MAX_FPS/40.0)
#define FRAME_TIME (1.0 / MAX_FPS)
#define MAX_CPF (MAX_FPS / MIN_FPS)
#define aEPS (0.0001f)

@implementation StarView

@synthesize starImage = _starImage;
@synthesize x, y;

- (void)baseInit {
    _starImage = nil;
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self     selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
    [self baseInit];
}
return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
    [self baseInit];
}
return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    [self.starImage drawAtPoint:CGPointMake(self.x, self.y)];
}

-(void) cycle {
    self.x += 5;
    if (self.x > 230) {
        self.x = 0;
    }
}

- (void) runLoop {
//NSLog(@"called");
static CFTimeInterval last_time = 0.0f;
static float cycles_left_over = 0.0f;
static float dt2 = 0.0f;

float dropAnimRate = (2.1f/25.0f);

CFTimeInterval current_time = CACurrentMediaTime();
float dt = current_time - last_time + cycles_left_over;
dt2 += dt;

[self setNeedsDisplay];

if (dt > (MAX_CPF * FRAME_TIME)) {
    dt = (MAX_CPF * FRAME_TIME);
}
while (dt > FRAME_TIME) {
    if (dt2 > (dropAnimRate - aEPS)){
        [self cycle];
        dt2 = 0.0f;
    }
    dt -= FRAME_TIME;
}

cycles_left_over = dt;
last_time = current_time;
}

@end

这是我无法翻译的部分是这个

The part that I can't translate is this one

- (void)baseInit {
    _starImage = nil;
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self     selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

我知道可以使用一个的NSTimer,但它不具有相同的精度

I know that I can use a NSTimer, but it doesn't have the same accuracy

推荐答案

您可以配置CVDisplayLink OpenGL的独立工作。以下是code,我已经用于建立一个CVDisplayLink触发定期捕获和从工业相机渲染:

You can configure a CVDisplayLink to work independently of OpenGL. The following is code that I've used to set up a CVDisplayLink to trigger regular capture and rendering from an industrial camera:

CGDirectDisplayID   displayID = CGMainDisplayID();
CVReturn            error = kCVReturnSuccess;
error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink);
if (error)
{
    NSLog(@"DisplayLink created with error:%d", error);
    displayLink = NULL;
}
CVDisplayLinkSetOutputCallback(displayLink, renderCallback, (__bridge void *)self);

我的 renderCallback 函数看起来是这样的:

static CVReturn renderCallback(CVDisplayLinkRef displayLink, 
                               const CVTimeStamp *inNow, 
                               const CVTimeStamp *inOutputTime, 
                               CVOptionFlags flagsIn, 
                               CVOptionFlags *flagsOut, 
                               void *displayLinkContext)
{
    return [(__bridge SPVideoView *)displayLinkContext renderTime:inOutputTime];
}

您必须与你自己的类和回调方法来替代上述,当然。在 __在code桥是有ARC的支持,所以你可能不需要在手动引用计数的环境。

You'll have to replace the above with your own class and callback method, of course. The __bridge in the code is there for ARC support, so you may not need that in a manually reference counted environment.

要开始从显示的链接捕获的事件,你会使用

To start capturing events from the display link, you'd use

CVDisplayLinkStart(displayLink);

和停止

CVDisplayLinkStop(displayLink);

完成后,务必使用您创建CVDisplayLink后清理 CVDisplayLinkRelease()

如果我可以做最后的评论,为什么你看到CVDisplayLink通常与OpenGL的配对是,你通常不希望使用核芯显卡在屏幕上做快速刷新的原因。如果您需要在30-60 FPS速率来动画的东西,你会想要么直接使用OpenGL绘制或使用的Core Animation,让它处理动画计时为您服务。核心图形绘制不流畅动画事物的方式。

If I may make one last comment, the reason why you see CVDisplayLink normally paired with OpenGL is that you usually don't want to be doing rapid refreshes on the screen using Core Graphics. If you need to be animating something at a 30-60 FPS rate, you're going to either want to draw directly using OpenGL or use Core Animation and let it handle the animation timing for you. Core Graphics drawing is not the way to fluidly animate things.

这篇关于CADisplayLink替代的Mac OS X的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆