用OpenGL ES结合核心animation

编辑:我想,而不是下面的长解释,我可能还会问:发送-setNeedsDisplay的实例不会导致图层重绘(即, -drawInContext:不会被调用)。 相反,我得到这个控制台消息:

 <GLLayer: 0x4d500b0>: calling -display has no effect. 

有没有办法解决这个问题? 我可以调用-drawInContext:何时调用-drawInContext: ? 下面的解释很长:


我有一个OpenGL的场景,我想使用核心animationanimationanimation。

遵循在CALayer中animation定制属性的标准方法,我创build了CAEAGLLayer的子类,并在其中定义了一个属性sceneCenterPoint ,其值应该是animation的。 我的图层还拥有对OpenGL渲染器的引用:

 #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> #import "ES2Renderer.h" @interface GLLayer : CAEAGLLayer { ES2Renderer *renderer; } @property (nonatomic, retain) ES2Renderer *renderer; @property (nonatomic, assign) CGPoint sceneCenterPoint; 

然后我声明属性@dynamic让CA创build访问器,覆盖+needsDisplayForKey:并实现-drawInContext:sceneCenterPoint属性的当前值传递给渲染器,并让它渲染场景:

 #import "GLLayer.h" @implementation GLLayer @synthesize renderer; @dynamic sceneCenterPoint; + (BOOL) needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"sceneCenterPoint"]) { return YES; } else { return [super needsDisplayForKey:key]; } } - (void) drawInContext:(CGContextRef)ctx { self.renderer.centerPoint = self.sceneCenterPoint; [self.renderer render]; } ... 

(如果您有权访问WWDC 2009会话video,可以在会话303(“animation”)中查看此技巧)。

现在,当我为keyPath @"sceneCenterPoint"上的图层创build一个显式animation时,Core Animation应该计算自定义属性的插值,并为animation的每一步调用-drawInContext:

 - (IBAction)animateButtonTapped:(id)sender { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"sceneCenterPoint"]; animation.duration = 1.0; animation.fromValue = [NSValue valueWithCGPoint:CGPointZero]; animation.toValue = [NSValue valueWithCGPoint:CGPointMake(1.0f, 1.0f)]; [self.glView.layer addAnimation:animation forKey:nil]; } 

至less这是一个正常的CALayer子类会发生什么。 当我CAEAGLLayer ,我在控制台上获得了animation每一步的输出:

 2010-12-21 13:59:22.180 CoreAnimationOpenGL[7496:207] <GLLayer: 0x4e0be20>: calling -display has no effect. 2010-12-21 13:59:22.198 CoreAnimationOpenGL[7496:207] <GLLayer: 0x4e0be20>: calling -display has no effect. 2010-12-21 13:59:22.216 CoreAnimationOpenGL[7496:207] <GLLayer: 0x4e0be20>: calling -display has no effect. 2010-12-21 13:59:22.233 CoreAnimationOpenGL[7496:207] <GLLayer: 0x4e0be20>: calling -display has no effect. ... 

因此,可能出于性能的原因,对于OpenGL层, -drawInContext:不会被调用,因为这些层不使用标准的显示方法来绘制自己。 有人可以证实吗? 有没有办法解决它?

还是我不能使用我上面列出的技术? 这将意味着我将不得不在OpenGL渲染器(这是可能的,但不是优雅的IMO)手动实现animation。

你有没有尝试在OpenGL层之上创build一个父层,然后animation呢?

您可以覆盖display而不是drawInContext 。 在animation中,animation值在表示层中。

 - (void) display { GLLayer* myPresentationLayer = (GLLayer*)[self presentationLayer]; self.renderer.centerPoint = myPresentationLayer.sceneCenterPoint; [self.renderer render]; } 

最后,表示层将具有模型图层值,因此您需要在开始animation之前在模型图层上设置最终值。