thomasguenzel.com

Apps/Programming

Category: iOS (page 2 of 2)

SpaceDebris online

My newest game, SpaceDebris, is now online in the App Store and Mac App Store. Check it out!

OpenGL ES 2.0 Render to UIImage

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
Newer posts

© 2024 thomasguenzel.com

Theme by Anders NorenUp ↑