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?
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
: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 yourrender (...)
function: