Quote:
Originally Posted by saran
Hi.. NewiPhoneDeveloper... I stumbled upon the same problem as digicide in an application i am building.. merging the UIImage with the EAGLview... u mentioned that u managed to merge the images using the 'legal' method...
cld you pls share it....
Thanx,
Saran.
|
Sure, let me try to remember. The whole thing is a bit complex but not really complicated, if you know openGL a bit. Maybe I'm not doing it the best way, but so far my method did a great job.
Here is a rough step by step guide for merging an image (or content of a UIImage) with content of an EAGLview object:
1) Create a new texture, using the texture2D class, like:
Code:
_textures[kTexture_Clean] = [[Texture2D alloc] initWithImage: [UIImage imageNamed:@"clean.png"]];
Mind, that "clean.png" is an image inside my project folder, that is just 320x480 pixels with nothing on it.
2) Bind the new texture:
Code:
glBindTexture(GL_TEXTURE_2D,[_textures[kTexture_Clean] name]);
3) The following grabs the screen content INCLUDING ALL ALPHA CHANNELS and puts it on our CLEAN texture:
Code:
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 320, 480);
Right now you have our framebuffer on the new texture. So, all you have to do now, is get your background image into the scene.
4) We're rebuilding the scene back to front. First we draw the background image - now using openGL:
Code:
[_textures[kTexture_Background] drawInRect:[self bounds]]; //
5) Draw the new texture (=Clean texture with our framebuffer on it) over the background image - blending enabled
Code:
[_textures[kTexture_Clean] drawInRect:[self bounds]:0.0:0.0]; //
Get the idea? Now you have everything in your scene and that also means, that you can now safely use glReadPixels to make a screenshot for you. To do so, simply call a method, like the one below:
Code:
- (void)grabScreen {
unsigned char buffer[320*480*4];
glReadPixels(0,0,320,480,GL_RGBA,GL_UNSIGNED_BYTE,&buffer);
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, &buffer, 320*480*4, NULL);
CGImageRef iref = CGImageCreate(320,480,8,32,320*4,CGColorSpaceCreateDeviceRGB(),kCGBitmapByteOrderDefault,ref,NULL,true,kCGRenderingIntentDefault);
width = CGImageGetWidth(iref);
height = CGImageGetHeight(iref);
size_t length = width*height*4;
uint32_t *pixels = (uint32_t *)malloc(length);
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width*4, CGImageGetColorSpace(iref), kCGImageAlphaLast | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), iref);
CGImageRef outputRef = CGBitmapContextCreateImage(context);
UIImage *outputImage = [UIImage imageWithCGImage:outputRef];
UIImageWriteToSavedPhotosAlbum(outputImage, nil, nil, nil); //YAY - SAVE IT :-)
CGContextRelease(context);
CGImageRelease(iref);
CGDataProviderRelease(ref);
}
In case the above steps don't make any sense, I suggest to check out the CrashLanding app and GLPaint app. I adopted parts of that code, when learning from it.
Hope, this helps...