-[EAGLContext renderbufferStorage:fromDrawable:]第二次失败?

尼古拉斯·米亚里(Nicolas Miari)

我正在开发一个iOS openGL ES应用程序。

我正在做通常的EAGLView / ES2Render东西。

启动时,使用以下代码成功创建frambuffer:

- (BOOL) createFramebuffers
{
    [EAGLContext setCurrentContext:_mainContext];

    // [ A ] On-screen  

    // 1. Framebuffer
    glGenFramebuffers(1, &_mainFramebuffer);
    bindFramebuffer(_mainFramebuffer);

    // 2. Color buffer
    glGenRenderbuffers(1, &_mainColorbuffer);
    bindRenderbuffer(_mainColorbuffer);

    // Adjust size to view's layer:
    CAEAGLLayer* layer = (CAEAGLLayer*)[_view layer];

    if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
        // something went horribly wrong
        NSLog(@"-[ES2Renderer createFramebuffers]: Failed to obtain renderbuffer storage from layer!");
        return NO;
    }

    // Query new size:
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,  &_backingWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);

    // Attach to color:
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _mainColorbuffer);

    // 3. Depth buffer
    glGenRenderbuffers(1, &_depthBuffer);
    bindRenderbuffer(_depthBuffer);

    if (_useStencilBuffer) {
        // Depth + Stencil

        // Allocate storage:
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);

        // Attach to depth:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);

        // Attach to stencil:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
    }
    else{
        // Depth only

        // Allocate storage:
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);

        // Attachto depth:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);

    }

    // 4. Validate the set:
    GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
        // Something went wrong!

        NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@",
              [self stringFromFramebufferStauts:framebufferStatus]);

        return NO;
    }

    // [ B ] Off-screen (Render-to-texture)

    // 1. Framebuffer
    glGenFramebuffers(1, &_transFramebuffer);
    bindFramebuffer(_transFramebuffer);

    // 2. Depth buffer
    glGenRenderbuffers(1, &_transDepthBuffer);
    bindRenderbuffer(_transDepthBuffer);

    if (_useStencilBuffer) {
        // Allocate storage:
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);

        // Attach to depth:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);

        // Attach to stencil:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);
    }
    else{
        // Allocate storage
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);

        // Attach to depth:
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);
   }


    // 3. Textures (color buffers)

    GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2};

    for (NSUInteger i=0; i < 2; i++) {

        GLuint* texPtr = texPtrs[i];

        // Create:
        glGenTextures(1, texPtr);

        // Bind:
        bindTexture2D(*texPtr);

        // Configure for pixel-aligned use:
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Allocate storage:
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

        // Attach:
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0);

        framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);

        // Validate:
        if ( framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
            // Something went wrong!

            NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@",
                  [self stringFromFramebufferStauts:framebufferStatus]);

            return NO;
        }
    }

    // Final State:

    bindFramebuffer(_mainFramebuffer);
    bindRenderbuffer(_mainColorbuffer);
    bindTexture2D(0);


    NSLog(@"-[ES2Renderer createFramebuffers] Succeeded.");
    return YES;
}

不久之后,UIView-layoutSubviews叫,我又执行-resizeFromLayer:

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{
    // [ A ] On screen framebuffer

    bindFramebuffer(_mainFramebuffer);

    // 1. Resize color buffer
    bindRenderbuffer(_mainColorbuffer);

    if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
        // Something went wrong
        return NO; // <-- SECOND TIME ON, THIS HAPPENS
    }

    // Query new size:
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,  &_backingWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);

    // 2. Resize depth buffer
    bindRenderbuffer(_depthBuffer);

    if (_useStencilBuffer) {
        // (Depth & Stencil)

        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
    }
    else{
        // (Depth only)

        glRenderbufferStorage(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);
    }

    // ...Validate:
    GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
        // Something went wrong!

        NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@",
              [self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)]);

        return NO;
    }

    // [ B ] Off screen (render-to-terxture) framebuffer

    bindFramebuffer(_transFramebuffer);

    // 1. Resize depth buffer

    bindRenderbuffer(_transDepthBuffer);

    if (_useStencilBuffer) {
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
    }
    else{
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);        
    }


    // 2. Resize textures

    GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2};

    for (NSUInteger i=0; i < 2; i++) {

        GLuint* texPtr = texPtrs[i];

        // Bind:
        bindTexture2D(*texPtr);

        // Configure for pixel-aligned use:
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Allocate storage:
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

        // Attach:
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0);


        // Validate:
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
            // Something went wrong!
            NSString* statusString = [self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)];
            NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@", statusString);
            return NO;
        }
    }

    bindFramebuffer(_mainFramebuffer);
    bindRenderbuffer(_mainColorbuffer);


    // Pass new ortho projection to shaders
    [self initializeModelViewMatrix];
    [self initializeSpriteProgram];

    // Set new viewport
    glViewport(0, 0, _backingWidth, _backingHeight);

    NSLog(@"-[ES2Renderer resizeFromLayer:]: Succeeded.");

    return YES;
}

