Hi,
I am doing some render to texture stuff using FBOs and Texture2D inside EAGLView (using the default OpenGL ES XCode project template).
The Texture2D object is initialized with a mist which is dynamically changed by rendering to an FBO. I setup the FBO this way:
Code:
glGenFramebuffersOES(1, &mistFBO);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mistFBO);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, self.mist.name, 0);
GLuint status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
if (status != GL_FRAMEBUFFER_COMPLETE_OES)
{
// didn't work
}
This mist is displayed over a background image.
Now, when my application quits, I want to save the mist state. I use this code to save:
Code:
- (void)applicationWillTerminate:(NSNotification *)notification
{
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mistFBO);
glViewport(0, 0, backingWidth, backingHeight);
CGRect rect = [[UIScreen mainScreen] bounds];
int width = rect.size.width;
int height = rect.size.height;
NSInteger myDataLength = width * height * 4;
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
//glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
for(int y = 0; y <height; y++) {
for(int x = 0; x <width * 4; x++) {
buffer2[((height - 1 - y) * width * 4 + x)] = buffer[(y * 4 * width + x)];
}
}
free(buffer); // YOU CAN FREE THIS NOW
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, releaseData);
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef); // YOU CAN RELEASE THIS NOW
CGDataProviderRelease(provider); // YOU CAN RELEASE THIS NOW
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; // change this to manual alloc/init instead of autorelease
CGImageRelease(imageRef); // YOU CAN RELEASE THIS NOW
//Now lets save the mist
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
NSData *mistData2 = UIImagePNGRepresentation(image); //just take a snapshot of the mist
[archiver encodeObject:mistData2 forKey:kMistKey];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES]; initForWritingWithMutableData:data];
}
I load the archived mist on the next startup by:
Code:
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
self.mistData = [unarchiver decodeObjectForKey:kMistKey];
[unarchiver finishDecoding];
UIImage *try = [UIImage imageWithData:self.mistData];
self.mist = [[Texture2D alloc] initWithImage:try];
Now, when I load the archived mist on the next application launch, I see that the mist is opaque! That is, I am unable to see the background image through the mist, instead I just get a black background. If I disable mist display, the bg image does show.
If I ignore the archived mist and always initialize mist by this:
Code:
self.mist = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"DefaultMist.png"]];
then it all works fine, but of course I do not have the mist state saved and retained.
Comments?
Regards,
Kid