开发者

Smoothing lines in OpenGL ES on iPhone

I'm experimenting with simple line drawing in OpenGL ES on 开发者_如何学运维iPhone 4. I created a stick man out of an array of GLfloats and first tested drawing the stick man in a normal UIView (overriding the draw method). The output as shown here is pretty good...

Smoothing lines in OpenGL ES on iPhone

The problem is that I need to do this drawing under OpenGL for maximum speed (amongst other reasons) so that if I have hundreds of objects, the drawing will still be fast. When I tested a simple line drawing version under OpenGL ES 1.1, I got the following (ignore the missing head!)...

Smoothing lines in OpenGL ES on iPhone

I'm using GL_LINES with one array to draw the figure and have GL_LINE_SMOOTH enabled (along with GL_NICEST) but the figure doesn't look very smooth at all. Is there a way to achieve smoother antialiased lines under OpenGL with primative lines?


Lines drawn using Quartz are normally antialiased, but by default this isn't true in OpenGL ES . As of iOS 4.0, Apple added multisample antialiasing (MSAA) to their OpenGL ES implementation, so you should be able to enable this in order to smooth out your lines (as well as other edges in your scene).

Apple describes how to set this up in the OpenGL ES Programming Guide for iOS under the section "Using Multisampling to Improve Image Quality". You set up a multisampling framebuffer, render buffer, and depth buffer (if needed) using code like the following:

glGenFramebuffers(1, &msaaFramebuffer); 
glGenRenderbuffers(1, &msaaRenderbuffer);

glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);   

glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_RGBA8_OES, backingWidth, backingHeight); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer); 

glGenRenderbuffers(1, &msaaDepthbuffer);   
glBindRenderbuffer(GL_RENDERBUFFER, msaaDepthbuffer); 
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, backingWidth, backingHeight); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msaaDepthbuffer);

Note that this code is drawn from an OpenGL ES 2.0 application, so you may need to alter the above to add the appropriate OES suffixes for 1.1.

Once you go to present your frame, you'll do something like the following:

glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, viewFramebuffer);

glResolveMultisampleFramebufferAPPLE();

glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);

success = [context presentRenderbuffer:GL_RENDERBUFFER];

glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer); 

You may want to discard the color and depth buffers right before or right after presenting your content to the screen as an optimization, for which you can use the following code:

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

I created an example for a class that shows this MSAA working in an OpenGL ES 2.0 application here. Look in the ES2Renderer class there and enable the MSAA define to see this in action. Again, it's pretty simple to place this within an OpenGL ES 1.1 application, because you just need to change a few function and constant suffixes.


http://chimera.labs.oreilly.com/books/1234000001814/ch06.html#ch06_id36002707, 'Antialiasing Tricks with Offscreen FBOs' section

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