问题描述
编辑:我想而不是下面的长解释我也可能会问:将 -setNeedsDisplay
发送到 CAEAGLLayer 不会导致图层重绘(即,不会调用 -drawInContext:
)。相反,我得到这个控制台消息:
I suppose instead of the long explanation below I might also ask: Sending -setNeedsDisplay
to an instance of CAEAGLLayer
does not cause the layer to redraw (i.e., -drawInContext:
is not called). Instead, I get this console message:
<GLLayer: 0x4d500b0>: calling -display has no effect.
有没有解决这个问题的方法?当调用 -setNeedsDisplay
时,我可以调用 -drawInContext:
吗?下面详细说明:
Is there a way around this issue? Can I invoke -drawInContext:
when -setNeedsDisplay
is called? Long explanation below:
我有一个OpenGL场景,我想使用Core Animation动画制作动画。
I have an OpenGL scene that I would like to animate using Core Animation animations.
遵循在CALayer中设置自定义属性动画的标准方法,我创建了一个 CAEAGLLayer
的子类,并定义了一个属性 sceneCenterPoint
,其值应该是动画的。我的图层还包含对OpenGL渲染器的引用:
Following the standard approach to animate custom properties in a CALayer, I created a subclass of CAEAGLLayer
and defined a property sceneCenterPoint
in it whose value should be animated. My layer also holds a reference to the OpenGL renderer:
#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:
以传递<$的当前值c $ c> sceneCenterPoint 渲染器的属性并要求它渲染场景:
I then declare the property @dynamic
to let CA create the accessors, override +needsDisplayForKey:
and implement -drawInContext:
to pass the current value of the sceneCenterPoint
property to the renderer and ask it to render the scene:
#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(动画绘图)中查看此技术。
(If you have access to the WWDC 2009 session videos, you can review this technique in session 303 ("Animated Drawing")).
现在,当我在keyPath <$上为图层创建显式动画时c $ c> @sceneCenterPoint,Core Animation应计算自定义属性的插值,并为每个步骤调用 -drawInContext:
动画:
Now, when I create an explicit animation for the layer on the keyPath @"sceneCenterPoint"
, Core Animation should calculate the interpolated values for the custom properties and call -drawInContext:
for each step of the animation:
- (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
时,我会在控制台上为动画的每一步获得此输出:
At least that is what would happen for a normal CALayer
subclass. When I subclass CAEAGLLayer
, I get this output on the console for each step of the 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:
未被调用,因为这些图层不使用标准 -display
绘制自己的方法。任何人都可以证实吗?有办法吗?
So it seems that, possibly for performance reasons, for OpenGL layers, -drawInContext:
is not getting called because these layers do not use the standard -display
method to draw themselves. Can anybody confirm that? Is there a way around it?
或者我可以不使用上面列出的技术吗?这意味着我必须在OpenGL渲染器中手动实现动画(这可能但不是优雅的IMO)。
Or can I not use the technique I laid out above? This would mean I would have to implement the animations manually in the OpenGL renderer (which is possible but not as elegant IMO).
推荐答案
您是否尝试在OpenGL图层上方创建父图层并为其设置动画?
Have you tried making a parent layer above the OpenGL layer and animating that instead?
这篇关于将核心动画与OpenGL ES结合在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!