web-dev-qa-db-fra.com

OpenGL ES iPhone - dessin de lignes anti-aliasées

Normalement, vous utiliseriez quelque chose comme:

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

Il semble bon dans le simulateur iPhone, mais sur l'iPhone, les lignes deviennent extrêmement fines et sans anti-crénelage.

Comment obtenez-vous AA sur iPhone?

37
quano

On peut obtenir l'effet d'anti-aliasing à très bon marché en utilisant des sommets avec l'opacité 0. Voici un exemple d'image pour expliquer:

alt text

Comparaison avec AA:

alt text

Vous pouvez lire un article à ce sujet ici:

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

Vous pourriez faire quelque chose de cette façon:

// 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);
59
quano

À partir de iOS version 4.0 , vous avez une solution simple, il est maintenant possible d'utiliser l'anticrénelage pour toute la scène OpenGL ES avec seulement quelques lignes de code ajouté. (Et presque aucune perte de performances, du moins sur le GPU SGX).

Pour le code, veuillez lire ce qui suit Apple Dev-Forum Thread . Il y a aussi quelques exemples d'images à quoi il ressemble pour moi sur mon blog.

25
Bersaelor

En utilisant http://answers.oreilly.com/topic/1669-how-to-render-anti-alias-lines-with-textures-in-ios-4/ comme point de départ, je a pu obtenir des lignes anti-aliasées comme celles-ci: alt text

Ils ne sont pas parfaits ni aussi agréables que ceux que j'avais dessinés avec Core Graphics, mais ils sont plutôt bons. En fait, je dessine deux fois les mêmes lignes (sommets) - une fois avec une texture et une couleur plus grandes, puis avec une texture plus petite et un blanc translucide.

Il y a des artefacts lorsque les lignes se chevauchent trop étroitement et que les alphas commencent à s'accumuler.

6
westsider

Une approche autour de cette limitation consiste à tesseler vos lignes en bandes triangulaires texturées (comme on le voit ici ).

4
prideout

Le problème est que sur l'iPhone, OpenGl se transforme en objet tampon de trame plutôt qu'en tampon de trame principal et si je comprends bien, les FBO ne prennent pas en charge le multi-échantillonnage.

Il existe différentes astuces qui peuvent être effectuées, telles que le rendu sur un autre FBO avec une taille d'affichage deux fois supérieure, puis en s'appuyant sur le filtrage de texture pour lisser les choses, pas quelque chose que j'ai essayé, donc je ne peux pas commenter comment cela fonctionne.

3
Paul

Je me souviens très précisément que j'ai essayé cela et qu'il n'y a pas de moyen simple de le faire en utilisant OpenGL sur l'iPhone. Vous pouvez dessiner à l'aide de CGPaths et d'un CGContextRef, mais cela sera beaucoup plus lent.

2
Ed Marty

Mettez ceci dans votre méthode de rendu et le tampon setUpFrame ... Vous obtiendrez une apparence anti-aliasée.

/*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*/
0
Abhishek Bedi