2010-12-21 37 views
11

编辑:我想的不是长解释下面我也可能会问:发送-setNeedsDisplayCAEAGLLayer实例不会造成层重绘(即-drawInContext:不叫)。相反,我得到这个控制台消息:嫁核心动画使用OpenGL ES

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

有没有解决这个问题的方法吗?当调用-setNeedsDisplay时,可以调用-drawInContext:吗?下面的长解释:


我有一个OpenGL场景,我想动画使用核心动画动画。

遵循在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]; 
} 
... 

(如果你有机会获得2009年WWDC会议视频,您可以查看在会话303(“动态显示”)这一技术)。

现在,当我创建的的keyPath @"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,我得到的控制台上输出动画的每一步:

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:是没有得到所谓的,因为这些图层不使用标准的-display方法绘制自己。任何人都可以证实吗?有没有办法解决它?

或者我不能用我上面布置的技术?这意味着我将不得不在OpenGL渲染器中手动实现动画(这可能但不是优雅的IMO)。

回答

4

您是否尝试过做了OpenGL层之上父层和动画是不是?

+0

感谢您的建议。我会尝试一下并报告。 – 2010-12-27 12:03:23

+0

它的确如此,非常感谢!性能似乎不如纯粹的OpenGL解决方案,但我将很快写一篇关于具体细节的博客文章。 – 2010-12-27 15:30:15

6

您可以覆盖display而不是drawInContext。在动画中,动画值位于表示层中。

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

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