Почему добавление мультисэмплинга в мое приложение останавливает экран на первом кадре?

Я пытаюсь добавить мультисэмплинг в свое приложение, но, похоже, я допустил ошибку, но не могу найти то, что сделал неправильно.

Вот как я настраиваю свои буферы кадров и буферы рендеринга

- (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];
}

Это вызывает мой метод рендеринга, который довольно прост:

- (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 ответ

Решение

Это не удивительно, если не сказать больше. Единственный раз, когда у вас есть _msaa_framebuffer привязан как буфер DRAW сразу после инициализации ваших FBO.

Первый раз звонишь 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);
Другие вопросы по тегам