【问题标题】:GLKView set drawable propertiesGLKView 设置可绘制属性
【发布时间】:2016-05-02 07:52:56
【问题描述】:

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

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

有其他人遇到过这个问题或有解决方案吗?

【问题讨论】:

  • 我没有解决方案,但请注意,在视网膜模式下的新 iPad 中存在一个驱动程序错误,其中保留的备份模式完全混乱。这里有讨论和解决方法:stackoverflow.com/questions/9753230/…
  • 你画的是委托方法吗?您是否使用了明确的步骤?
  • 我不记得说实话了。我最终只使用了 CAEAGLLayer,但使用 GLKit 进行矩阵数学和纹理加载。
  • 另见stackoverflow.com/questions/9753230/…。似乎写那篇文章的人肯定知道如何做你想做的事。

标签: iphone ios5 opengl-es-2.0 glkit


【解决方案1】:

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

@interface CAEAGLLayer (Retained)

@end 

@implementation CAEAGLLayer (Retained)

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

@end

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

【讨论】:

  • 这也适用于读取深度缓冲区吗?我尝试使用和不使用此代码,但读取的 Z 值始终为 0?
【解决方案2】:

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。

【讨论】:

    【解决方案3】:

    不确定这是否可行,但这里有一些代码:

    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。希望这可以让您设置所需的参数。

    【讨论】:

    • 此答案实际上不适用于设置 kEAGLDrawablePropertyRetainedBacking(至少在 iPad 3 上)。 GLKView 在从上下文生成 renderBufferStorage 时会覆盖层属性。我在下面发布了一个答案,可以让你解决这个问题。
    【解决方案4】:

    在您的 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;
    }
    

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

    【讨论】:

      【解决方案5】:

      你好,试试这个

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-27
        • 2023-03-13
        • 2021-11-24
        • 2014-01-11
        • 1970-01-01
        • 2015-11-27
        • 1970-01-01
        • 2019-05-03
        相关资源
        最近更新 更多