31

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

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

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

4

5 回答 5

8

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

@interface CAEAGLLayer (Retained)

@end 

@implementation CAEAGLLayer (Retained)

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

@end

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

于 2012-12-03T13:41:31.603 回答
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。

于 2012-12-12T23:38:23.647 回答
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. 希望这可以让您设置所需的参数。

于 2012-08-01T14:00:19.893 回答
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;
}

我不知道人们是怎么把事情弄得这么复杂的。就是这样,也只有这个。

于 2016-05-01T23:52:56.487 回答
-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;
于 2012-08-17T06:24:16.043 回答