获取openGL ES中的视图截图
来源:互联网 发布:自动发微博淘宝客软件 编辑:程序博客网 时间:2024/06/09 22:23
How do I take a snapshot of my OpenGL ES view and save the result in a UIImage?
A: The OpenGL ES commands issued by your application are sent to the current rendering context (an EAGLContext object) which contains state information of your rendering target. To take a snapshot of your OpenGL ES view, make sure you bind to the correct context and framebuffer, and then call glReadPixels to obtain the pixel data from the framebuffer. You can then create aCGImage with the pixel data, and then a UIImage out of the CGImage.
The UIKit coordinate system (y down) is upside down to the OpenGL ES and Quartz coordinate system (y up). You should take this into account when creating the UIImage from the CGImage. In the following listing, we demonstrate how to create a flipped bitmap context using UIGraphics calls and then render the original image to it.
On iOS 4 and later, UIGraphicsBeginImageContextWithOptions allows you to provide with a scale factor. When setting it to your OpenGL ES view's contentScaleFactor property value and it is greater than 1.0, you will get the sharp, high-resolution snapshot for your OpenGL ES drawing. On iOS prior to 4, the code falls back to use UIGraphicsBeginImageContext.
Important By default, the contents of a renderbuffer are invalidated after you present them to the display. Therefore, to get defined results when reading your OpenGL ES content, you must do one of the following:
1) Call glReadPixels before calling EAGLContext/-presentRenderbuffer:, or
2) Set the CAEAGLLayer's retained backing property to true to retain the contents of the layer. However, this can have adverse performance implications so you are cautioned to use this setting only when necessary.
The above restrictions do not apply for offscreen, non-displayable framebuffers.
Listing 1 OpenGL ES view snapshot. Call this method after you draw and before -presentRenderbuffer:.
- (UIImage*)snapshot:(UIView*)eaglview
{
GLint backingWidth, backingHeight;
// Bind the color renderbuffer used to render the OpenGL ES view
// If your application only creates a single color renderbuffer which is already bound at this point,
// this call is redundant, but it is needed if you're dealing with multiple renderbuffers.
// Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);
// Get the size of the backing CAEAGLLayer
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;
}
- 获取openGL ES中的视图截图
- iphone opengl es 截图
- OpenGL ES 模型视图操作
- Opengl ES 视图与投影
- iOS开发- OpenGL ES屏幕截图
- iOS开发- OpenGL ES屏幕截图
- OpenGL ES 模型视图之缩放操作
- OpenGL ES 模型视图之平移操作
- OpenGL ES 模型视图矩阵操作
- OpenGL ES 模型视图操作入门
- OpenGL ES随手记——视图
- Android中的OpenGL ES简介
- Android中的OpenGL ES简介
- OpenGL ES中的变化矩阵
- OpenGL ES中的坐标变换
- 【OpenGL】Android 中的 skia 和 OpenGL ES
- opengl中的视图变换
- OpenGL ES教程I之创建OpenGL视图(原文对照)
- javascript 中的内存泄露
- android IPC及原理简介
- Callable与Future
- 改变一个文件的拥有者,chown的简单介绍
- 字符串比较
- 获取openGL ES中的视图截图
- waveout 播放声音
- 类集框架(一)
- java中的字符串转换成c的字符串 工具方法
- Android 检测网络连接状态
- 关于进程访问令牌( access token ) 及 OpenProcessToken
- linux usb 打印机命令
- 如何区分Shapefile,Coverage,Geodatabase
- ubutn12.04 安装配置nginx fpm mysql apc