Setting up a File Type for your Mac App

As I often have problems setting up a custom filetype for my Document-Based Applications I decided to write a short tutorial on how to do it (actually just one image). You just need to enter most of the information twice, once for the Document Type and once for the Exported UTI.
Look at those two lists for what types you have to choose:
List of Uniform Type Identifiers
Wikipedia Article about MIME (including common types)

filetypetut

Read More

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

Read More

New Domain!

I was able to get myself a new domain (and also a new server). Together with the new domain i’ve decided to only write in english from now on as i have received many emails about stuff that has been clearly stated on the site in german. I will add more content to this site over the next days/weeks.

Read More