2009-07-03 4 views
12

Sto iniziando a lavorare sulla mia prima app per iPhone OpenGL, ma ho subito un problema.openGL Le trame ES dai PNG con trasparenza vengono renderizzate con strani artefatti e mi fanno impazzire!

Ho una piccola trama MOLTO SEMPLICE che voglio usare come sprite in un gioco 2D, ma rende con strani pixel colorati "casualmente" in alto.

http://i40.tinypic.com/2s7c9ro.png < - Screenshot qui

I sorta della sensazione che questo è colpa di Photoshop, quindi se qualcuno qualcosa a tale proposito per favore fatemelo sapere.

Se non di Photoshop allora devo essere il mio codice ... ecco il codice in questione ...

- (void)loadTexture { 

CGImageRef textureImage = [UIImage imageNamed:@"zombie0.png"].CGImage; 

if (textureImage == nil) { 
    NSLog(@"Failed to load texture image"); 
    return; 
} 

NSInteger texWidth = CGImageGetWidth(textureImage); 
NSInteger texHeight = CGImageGetHeight(textureImage); 

GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4); 

CGContextRef textureContext = CGBitmapContextCreate(textureData, texWidth, texHeight, 8, texWidth * 4, CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast); 

CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage); 

CGContextRelease(textureContext); 

glGenTextures(1, &textures[0]); 

glBindTexture(GL_TEXTURE_2D, textures[0]); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); 

free(textureData); 

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

glEnable(GL_TEXTURE_2D); 

glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

}

Questa funzione miscela ha dato i migliori risultati.

Per favore, fammi sapere cosa pensi sia sbagliato.

Grazie mille, questo problema mi sta facendo impazzire.

risposta

19

Un problema che posso vedere dal codice è che non si cancella il contesto prima di disegnare l'immagine. Poiché l'immagine contiene aree trasparenti e viene composta sullo sfondo, è sufficiente vedere cosa c'è nella memoria allocata da malloc. Provate voi impostare la modalità di miscelatura quarzo per copiare prima di disegnare l'immagine:

CGContextSetBlendMode(textureContext, kCGBlendModeCopy); 

Si potrebbe anche usare calloc invece di malloc, dal momento che calloc dà azzerato la memoria.

tuo miscelazione OpenGL è corretta:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

ti dà Porter-Duff "OVER", che è quello che di solito si desidera.

+0

SEI FANTASTICO! Questa risposta mi rende totalmente felice e ha senso per me! Avevo la sensazione che quei artefatti fossero una sorta di memoria, ma non ci avevo pensato. Grazie ancora così tanto! Regola! –

+0

* diventa rosso * ... felice di poterti aiutare. –

+0

GRAZIE anche! Non riuscivo a capire perché avevo tutti questi artefatti, ora sembra fantastico. – mk12

1

Prova cancellando la tua CGContextRef prima:

CGContextSetRGBFillColor(ctxt, 1, 1, 1, 0); 
CGContextFillRect(ctxt, CGRectMake(0, 0, w, h)); 
0

Molto probabilmente la vostra immagine ha dei pixel colorati con un valore di alfa pari a zero, ma a causa della funzione di blending si sta mostrando loro. Prova

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+0

Questa funzione di fusione fornisce buoni risultati solo per alfa non premoltiplicato, che raramente è in quarzo. –