gpt4 book ai didi

objective-c - Mac OS X 的 CADisplayLink 替代品

转载 作者:技术小花猫 更新时间:2023-10-29 10:08:25 24 4
gpt4 key购买 nike

iOS有CADisplayLink吗,Mac OS X有CVDisplayLink,但是我找不到使用方法,所有的例子都与OpenGL相关。

我创建了这个自定义 UIView,我想将它转换为 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

我不能翻译的是这一段

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

我知道我可以使用 NSTimer,但它的精度不一样

最佳答案

您可以将 CVDisplayLink 配置为独立于 OpenGL 工作。以下是我用来设置 CVDisplayLink 以从工业相机触发定期捕获和渲染的代码:

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];
}

当然,您必须用自己的类和回调方法替换上面的内容。代码中的 __bridge 用于 ARC 支持,因此在手动引用计数环境中您可能不需要它。

要从显示链接开始捕获事件,您需要使用

CVDisplayLinkStart(displayLink);

停止

CVDisplayLinkStop(displayLink);

完成后,请务必在使用 CVDisplayLinkRelease() 创建 CVDisplayLink 后进行清理。

如果我可以做最后一点评论,您看到 CVDisplayLink 通常与 OpenGL 配对的原因是您通常不希望使用 Core Graphics 在屏幕上进行快速刷新。如果您需要以 30-60 FPS 的速率制作动画,您要么想直接使用 OpenGL 绘制,要么使用 Core Animation 并让它为您处理动画计时。 Core Graphics 绘图不是流畅动画的方式。

关于objective-c - Mac OS X 的 CADisplayLink 替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14158743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com