为什么在我的应用中添加多重采样会冻结第一帧的屏幕?

时间:2014-01-12 19:26:26

标签: ios opengl-es opengl-es-2.0 msaa

我正在尝试为我的应用添加多重采样,但似乎我犯了一个错误,但我找不到我做错了什么。

这就是我设置帧缓冲区和渲染缓冲区的方法

- (void)setupBuffers {
    glGenFramebuffers(1, &_framebuffer);
    glGenRenderbuffers(1, &_renderbuffer);

    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _renderbuffer);

    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer]; // I already set the current context to _context, and _eaglLayer is just self.layer

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _renderbuffer);

    if (YES) { // note if I set this to no, my app properly displays (I don't even have to remove the code in my render method)
        glGenFramebuffers(1, &_msaa_framebuffer);
        glGenRenderbuffers(1, &_msaa_renderbuffer);

        glBindFramebuffer(GL_FRAMEBUFFER, _msaa_framebuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _msaa_renderbuffer);

        glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 2, GL_RGBA8_OES, [AppDelegate screenWidth], [AppDelegate screenHeight]); // yes, this is the proper width and height I tested it
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _msaa_renderbuffer);
    }

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(status != GL_FRAMEBUFFER_COMPLETE) {
        NSLog(@"Failed to make complete framebuffer object %x", status);
        exit(1);
    }
}

viewDidLoad上调用ViewController后,我在setupDisplayLink子类上调用方法UIView

- (void)setupDisplayLink {
    CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
    //displayLink.frameInterval = [[NSNumber numberWithInt:1] integerValue];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

这会调用我的render方法,这非常简单:

- (void)render:(CADisplayLink*)displayLink {
    glBindRenderbuffer(GL_RENDERBUFFER, _msaa_framebuffer);

    glViewport(0, 0, [AppDelegate screenWidth], [AppDelegate screenHeight]);
    glClearColor(188.0f / 255.0f, 226.0f / 255.0f, 232.0f / 255.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    [[OpenGLViewController instance].menu draw:displayLink]; // drawing happens here

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, _framebuffer);
    glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, _msaa_framebuffer);

    glResolveMultisampleFramebufferAPPLE();

    glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 1, (GLenum[1]) { GL_COLOR_ATTACHMENT0 });

    glBindRenderbuffer(GL_RENDERBUFFER, _renderbuffer);

    NSLog(@"%@", @"HI");
    [_context presentRenderbuffer:GL_RENDERBUFFER];
}

它根本没有挂起(应用程序在控制台中继续打印“HI”因为我在渲染方法中告诉它)。出于某种原因,当我添加额外的帧缓冲区和渲染缓冲区进行多重采样时,只绘制了第一帧,我无法弄清楚原因。它就冻结在那个框架上。为什么我的应用只会使用MSAA绘制第一帧?

1 个答案:

答案 0 :(得分:1)

至少可以说这并不奇怪。在您初始化FBO之后,您唯一一次_msaa_framebuffer绑定为 DRAW 缓冲区。

第一次拨打render (...)时,以下行会被吸引到_msaa_framebuffer

[[OpenGLViewController instance].menu draw:displayLink]; // drawing happens here

但是,稍后在render (...)中,您将绘制缓冲区设置为_framebuffer,并且您永远不会从该点开始更改它。

要解决您的问题,您只需记住在_msaa_framebuffer函数的开头绑定render (...)作为绘制缓冲区:

- (void)render:(CADisplayLink*)displayLink {
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, _msaa_framebuffer);