2012-02-22 23 views
31

我想端口苹果GLPaint使用GLKit的例子。使用UIView,可以返回视图的CAEAGLLayer并设置drawableProperties以包含kEAGLDrawablePropertyRetainedBacking。如预期的那样,这具有在呈现渲染缓冲区之后保留可绘制内容的效果。删除此属性会导致绘图调用后出现闪烁,部分可绘制内容似乎被绘制到不同的缓冲区中。GLKView设置可绘制的属性

问题是,这正是我现在在我的GLKView中的问题,但似乎没有设置可绘制属性的方法。返回CAEAGLLayer并设置属性不起作用,我没有看到GLKView的任何相关属性来设置保留的支持。

有没有人遇到过这个或有解决方法?

+0

我没有解决方案,但请注意,视网膜模式下的新iPad中存在驱动程序错误,其中保留的支持模式完全混乱。有讨论和解决方法在这里:http://stackoverflow.com/questions/9753230/ipad-3-opengl-bug-with-keagldrawablepropertyretainedbacking-and-retina – 2012-05-06 05:21:16

+0

你在绘制委托方法?您是否采取了明确的措施? – nielsbot 2012-07-30 21:48:46

+0

我不记得说实话。我结束了刚刚使用CAEAGLLayer,但使用GLKit进行矩阵数学和纹理加载。 – Brett 2012-07-31 13:49:30

回答

2

不知道这是否会工作,但这里是一些代码有:

GLKView * const view = (GLKView *)self.view; 
view.context = self.context; 
view.delegate = self; 
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 
view.drawableDepthFormat = GLKViewDrawableDepthFormat24; 
view.drawableMultisample = GLKViewDrawableMultisampleNone; 
self.preferredFramesPerSecond = 30; 

[EAGLContext setCurrentContext:self.context]; 
CAEAGLLayer * const eaglLayer = (CAEAGLLayer*) view.layer; 
eaglLayer.opaque = YES; 

您应该能够访问eaglLayer.drawableProperties。希望可以让你设置你想要的参数。

+0

谢谢你的赏金! – Liron 2012-08-02 11:07:38

+0

这个答案实际上并不适用于设置kEAGLDrawablePropertyRetainedBacking(至少在iPad 3上)。当它从上下文生成renderBufferStorage时,GLKView覆盖图层属性。我在下面发布了一个答案,可以让你解决这个问题。 – simeon 2012-12-03 13:39:14

-2

如果你想获得kEAGLDrawablePropertyRetainedBacking在GLKView,添加以下类别项目你好,请试试这个

GLKView * const view = (GLKView *)self.view; 
view.context = self.context; 
view.delegate = self; 
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 
view.drawableDepthFormat = GLKViewDrawableDepthFormat24; 
view.drawableMultisample = GLKViewDrawableMultisampleNone; 
self.preferredFramesPerSecond = 10; 

[EAGLContext setCurrentContext:self.context]; 
CAEAGLLayer * const eaglLayer = (CAEAGLLayer*) view.layer; 
+1

这里有什么新信息? – 2012-08-17 09:17:16

8

@interface CAEAGLLayer (Retained) 

@end 

@implementation CAEAGLLayer (Retained) 

- (NSDictionary*) drawableProperties 
{ 
    return @{kEAGLDrawablePropertyRetainedBacking : @(YES)}; 
} 

@end 

设置由GLKView保持在CAEAGLLayer的drawableProperties不起作用,因为GLKView覆盖这些属性,当它结合其绘制和产生它的渲染存储。使用此方法强制GLKView使用您类别的返回drawableProperties。

+0

这也适用于读取深度缓冲区吗?我试过,没有这个代码,但Z值读取始终为0? – Bram 2016-12-10 01:49:22

7

Simeon的答案可以工作,但会改变应用程序中所有基于EAGL的视图的行为。我有需要的后盾迫使一些看法和其他人,其没有,所以我创建GLKView和CEAGLLayer的子类,这样想出了一个稍微不同的解决方案:

@interface RetainedEAGLLayer : CAEAGLLayer 
@end 

@implementation RetainedEAGLLayer 
- (void)setDrawableProperties:(NSDictionary *)drawableProperties { 
    // Copy the dictionary and add/modify the retained property 
    NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] initWithCapacity:drawableProperties.count + 1]; 
    [drawableProperties enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) { 
     // Copy all keys except the retained backing 
     if (![key isKindOfClass:[NSString class]] 
     || ![(NSString *)key isEqualToString:kEAGLDrawablePropertyRetainedBacking]) 
      [mutableDictionary setObject:object forKey:key]; 
    }]; 
    // Add the retained backing setting 
    [mutableDictionary setObject:@(YES) forKey:kEAGLDrawablePropertyRetainedBacking]; 
    // Continue 
    [super setDrawableProperties:mutableDictionary]; 
    [mutableDictionary release]; 
} 
@end 

@interface RetainedGLKView : GLKView 
@end 

@implementation RetainedGLKView 
+ (Class)layerClass { 
    return [RetainedEAGLLayer class]; 
} 
@end 

现在我可以使用RetainedGLKView而不是GLKView来处理那些我想强制保留后台的视图。

+0

谢谢,你的解决方案为我工作。 – lppier 2013-01-29 06:57:14

1

在你GLKView实现文件:

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    if ((self = [super initWithCoder:aDecoder])) 
    { 
     _eaglLayer = (CAEAGLLayer *)self.layer; 

     _eaglLayer.opaque = TRUE; 
     _eaglLayer.drawableProperties = @{ kEAGLDrawablePropertyRetainedBacking : [NSNumber numberWithBool:NO], 
              kEAGLDrawablePropertyColorFormat  : kEAGLColorFormatRGBA8}; 

    } 
    return self; 
} 

我不知道人们是如何设法让事情这么复杂;就是这样,只有这个。