40

Normally, you'd use something like:

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

It looks good in the iPhone simulator, but on the iPhone the lines get extremely thin and w/o any anti aliasing.

How do you get AA on iPhone?

quano
  • 18,812
  • 25
  • 97
  • 108

7 Answers7

62

One can achieve the effect of anti aliasing very cheaply using vertices with opacity 0. Here's an image example to explain:

alt text

Comparison with AA:

alt text

You can read a paper about this here:

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

You could do something along this way:

// 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);
quano
  • 18,812
  • 25
  • 97
  • 108
  • 6
    Is there anything comparable (but simpler) for drawing anti-aliased lines - the kind that one might use to graph equations, etc. ?? In other words, for drawing that use GL_LINE_STRIP instead of GL_TRIANGLE_STRIP. Everything that I am drawing seems so pixelated. I am exploring using GL_POINT_SPRITE_OES (per Apple's GLPaint sample code) but it means creating points for every pixel location ... or so it seems. And I would like to let OpenGL-ES do the tweening for me. – westsider Aug 03 '10 at 19:58
  • Can't understand what are colors, points ... Can you directly show the example in drawing circle? – TomSawyer Oct 20 '16 at 09:41
26

Starting in iOS Version 4.0 you have an easy solution, it's now possible to use Antialiasing for the whole OpenGL ES scene with just a few lines of added code. (And nearly no performance loss, at least on the SGX GPU).

For the code please read the following Apple Dev-Forum Thread. There are also some sample pictures how it looks for me on my blog.

Kheldar
  • 5,361
  • 3
  • 34
  • 63
Bersaelor
  • 2,517
  • 34
  • 58
  • 2
    Thanks for posting this: I almost started writing some seriously arcane code based on the older answers to this question on SO. – benzado Nov 04 '10 at 23:41
  • 2
    The link to your Apple dev forum post no longer works: I get an error page. – Kyle Fox Jul 11 '12 at 20:39
  • Works for me, remember you have to be logged into your developer account to view the forums. – Bersaelor Jul 12 '12 at 10:26
  • It doesn't work for me either.. I have an iPhone paid developer account but I can't log into the apple developer forums (any of them). – mm24 Aug 10 '12 at 08:37
  • It's possible you have to register another time for the forums, after you get your iOS-Developer Account. It was really long ago so I don't remember the exact details. I just logged in another time and the thread itself is fine and the forums accessible for me. – Bersaelor Aug 10 '12 at 09:23
6

Using http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/ as a starting point, I was able to get anti-aliased lines like these: alt text

They aren't perfect nor are they as nice as the ones that I had been drawing with Core Graphics, but they are pretty good. I am actually drawing same lines (vertices) twice - once with bigger texture and color, then with smaller texture and translucent white.

There are artifacts when lines overlap too tightly and alphas start to accumulate.

westsider
  • 4,967
  • 5
  • 36
  • 51
4

One approach around this limitation is tessellating your lines into textured triangle strips (as seen here).

prideout
  • 2,895
  • 1
  • 23
  • 25
3

The problem is that on the iPhone OpenGl renders to a frame buffer object rather than the main frame buffer and as I understand it FBO's don't support multisampling.

There are various tricks that can be done, such as rendering to another FBO at twice the display size and then relying on texture filtering to smooth things out, not something that I've tried though so can't comment on how well this works.

Paul
  • 91
  • 2
2

I remember very specifically that I tried this and there is no simple way to do this using OpenGL on the iPhone. You can draw using CGPaths and a CGContextRef, but that will be significantly slower.

Ed Marty
  • 39,590
  • 19
  • 103
  • 156
  • I hear that Quartz is pretty much a wrapper for OpenGL. If Quartz can do it, you should be able to do it in OpenGL also. How does CGPaths accomplish AA? I'm using an OpenGL based game engine called Cocos2D. Afaik, you cannot draw using Quartz into a Cocos2d layer. – quano Nov 29 '09 at 00:06
  • I am familiar with Cocos2D. You can always draw to a CGImage and create a texture from that image to draw in a TextureNode. I don't know for sure, but I don't think that the CGContext methods are relying on OpenGL when drawing. After something is drawn, that image may very well be managed by Quartz and displayed using OpenGL. – Ed Marty Nov 29 '09 at 04:44
  • Thanks Ed, I tried this method. It's really slow in comparison to OpenGL. Might work if you only draw once a second or so, but if you need to draw more frequently, you're screwed. We have a thread at the cocos2d forum about this here: http://www.cocos2d-iphone.org/forum/topic/2241 – quano Nov 29 '09 at 16:12
0

Put this in your render method and setUpFrame buffer... You will get anti-aliased appearance.

/*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*/
Stuart
  • 36,683
  • 19
  • 101
  • 139
Abhishek Bedi
  • 5,205
  • 2
  • 36
  • 62