2009-11-28 19 views
37

Normalmente, devi usare qualcosa di simile a:OpenGL ES iPhone - disegnare linee anti-aliasing

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

Sembra buono nel simulatore iPhone, ma su iPhone le linee di diventare estremamente sottile e w/o qualsiasi di anti aliasing.

Come si ottiene AA su iPhone?

+0

Si potrebbe renderli come linee alias quindi applicare una [filtro di fioritura] (http://ofps.oreilly.com/titles/9780596804824/chadvanced.html#fig-BloomTriptych) – bobobobo

+0

@bobobobo il link è morto . – TomSawyer

risposta

59

si può ottenere l'effetto di anti aliasing molto a buon mercato usando i vertici con l'opacità 0. Ecco un esempio un'immagine per spiegare:

alt text

Confronto con AA:

alt text

Puoi leggere un articolo al riguardo qui:

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

Si potrebbe fare qualcosa insieme in questo modo:

// 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

Wow! metodo e descrizione semplici, chiari e perfetti. Bello! – Eonil

+5

C'è qualcosa di paragonabile (ma più semplice) per disegnare linee anti-alias: il tipo che si potrebbe usare per tracciare equazioni, ecc. ?? In altre parole, per il disegno che utilizza GL_LINE_STRIP invece di GL_TRIANGLE_STRIP. Tutto ciò che sto disegnando sembra così pixelato. Sto esplorando usando GL_POINT_SPRITE_OES (secondo il codice di esempio GLPaint di Apple) ma significa creare punti per ogni posizione di pixel ... o almeno così sembra. E vorrei lasciare che OpenGL-ES faccia il tweening per me. – westsider

+0

Grazie mille :) –

2

Mi ricordo in particolare che ho provato questo e non c'è un modo semplice per farlo usando OpenGL su iPhone. Puoi disegnare usando CGPaths e un CGContextRef, ma questo sarà molto più lento.

+0

Ho sentito che Quartz è praticamente un wrapper per OpenGL. Se Quartz può farlo, dovresti essere in grado di farlo anche in OpenGL. In che modo CGPaths realizza AA? Sto usando un motore di gioco basato su OpenGL chiamato Cocos2D. Afaik, non puoi disegnare usando Quartz in un livello Cocos2d. – quano

+0

Ho familiarità con Cocos2D. Puoi sempre disegnare su una macchia CGI e creare una texture da quella immagine per disegnare in un TextureNode. Non lo so per certo, ma non penso che i metodi di CGContext si basino su OpenGL durante il disegno. Dopo che qualcosa è stato disegnato, quell'immagine potrebbe essere gestita da Quartz e visualizzata usando OpenGL. –

+0

Grazie Ed, ho provato questo metodo. È molto lento rispetto a OpenGL. Potrebbe funzionare se disegni solo una volta al secondo, ma se hai bisogno di disegnare più spesso, sei fregato. Abbiamo una discussione al forum cocos2d su questo qui: http://www.cocos2d-iphone.org/forum/topic/2241 – quano

3

Il problema è che su iPhone OpenGl esegue il rendering su un oggetto frame buffer anziché sul frame buffer principale e, a quanto ho capito, gli FBO non supportano il multisampling.

Ci sono vari trucchi che è possibile eseguire, ad esempio il rendering su un altro FBO con una dimensione doppia dello schermo e quindi fare affidamento sul filtro della trama per appianare le cose, non qualcosa che ho provato, quindi non posso commentare come bene questo funziona.

+0

Sono davvero noob in OpenGL. Sai dove posso trovare ulteriori informazioni su questo metodo? Il collegamento – quano

4

Un approccio attorno a questa limitazione è la tassellazione delle linee in strisce triangolari strutturate (come visto here).

+0

è morto – paulm

+0

risolto il collegamento, grazie. – prideout

6

Utilizzando http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/ come punto di partenza, sono stato in grado di ottenere linee di anti-alias come questi: alt text

Non sono perfetti né sono belli come quelli che avevo disegnato con Core Graphics, ma sono piuttosto buoni. In realtà sto disegnando due volte le stesse linee (vertici) - una volta con texture e colori più grandi, quindi con una trama più piccola e un bianco traslucido.

Ci sono artefatti quando le linee si sovrappongono troppo strettamente e gli alfa iniziano ad accumularsi.

+0

Forse è possibile correggere l'alpha impostando la funzione di fusione personalizzata? – jv42

25

A partire da iOS versione 4.0 si ha una soluzione semplice, ora è possibile utilizzare l'antialias per l'intera scena OpenGL ES con solo poche righe di codice aggiunto. (E quasi nessuna perdita di prestazioni, almeno sulla GPU SGX).

Per il codice leggere la seguente Apple Dev-Forum Thread. Ci sono anche alcune immagini di esempio su come mi cerca sul mio blog.

+2

Grazie per aver postato questo: ho quasi iniziato a scrivere codice seriamente arcano basato sulle risposte più vecchie a questa domanda su SO. – benzado

+2

Il link al tuo forum del forum di dev di Apple non funziona più: ricevo una pagina di errore. –

+0

Funziona per me, ricorda che devi accedere al tuo account sviluppatore per visualizzare i forum. – Bersaelor

0

Inserire questo nel metodo di rendering e setUpFrame buffer ... Si otterrà l'aspetto anti-alias.

/*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

... e hai dichiarato il msaaFramebuffer come esattamente? – BlueVoodoo