Search code examples
iosopengl-esmultisampling

Why doesn't multisampling work?


I'm trying to get multisampling to work in my OpenGL ES app.

Framebuffer setup code:

glGenFramebuffersOES(1, &framebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);  
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

GLint backingWidth;
GLint backingHeight;
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

glGenFramebuffersOES(1, &sampleFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);

glGenRenderbuffersOES(1, &sampleColorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, backingWidth, backingWidth);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer);

glGenRenderbuffersOES(1, &sampleDepthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, backingWidth, backingWidth);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);

Rendering code:

glBindFramebufferOES(GL_RENDERBUFFER_OES, sampleFramebuffer);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

GLfloat vertices[] = {
    1.0f, 1.0f, 0.0f,
    2.0f, 4.0f, 0.0f,
    1.0f, 3.0f, 0.0f
};
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);

glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, sampleFramebuffer);
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer);
glResolveMultisampleFramebufferAPPLE();

glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

Result:

Rendering result

As you can see triangle still has aliased sides.


Solution

  • sampleFramebuffer is framebuffer, not renderbuffer. But you are binding it as renderbuffer in rendering code. That's wrong. You should check OpenGL errors by calling glGetError - that would tell you which GL call is invalid.

    Your rendering code should start with following line:

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);
    

    Rest of it is ok. But to improve performance you could use glDiscardFramebufferEXT call on your multisampled framebuffer after Resolve call:

    glResolveMultisampleFramebufferAPPLE();
    const GLenum discards[]  = {GL_COLOR_ATTACHMENT0,GL_DEPTH_ATTACHMENT};
    glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE,2,discards);