2010-12-21 117 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]; 
} 

最後,表示層將具有模型圖層值,因此您需要在開始動畫之前在模型圖層上設置最終值。