在iPhone上的OpenGL ES中平滑线条

时间:2011-08-24 13:49:42

标签: iphone graphics opengl-es

我正在试验iPhone 4上的OpenGL ES中的简单线条画。我用一系列GLfloats创建了一个棒子,并且首先测试了在普通UIView中绘制棒子的人(覆盖绘制方法)。这里显示的输出非常好......

Example of drawing into UIView

问题是我需要在OpenGL下进行绘图以获得最大速度(以及其他原因),这样如果我有数百个对象,绘图仍然会很快。当我在OpenGL ES 1.1下测试一个简单的线条绘制版本时,我得到了以下内容(忽略丢失的头部!)...

enter image description here

我正在使用带有一个数组的GL_LINES来绘制图形并启用GL_LINE_SMOOTH(以及GL_NICEST)但图形看起来并不是很平滑。有没有办法在OpenGL下用主线来实现更平滑的抗锯齿线?

2 个答案:

答案 0 :(得分:4)

使用Quartz绘制的线通常是抗锯齿的,但默认情况下在OpenGL ES中不是这样。从iOS 4.0开始,Apple在其OpenGL ES实现中添加了多重采样抗锯齿(MSAA),因此您应该能够启用它以平滑线条(以及场景中的其他边缘)。

Apple介绍了如何在“OpenGL ES编程指南”中的“Using Multisampling to Improve Image Quality”部分中进行设置。您可以使用以下代码设置多重采样帧缓冲区,渲染缓冲区和深度缓冲区(如果需要):

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

请注意,此代码是从OpenGL ES 2.0应用程序中提取的,因此您可能需要更改上述内容以为1.1添加适当的OES后缀。

一旦你出现你的框架,你将做类似以下的事情:

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

您可能希望在将内容作为优化内容显示在屏幕之前或之后立即丢弃颜色和深度缓冲区,您可以使用以下代码:

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

我为一个类创建了一个示例,该类显示了在OpenGL ES 2.0应用程序here中工作的MSAA。在那里查看ES2Renderer类并启用MSAA定义以查看此操作。同样,将它放在OpenGL ES 1.1应用程序中非常简单,因为您只需要更改一些函数和常量后缀。

答案 1 :(得分:1)

http://chimera.labs.oreilly.com/books/1234000001814/ch06.html#ch06_id36002707,“使用屏幕外FBO的抗锯齿技巧”部分