2009-11-28 132 views
37

通常情况下,你会使用类似:OpenGL ES的iPhone - 绘制反锯齿线

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_BLEND); 
glEnable(GL_LINE_SMOOTH); 

glLineWidth(2.0f); 

glVertexPointer(2, GL_FLOAT, 0, points); 
glEnableClientState(GL_VERTEX_ARRAY); 

glDrawArrays(GL_LINE_STRIP, 0, num_points); 

glDisableClientState(GL_VERTEX_ARRAY); 

它看起来在iPhone模拟器不错,但在iPhone上线得到非常薄和W/O任何反走样。

如何在iPhone上看到AA?

+0

你可以使其为锯齿线然后应用[布隆过滤器(http://ofps.oreilly.com/titles/9780596804824/chadvanced.html#fig-BloomTriptych) – bobobobo 2012-12-21 20:16:03

+0

@bobobobo链接是死。 – TomSawyer 2016-10-20 09:24:02

回答

59

人们可以实现抗混叠的影响非常便宜使用顶点不透明度为0。 下面是一个图像的例子来解释:

alt text

比较AA:

alt text

您可以在这里阅读关于此的文章:

http://research.microsoft.com/en-us/um/people/hoppe/overdraw.pdf

你可以沿着这条道路做一些事情:

// Colors is a pointer to unsigned bytes (4 per color). 
// Should alternate in opacity. 
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); 
glEnableClientState(GL_COLOR_ARRAY); 

// points is a pointer to floats (2 per vertex) 
glVertexPointer(2, GL_FLOAT, 0, points); 
glEnableClientState(GL_VERTEX_ARRAY); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, points_count); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_COLOR_ARRAY); 
+2

哇!简单,清晰和完美的方法和描述。太好了! – Eonil 2010-01-29 04:09:15

+5

有没有什么可比较的(但更简单)绘制反锯齿线 - 人们可以用来绘制方程式等。换句话说,对于使用GL_LINE_STRIP而不是GL_TRIANGLE_STRIP的绘图。 我正在绘制的东西看起来很像。我正在探索使用GL_POINT_SPRITE_OES(每个苹果的GLPaint示例代码),但它意味着为每个像素位置创建点...或者看起来似乎。我想让OpenGL-ES为我补间。 – westsider 2010-08-03 19:58:28

+0

非常感谢:) – 2011-05-23 16:58:03

2

我记得非常具体,我尝试过这一点,并没有简单的方法来使用iPhone上的OpenGL做到这一点。您可以使用CGPath和CGContextRef进行绘制,但会显着变慢。

+0

我听说Quartz几乎是OpenGL的包装。如果Quartz能够做到这一点,你应该可以在OpenGL中做到这一点。 CGPaths如何完成AA? 我使用的是一个名为Cocos2D的基于OpenGL的游戏引擎。 Afaik,你不能使用Quartz来绘制Cocos2d图层。 – quano 2009-11-29 00:06:54

+0

我对Cocos2D很熟悉。您总是可以绘制到CGImage并从该图像创建纹理以在TextureNode中绘制。 我不确定,但我不认为CGContext方法在绘图时依赖于OpenGL。绘制完东西后,该图像很可能由Quartz进行管理,并使用OpenGL进行显示。 – 2009-11-29 04:44:13

+0

谢谢埃德,我试过这个方法。这与OpenGL相比非常慢。如果你每秒只抽一次左右,可能会工作,但如果你需要更频繁地抽签,那么你就被搞砸了。我们在cocos2d论坛上有关于此的一个主题:http://www.cocos2d-iphone.org/forum/topic/2241 – quano 2009-11-29 16:12:36

3

问题是iPhone上的OpenGl呈现给帧缓冲区对象而不是主帧缓冲区,据我了解FBO不支持多重采样。

有很多技巧可以完成,例如以两倍的显示大小呈现给另一个FBO,然后依靠纹理过滤来平滑事情,而不是我已经尝试的东西,所以无法评论如何以及这个作品。

+0

我真的在OpenGL noob。你知道我在哪里可以找到更多关于这种方法? – quano 2009-11-29 16:14:06

4

解决此限制的一种方法是将线条镶嵌成纹理三角形条(如所示here)。

+0

链接现已停止 – paulm 2016-10-19 22:17:50

+0

修复了链接,谢谢。 – prideout 2017-04-21 15:15:09

6

使用http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/作为一个起点,我能得到消除锯齿线这样的: alt text

他们是不完美它们也不像我用Core Graphics绘制的那么好,但它们非常好。实际上,我绘制了两条相同的线(顶点) - 一次是较大的纹理和颜色,然后是较小的纹理和半透明的白色。

当线条重叠过紧并且alphas开始积累时,会出现文物。

+0

也许alpha可以通过设置自定义混合功能来解决? – jv42 2011-08-24 09:16:07

25

开始iOS 4.0版您有一个简单的解决方案,现在可以在整个OpenGL ES场景中使用Antialiasing,只需添加几行代码即可。 (几乎没有性能损失,至少在SGX GPU上)。

对于代码请阅读以下苹果Dev-Forum Thread。 还有一些示例图片是如何在我的博客上查找我的。

+2

感谢您发布这篇文章:我几乎开始编写一些严重的神秘代码,基于对这个问题的旧答案。 – benzado 2010-11-04 23:41:59

+2

到您的Apple开发论坛帖子的链接不再有效:我收到一个错误页面。 – 2012-07-11 20:39:29

+0

适用于我,请记住,您必须登录到您的开发者帐户才能查看论坛。 – Bersaelor 2012-07-12 10:26:31

0

把这个放在你的渲染方法和setUpFrame缓冲区中...... 你会得到消除锯齿的外观。

/*added*/ 
//[_context presentRenderbuffer:GL_RENDERBUFFER]; 

//Bind both MSAA and View FrameBuffers. 
glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer); 
// Call a resolve to combine both buffers 
glResolveMultisampleFramebufferAPPLE(); 
// Present final image to screen 
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer); 
[_context presentRenderbuffer:GL_RENDERBUFFER]; 
/*added*/ 
+3

...你已经宣布了msaaFramebuffer到底如何? – BlueVoodoo 2013-09-04 12:45:54