So I’ve struggled quite a bit getting a UIImage from my OpenGL view, as most of the stackoverflow.com posts were about OpenGL ES 1.0 (which seems a little bit different from 2.0). A few days later i contact the Apple Support as i had a few help-tickets left and they were able to tell me one line I was missing in my code. As this may be helpful to other programmers i decided to post it here. Here’s the source code (just replace the ‘draw code here’-comment with your code).
@interface RenderToImage() { EAGLContext* myContext; GLuint framebuffer; GLuint colorRenderbuffer; GLuint depthRenderbuffer; int width; int height; } @end @implementation RenderToImage - (id) init { self = [super init]; if (self) { } return self; } -(void) setupOpenGL { [EAGLContext setCurrentContext:myContext]; glGenFramebuffersOES(1, &framebuffer); glBindFramebufferOES(GL_FRAMEBUFFER, framebuffer); glGenRenderbuffersOES(1, &colorRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER, colorRenderbuffer); glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGBA8_OES, width, height); glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); //GLuint depthRenderbuffer; glGenRenderbuffersOES(1, &depthRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER, depthRenderbuffer); glRenderbufferStorageOES(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ; if(status != GL_FRAMEBUFFER_COMPLETE) { NSLog(@"failed to make complete framebuffer object %x", status); } sample = [[OpenGLSample alloc] init]; [sample setContext:myContext]; [sample setupGL]; } -(UIImage *) renderWithSize:(CGSize)size { myContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; width = size.width; height = size.height; [EAGLContext setCurrentContext:myContext]; [self setupOpenGL]; glViewport(0,0,width,height); glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); // --- DRAW CODE HERE --- // grabbing image from FBO GLint backingWidth, backingHeight; glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); NSInteger x = 0, y = 0; NSInteger dataLength = width * height * 4; GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); glPixelStorei(GL_PACK_ALIGNMENT, 4); glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); 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); UIGraphicsBeginImageContext(CGSizeMake(width, height)); CGContextRef cgcontext = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, width, height), iref); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); free(data); CFRelease(ref); CFRelease(colorspace); CGImageRelease(iref); [EAGLContext setCurrentContext:nil]; return image; } @end
Recent Comments