2
votes

I am loading a PNG texture and I am getting weird artifacts on images that have a lot of alpha transparency.

Here is the source png: http://imgur.com/M8Wj3

Here is the texture in game on a white background: http://imgur.com/anliu

Here is the code I use to load the images:

NSString* pTextureNameString = [NSString stringWithFormat:@"%s", fileNameWithPath];
UIImage* pImage = [UIImage imageNamed:pTextureNameString];

GLubyte* pImageData = (GLubyte*)malloc(pImage.size.width * pImage.size.height * 4);
CGContextRef imageContext = CGBitmapContextCreate(pImageData, pImage.size.width, pImage.size.height, 8, pImage.size.width * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pImage.size.width, pImage.size.height), pImage.CGImage);
CGContextRelease(imageContext);

// Build A Texture From The Data
glGenTextures(1, &m_textureID);                                 // generate opengl texture id
glBindTexture(GL_TEXTURE_2D, m_textureID);          // Bind Our Texture

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Mipmap Linear Filtering

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pImage.size.width, pImage.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImageData);

The memory for pImageData is already messed up after grabbing it from the UIImage, the first pixel is correctly red, but the next pixel should be transparent (like the 3rd pixel)

red ok    bad pixel ok       bad pixel etc...
FF0000FF  05F04713  00000000 70EF7D15  302635B0 02000000 00000000

I turned png compression off in the build settings, but it did not make a difference. Anyone have any ideas? The alpha/opengl settings seem to be correct, since changing this texture to TGA or compressing to PVRTC results in a correct image.

1
My apologies, didn't realize the checkmark meant "accept". Stackoverflow should really add some text there...Nitzan Wilnai

1 Answers

4
votes

Aha, found the answer here: openGL ES textures from PNGs with transparency are being rendered with weird artifacts and driving me nuts!

Adding the following line fixes the problem:

CGContextRef imageContext = CGBitmapContextCreate(pImageData, pImage.size.width, pImage.size.height, 8, pImage.size.width * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);

// Set the correct blending copy mode!
CGContextSetBlendMode(imageContext, kCGBlendModeCopy);

CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pImage.size.width, pImage.size.height), pImage.CGImage);