GLKView设置drawable属性

时间:2012-02-22 13:28:38

标签: iphone ios5 opengl-es-2.0 glkit

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

问题是这正是我现在在GLKView中遇到的问题,但似乎没有办法设置drawable属性。返回CAEAGLLayer并设置属性没有任何效果,我没有看到GLKView的任何相关属性来设置保留的支持。

有没有其他人遇到这个或有解决方案?

5 个答案:

答案 0 :(得分:8)

如果您想在GLKView中获取kEAGLDrawablePropertyRetainedBacking,请将以下类别添加到您的项目中。

@interface CAEAGLLayer (Retained)

@end 

@implementation CAEAGLLayer (Retained)

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

@end

在GLKView维护的CAEAGLLayer上设置drawableProperties不起作用,因为GLKView在绑定其drawable并生成其渲染存储时会覆盖这些属性。使用此方法会强制GLKView使用您的类别返回的drawableProperties。

答案 1 :(得分: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来查看那些我想强制保留支持的视图。

答案 2 :(得分: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。希望这可以让你设置你想要的参数。

答案 3 :(得分: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;
}

我不知道人们如何设法使事情如此复杂;就像这样,只有这一点。

答案 4 :(得分:-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 = 10;

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