Created
January 30, 2011 21:27
-
-
Save yeonsh/803265 to your computer and use it in GitHub Desktop.
Capture OpenGL ES View as an Image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (UIImage*)snapshot:(UIView*)eaglview | |
{ | |
// Get the size of the backing CAEAGLLayer | |
GLint backingWidth, backingHeight; | |
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer); | |
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); | |
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); | |
NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight; | |
NSInteger dataLength = width * height * 4; | |
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); | |
// Read pixel data from the framebuffer | |
glPixelStorei(GL_PACK_ALIGNMENT, 4); | |
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); | |
// Create a CGImage with the pixel data | |
// If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel | |
// otherwise, use kCGImageAlphaPremultipliedLast | |
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); | |
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); | |
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, | |
ref, NULL, true, kCGRenderingIntentDefault); | |
// OpenGL ES measures data in PIXELS | |
// Create a graphics context with the target size measured in POINTS | |
NSInteger widthInPoints, heightInPoints; | |
if (NULL != UIGraphicsBeginImageContextWithOptions) { | |
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration | |
// Set the scale parameter to your OpenGL ES view's contentScaleFactor | |
// so that you get a high-resolution snapshot when its value is greater than 1.0 | |
CGFloat scale = eaglview.contentScaleFactor; | |
widthInPoints = width / scale; | |
heightInPoints = height / scale; | |
UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale); | |
} | |
else { | |
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext | |
widthInPoints = width; | |
heightInPoints = height; | |
UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints)); | |
} | |
CGContextRef cgcontext = UIGraphicsGetCurrentContext(); | |
// UIKit coordinate system is upside down to GL/Quartz coordinate system | |
// Flip the CGImage by rendering it to the flipped bitmap context | |
// The size of the destination area is measured in POINTS | |
CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); | |
CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref); | |
// Retrieve the UIImage from the current context | |
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
// Clean up | |
free(data); | |
CFRelease(ref); | |
CFRelease(colorspace); | |
CGImageRelease(iref); | |
return image; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment