views:

99

answers:

1

Hey,

I've been using this method (I think I got it from one of Apple's example code projects):

- (void)loadTexture:(NSString *)name intoLocation:(GLuint)location
{ 
 CGImageRef textureImage = [UIImage imageNamed:name].CGImage;

 if(textureImage == nil)
 {
  NSLog(@"Failed to load texture!");
  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);

 //The Fix:
 //CGContextClearRect(textureContext, CGRectMake(0.0f, 0.0f, texWidth, texHeight));

 CGContextDrawImage(textureContext, CGRectMake(0, 0, (float)texWidth, (float)texHeight), textureImage);
 CGContextRelease(textureContext);

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

I then load in my textures like so in the initWithCoder method:

glGenTextures(NUM_OF_TEXTURES, &textures[0]);
[self loadTexture:@"1.png" intoLocation:textures[0]];
[self loadTexture:@"2.png" intoLocation:textures[1]];
[self loadTexture:@"3.png" intoLocation:textures[2]];
[self loadTexture:@"4.png" intoLocation:textures[3]];
[self loadTexture:@"5.png" intoLocation:textures[4]]; 

Now this works great for me, but when the images loaded contain transparent areas, they will show the previous images behind them.

For example, if all five images have transparent areas on them:

  • 1.png will show as it should.
  • 2.png will show with 1.png in the background.
  • 3.png will show with 2.png in the background with 1.png in the background.
  • etc...

I thought this would be in my drawing code, but even when I disable GL_BLEND this still happens. I am drawing using vertex arrays using GL_TRIANGLE_FAN.

EDIT: Further explanation

Here are the 3 textures I'm using in my game:

alt text

Using the code to load the textures and after binding them and drawing, this is what happens:

alt text

Surely this is not transparency functioning as intended. If anyone could help that would be great.

Thanks

+1  A: 

I had this same problem. You need to clear the CGContextRef before drawing the texture into it. It just happens to hold the last image, it could just as well be uninitialized memory or something.

CGContextClearRect( cgContext, CGRectMake( 0.0f, 0.0f, width, height ) );

Call this right before your CGContextDrawImage.

Thanks! Not sure why that wasn't included in the example I used. Solved my problemo anyway :)
ing0