texturas OpenGL ES de PNGs com transparência estão sendo prestados com artefatos estranhos e me deixando louco!

StackOverflow https://stackoverflow.com/questions/1079884

Pergunta

Estou começando a trabalhar no meu primeiro aplicativo para iPhone OpenGL, mas eu bati um obstáculo cedo.

Eu tenho um pouco de textura muito simples que eu quero usar como um sprite em um jogo 2D, mas processa com estranho 'aleatoriamente' pixels coloridos em cima.

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

Eu meio que tenho a sensação de que este é culpa do Photoshop, por isso, se alguém alguma coisa sobre isso, por favor me avise.

Se não do Photoshop, então ele tem que ser o meu código ... Então aqui está o código em questão ...

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

}

Esta função mistura produziu os melhores resultados.

Por favor, deixe-me saber o que você acha que está errado.

Muito obrigado, este problema foi me deixando louco.

Foi útil?

Solução

Um problema que pode ver a partir do código é que você não limpar seu contexto antes de desenhar a imagem. Desde sua imagem contém áreas transparentes e é composta no fundo, você só ver o que está na memória alocada por malloc. Tente configurar você quartzo Blend Mode para copiar antes de desenhar a imagem:

CGContextSetBlendMode(textureContext, kCGBlendModeCopy);

Você também pode usar calloc em vez de malloc, desde calloc lhe dá zerado memória.

Seu mistura OpenGL está correto:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

lhe dá Porter-Duff "OVER", que é o que normalmente você quiser.

Outras dicas

Tente apagar o seu CGContextRef primeiro:

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

Muito provavelmente sua imagem tem alguns pixels coloridos com um valor alfa zero, mas por causa da função de mistura que você está mostrando a eles. Tentar

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top