我在做什么都没什么特别的。我有一个单独的帧缓冲区来渲染场景过渡,其中两个纹理分别附加到颜色和深度上。

第二次-renderbufferStorage:fromDrawable:称为(-layoutSubviews-> resizeFromLayer:),它总是失败(返回NO);glGetError()在此之前立即调用不会导致任何错误,但在return之后立即调用它不会导致错误GL_INVALID_OPERATION如果我忽略这一点并继续进行操作,glGetRenderbufferParameteriv()仍然可以让我获得正确的宽度和高度(在iPhone 5上分别为640和1136),但是glCheckFramebufferStatus()会返回GL_FRAMEBUFFER_UNSUPPORTED

另外,我跳过了上述内容,resizeFromLayer:并用以下内容替换了它:

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{
    [self destroyFramebuffers];

    return [self createFramebuffers];
}

...但是相同的错误仍然存​​在(-renderStorage:fromDrawable:失败;这次是内部-createFramebuffers)。

现在,我只是返回YES(我的应用程序仅支持纵向,因此实际上没有发生任何屏幕尺寸更改),但是我真的想修复它,因为有一天我需要支持横向等等。

杰森·马莱斯(Jaysen Marais)

一个可能因此renderbufferStorage:fromDrawable:失败是,_mainContext是不是当时的当前上下文。即使似乎没有其他上下文可以窃取“当前”状态,我还是建议在对与该上下文关联的对象进行操作的[EAGLContext setCurrentContext:_mainContext]任何代码glEAGL代码之前进行调用(例如,在resizeFromLayer:方法的开头)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

-[EAGLContext renderbufferStorage:fromDrawable:]第二次失败?

来自分类Dev

-[EAGLContext renderbufferStorage:fromDrawable:] Failing the second time on?

来自分类Dev

EAGLContext presentRenderbuffer在第二个线程上?

来自分类Dev

EAGLContext presentRenderbuffer在第二个线程上?

来自分类Dev

JSTREE在第二次加载时失败

来自分类Dev

第二次尝试从IIS调用Powershell失败

来自分类Dev

SQL DBGeography第二次插入失败

来自分类Dev

第二次解密时,AES解密失败

来自分类Dev

JSTREE在第二次加载时失败

来自分类Dev

范围 .cells 的选择方法在第二次失败

来自分类Dev

第二次读取文件句柄失败

来自分类Dev

UIWebView卡在第二次

来自分类Dev

替换第二次出现的?与 &

来自分类Dev

TextBox第二次无效

来自分类Dev

第二次直接登录

来自分类Dev

第二次加入Codeigniter

来自分类Dev

第二次读数字

来自分类Dev

第二次委托GMSMapView

来自分类Dev

第二次验证无效

来自分类Dev

第二次登录

来自分类Dev

Angular 8-无头Chrome运行两次,第二次失败

来自分类Dev

连续调用SqlDependency.Start两次,第二次失败?

来自分类Dev

OpenJPA查询第二次失败(可能由于字节数组参数)

来自分类Dev

PHPunit测试:数据库连接之后第二次测试失败

来自分类Dev

Js闭包:第二次调用期间函数失败

来自分类Dev

为什么我的函数第二次在链表的开头插入节点失败?

来自分类Dev

第二次尝试创建画布并设置其宽度失败

来自分类Dev

Azure文件复制在构建管道中第二次运行时失败

来自分类Dev

重新分配第二次呼叫失败