CADisplayLink替代的Mac OS X [英] Alternative of CADisplayLink for 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屋!