Note that there are some explanatory texts on larger screens.

plurals
  1. POiOS OpenGL ES 2.0: Offscreen render and save the result to an UIImage
    text
    copied!<p>I'm using OpenGL ES to render some special effects, I don't want to show this to user, I just want to save the result as an UIImage, can anybody please help me?</p> <p>this is the code I'm using, I can get an image which contains the red clear color I use, but no geometry drawing shown.</p> <pre><code>#import "RendererGL.h" #import &lt;GLKit/GLKit.h&gt; #import &lt;UIKit/UIKit.h&gt; #import &lt;OpenGLES/EAGL.h&gt; #import &lt;OpenGLES/EAGLDrawable.h&gt; #import &lt;OpenGLES/ES2/glext.h&gt; #import &lt;QuartzCore/QuartzCore.h&gt; static NSInteger WIDTH_IN_PIXEL = 400; static NSInteger HEIGHT_IN_PIXEL = 300; typedef struct { GLKVector3 positionCoords; } SceneVertex; static const SceneVertex vertices[] = { {{-0.5f, -0.5f, 0.0}}, // lower left corner {{ 0.5f, -0.5f, 0.0}}, // lower right corner {{-0.5f, 0.5f, 0.0}} // upper left corner }; @implementation RendererGL { EAGLContext* _myContext; GLuint _framebuffer; GLuint _colorRenderbuffer; GLuint _depthRenderbuffer; GLuint _vertexBufferID; GLKBaseEffect *_baseEffect; } - (id) init { self = [super init]; if (self) { _myContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:_myContext]; [self setupOffscreenBuffer]; [self setUpEffect]; [self renderImage]; [self saveImage]; //this do works, since I get an image, but the image only contains the red color I used to clear } return self; } -(void)setUpEffect { _baseEffect = [[GLKBaseEffect alloc] init]; _baseEffect.useConstantColor = GL_TRUE; _baseEffect.constantColor = GLKVector4Make(0.0f, 0.0f, 1.0f, 1.0f); } //this code is from apples document -(void)setupOffscreenBuffer { glGenFramebuffers(1, &amp;_framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); glGenRenderbuffers(1, &amp;_colorRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer); glGenRenderbuffers(1, &amp;_depthRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL); glFramebufferRenderbuffer(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); } } - (void) renderImage { GLenum error = GL_NO_ERROR; glClearColor(1, 0, 0, 1); //red clear color, this can be seen glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_DEPTH_TEST); [_baseEffect prepareToDraw]; glGenBuffers(1, &amp;_vertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); error = glGetError(); if (error != GL_NO_ERROR) { NSLog(@"error happend, error is %d, line %d",error,__LINE__); } glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL); glDrawArrays(GL_TRIANGLES,0,3); error = glGetError(); if (error != GL_NO_ERROR) { NSLog(@"error happend, error is %d, line %d",error,__LINE__); } glFinish(); error = glGetError(); if (error != GL_NO_ERROR) { NSLog(@"error happend, error is %d, line %d",error,__LINE__); } } -(void)saveImage { GLenum error = GL_NO_ERROR; NSInteger x = 0, y = 0; NSInteger dataLength = WIDTH_IN_PIXEL * HEIGHT_IN_PIXEL * 4; GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); glPixelStorei(GL_PACK_ALIGNMENT, 4); glReadPixels(x, y, WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL, GL_RGBA, GL_UNSIGNED_BYTE, data); NSData *pixelsRead = [NSData dataWithBytes:data length:dataLength]; error = glGetError(); if (error != GL_NO_ERROR) { NSLog(@"error happend, error is %d, line %d",error,__LINE__); } CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGImageRef iref = CGImageCreate(WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL, 8, 32, WIDTH_IN_PIXEL * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, ref, NULL, true, kCGRenderingIntentDefault); UIGraphicsBeginImageContext(CGSizeMake(WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL)); CGContextRef cgcontext = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, WIDTH_IN_PIXEL, HEIGHT_IN_PIXEL), iref); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); NSData *d = UIImageJPEGRepresentation(image, 1); NSString *documentDirPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; static NSInteger imageNO = 1; imageNO++; NSString *savingPath = [documentDirPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.jpg",imageNO]]; BOOL succ = [d writeToFile:savingPath atomically:NO]; //is succeeded UIGraphicsEndImageContext(); free(data); CFRelease(ref); CFRelease(colorspace); CGImageRelease(iref); } @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload