用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之前在模型图层上设置最终值。