Domanda

I'm trying to add multisampling to my app, but it seems that I've made a mistake, but I can't find what I did wrong.

This is how I setup my frame buffers and render buffers

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

After viewDidLoad is called on my ViewController I call the method setupDisplayLink on my UIView subclass.

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

This calls my render method which is pretty simple:

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

It's not hanging at all (the app keeps printing "HI" in the console because I told it to in the render method). For some reason only the first frame is drawn when I add the extra frame buffer and render buffer for multisampling and I can't figure out why. It just freezes on that frame. Why will my app only draw the first frame with MSAA?

È stato utile?

Soluzione

This is not surprising to say the least. The only time you have _msaa_framebuffer bound as the DRAW buffer is immediately after you initialize your FBOs.

The first time you call render (...), the following line will be drawn into your _msaa_framebuffer:

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

However, later on in render (...) you set the draw buffer to _framebuffer and you never change it from that point on.

To fix your problem, all you have to do is remember to bind _msaa_framebuffer as your draw buffer at the beginning of your render (...) function:

- (void)render:(CADisplayLink*)displayLink {
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, _msaa_framebuffer);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top