Aleksejs Mjaliks
Aleksejs Mjaliks

Reputation: 8707

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.

Upvotes: 1

Views: 2558

Answers (2)

badweasel
badweasel

Reputation: 2399

Apple's multi-sampling doesn't completely get rid of the aliased edges, particularly at angles near 0, 90, 180, & 270. But it should help to soften them.

In some of my tests I've found onlly a slight difference with it on and off. And you have to decide if it's worth the cost in your app. For example on the iPhone the pixels density is so small that it doesn't make a difference to my eye. On tvOS however the aliasing is quite noticable on like a 45" screen.

Upvotes: 0

Mārtiņš Možeiko
Mārtiņš Možeiko

Reputation: 12917

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

Upvotes: 2

Related Questions