PNG alpha problem OGLES
Hello!
I have problems displaying PNGs images with an alpha channel if the dimensions are small. Here is what the problem looks like:
![[Image: bugg.jpg]](http://members.gamedev.net/osan/images/bugg.jpg)
As you can see the apple should have transparency around it but instead there are lots of garbage pixels. The apple has a dimension of 32x32. I have no problem displaying larger images.
My image is loaded with this function:
Any help appreciated.
I have problems displaying PNGs images with an alpha channel if the dimensions are small. Here is what the problem looks like:
![[Image: bugg.jpg]](http://members.gamedev.net/osan/images/bugg.jpg)
As you can see the apple should have transparency around it but instead there are lots of garbage pixels. The apple has a dimension of 32x32. I have no problem displaying larger images.
My image is loaded with this function:
Code:
GLuint loadTexture(NSString *filename){
GLuint location;
CGImageRef textureImage = [UIImage imageNamed:filename].CGImage;
if (textureImage == nil) {
NSLog(@"Failed to load texture image");
return false;
}
NSInteger texWidth = CGImageGetWidth(textureImage);
NSInteger texHeight = CGImageGetHeight(textureImage);
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
memset(textureData,0,sizeof(textureData));
CGContextRef textureContext = CGBitmapContextCreate(textureData,texWidth, texHeight,8, texWidth*4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast);
// Rotate the image
CGContextTranslateCTM(textureContext, 0, texHeight);
CGContextScaleCTM(textureContext, 1.0, -1.0);
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage);
CGContextRelease(textureContext);
glGenTextures(1, &location);
glBindTexture(GL_TEXTURE_2D, location);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
return location;
}Any help appreciated.
Change the malloc to calloc.
Thanks, it worked like a charm. Seems my memset was a bit of... thanks again
I had the same problem with a 16x16 image.
Was gonna grudgingly enlarge it to 64x64 despite it having an onscreen diameter of 10 pixels, but this saved me the trouble.
Thanks!
Was gonna grudgingly enlarge it to 64x64 despite it having an onscreen diameter of 10 pixels, but this saved me the trouble.
Thanks!
MrOlofsson Wrote:Thanks, it worked like a charm. Seems my memset was a bit of... thanks again
So you know the trouble was this:
Code:
memset(textureData,0,sizeof(textureData));sizeof(textureData) isn't doing what you think it's doing. I'm not at a machine with a compiler right now, but I think that will return the size of the pointer, not the size of the array pointed to by said pointer.
You'd want:
Code:
memset(textureData,0,sizeof(texWidth * texHeight * 4));Nonetheless calloc is simpler, might even be faster.
TomorrowPlusX Wrote:You'd want:
Code:
memset(textureData,0,sizeof(texWidth * texHeight * 4));
Won't work either. I think you mean:
Code:
memset(textureData, 0, texWidth * texHeight * 4);ThemsAllTook Wrote:Won't work either. I think you mean:
Code:
memset(textureData, 0, texWidth * texHeight * 4);
Or to be even more verbatim (and avoid polluting code with magic numbers):
Code:
memset(textureData, 0, texWidth * texHeight * sizeof(unsigned int));warmi Wrote:Or to be even more verbatim (and avoid polluting code with magic numbers):
Code:
memset(textureData, 0, texWidth * texHeight * sizeof(unsigned int));
Nope - that would be
Code:
memset(textureData, 0, texWidth * texHeight * 4 * sizeof(UInt8));backslash Wrote:Nope - that would be
But what's the point of using sizeof(UInt8) when the answer's in the name?Code:
memset(textureData, 0, texWidth * texHeight * 4 * sizeof(UInt8));
Depends how you look at it ... I tend to look at RGBA as an unsigned int as opposed to 4 unsigned chars.
Looks like fun, I wanna play too! How about:
or maybe better yet:
Code:
#define BYTES_PER_PIXEL 4
memset(textureData, 0, texWidth * texHeight * BYTES_PER_PIXEL);or maybe better yet:
Code:
#define FOUR_BYTES_PER_PIXEL 4
memset(textureData, 0, texWidth * texHeight * FOUR_BYTES_PER_PIXEL);AnotherJake Wrote:Looks like fun, I wanna play too! How about:
Code:
#define BYTES_PER_PIXEL 4
memset(textureData, 0, texWidth * texHeight * BYTES_PER_PIXEL);
or maybe better yet:
Code:
#define FOUR_BYTES_PER_PIXEL 4
memset(textureData, 0, texWidth * texHeight * FOUR_BYTES_PER_PIXEL);
Hehe ... you know , whatever you put in there it is still better than just a random magic number.
I suppose if you want to discourage "magic" numbers then you really should use descriptive constants, rather than sizeof(unsigned int), since that doesn't really say anything either
AnotherJake Wrote:I suppose if you want to discourage "magic" numbers then you really should use descriptive constants, rather than sizeof(unsigned int), since that doesn't really say anything either
Well, in this particular context I think it is more than enough, it says that the basic unit you are dealing with is an unsigned int.
Maybe unsigned int means it represents a four byte pixel to you, but not necessarily to someone else. If you look at it like that, unsigned int is only as helpful as the number 4.
Either one would work for me, since I'd understand the context regardless.
Either one would work for me, since I'd understand the context regardless.
Quote:Well, in this particular context I think it is more than enough, it says that the basic unit you are dealing with is an unsigned int.No you're not - RGBA with unsigned bytes is 4 separate single bytes, which happens to be the same size as an unsigned int on many systems, but you are making the very mistake you are telling us all to avoid. I like Jake's solution.

