I have an iPhone game that uses images to display things such as buttons on screen to control the game. The images aren't huge, but I want to load them "lazily" and unload them from memory when they are not being used.
I have a function that loads images as follows:
void loadImageRef(NSString *name, GLuint location, CGImageRef *textureImage)
{
*textureImage = [UIImage imageNamed:name].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);
CGContextTranslateCTM(textureContext, 0, texHeight);
CGContextScaleCTM(textureContext, 1.0, -1.0);
CGContextDrawImage(textureContext, CGRectMake(0.0, 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);
}
The reason I pass the CGImageRef
to the function is so that I can free it later. But I don't know if this is the correct thing to do?
I call the function as follows (for example):
loadImageRef(@"buttonConfig.png", textures[IMG_CONFIG], &imagesRef[IMG_CONFIG]);
And when I'm finished with it I unload it as follows:
unloadImage(&imagesRef[IMG_CONFIG]);
which calls the function:
void unloadImage(CGImageRef *image)
{
CGImageRelease(*image);
}
But when I run the app, I get EXC_BAD_ACCESS error, either when unloading, or loading for the second time (i.e. when it is needed again). I don't see anything else to help determine the real cause of the problem.
Perhaps I am attacking this issue from the wrong angle. What is the usual method of lazy loading of images, and what is the usual way to unload the image to free up the memory?
Many thanks in advance,
Sam