编辑:我想,与其在下面做长篇解释,不如直接问:向CAEAGLLayer
的实例发送-setNeedsDisplay
并不会导致该图层重新绘制(即不会调用-drawInContext:
)。相反,我会收到这条控制台消息:
<GLLayer: 0x4d500b0>: calling -display has no effect.
有没有方法可以解决这个问题?当调用-setNeedsDisplay
时,我能否调用-drawInContext:
来绘制图形呢?以下是详细说明:我有一个OpenGL场景,我想使用Core Animation动画来进行动态效果。
按照在CALayer中动画自定义属性的标准方法,我创建了一个
CAEAGLLayer
子类,并在其中定义了一个名为sceneCenterPoint
的属性,其值应该被动态地修改。我的层也持有对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创建访问器,重写+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会议视频,则可以在303号会议("Animated Drawing")中查看此技术的详细信息)。
现在,当我为键路径 @"sceneCenterPoint"
上的层创建显式动画时,核心动画应计算自定义属性的插值并在每个动画步骤中调用-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];
}
至少对于普通的CALayer
子类来说是这样。当我子类化CAEAGLLayer
时,在每个动画步骤中都会在控制台上输出以下内容:
所以看起来可能是出于性能原因,对于OpenGL图层,
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. ...
-drawInContext:
没有被调用,因为这些图层不使用标准的-display
方法来绘制自己。有人可以确认吗?有没有办法解决呢?
或者我不能使用我上面提出的技术吗?这意味着我必须在OpenGL渲染器中手动实现动画(这是可能的,但在我看来不太优雅)。