understanding retina display

I am trying to make a universal app for iphone and ipad, and on the iphone have retina support.

Using 0062 i’ve made the changes suggested by scott here

I have an iPod touch with retina to test on. It is now using the right icon and default.png files

the width & height I am getting from ofGetWidth/Height is 320x480. This has been mentioned on the forum before

On Apple Dev, it says if I load chris.png, it should also load chris@2x.png

Does this work with ofImage.load ?

I’ve got my OS target set at 3.2 as want to support older devices ideally.

Any advice would be great, thanks!

Try it and see. I don’t rely on it. I use a settings file segmented by device. On setup, I detect which device I’m using and load in the appropriate section of the settings file. These settings also contain the correct filenames to load images in. This method saves a ton of device specific if/elses peppered through your code.

Did you have any luck with images, Chris? I’m trying to resize the images if there’s retina support and it doesn’t appear to be rendering the pixels correctly. Also, has there been talk about updating ofTrueTypeFont for retina as well?

Been a while since I looked at this to explain exactly why, but no, oF does not make use of the “2x” automatic file selection. You could write your own code to detect whether you’re on a Retina display and add the 2x yourself before calling your ofImage loading of course.

Has any OF developer on the forum made an app that supports retina?

Is the resolution of the retina screen and touch area is still 480x320, is the retina resolution 960x640 ever used for anything?

I had two images…

test.png = 480x320
test-2.png = 960x640

when i load and draw(0,0) on an old iphone test.png draws the right size as you expect.

But when you draw test-2.png at its default size on retina, the file is 960 wide, but the screen res is only 480 wide. So you only see a quarter of the image.

So if you draw test-2.png like img.draw(0,0,480,320) then it fits in and does look crisper than drawing the previous image. Weird.

Why would you need 2 sets of images then? Couldn’t you always draw the higher resolution image at 480x320 on both devices? Or would it look squashed on the older iphone?


I recently made my app FunkyBooth with retina support using OF.http://itunes.apple.com/us/app/funkybooth/id424731057#

I had to hack into the guts of OF quite a bit. With the following method, your touch events and screen coordinates are all reporting the full size(e.g. 480x320 and 960x640). I created code with normalized coordinates from 0.0 to 1.0, and drew everything appropriately. For instance, draw(0.5, 0.5) would scale to 240, 160 on a regular display and 480, 320 on the retina.

Also, I use two sets of images and a draw function that was scale aware, loading the correct image. Using string values, I would just load the proper path into each, depending on the resolution. I tried to always use the high res version and just draw them smaller, but older phones don’t like to handle that many pixels.

First in EAGLView.mm:

			if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {  
				if ([[UIScreen mainScreen] scale] > 1)  
					[self setContentScaleFactor:[[UIScreen mainScreen] scale]];  
					touchScaleFactor=[[UIScreen mainScreen] scale];  

Then in ofxiPhoneAppDelegate.mm:

int w = 320, h = 480;  
	float ver = [[[UIDevice currentDevice] systemVersion] floatValue];  
	// Can't detect screen res in pre 3.2 devices, but they are all 320x480 anyway.  
	if (ver >= 3.2) {  
		UIScreen* mainscr = [UIScreen mainScreen];  
		w = mainscr.currentMode.size.width;  
		h = mainscr.currentMode.size.height;  
	if (w == 640){  
		NSLog(@"Retina Detected.");  

And finally in ofAppiPhoneWindow.mm:

// return cached size, read if nessecary  
ofPoint	ofAppiPhoneWindow::getWindowSize() {  
	if(windowSize.x == NOT_INITIALIZED) {  
		CGSize s = [[[UIApplication sharedApplication] keyWindow] bounds].size;  
		windowSize.set(s.width, s.height, 0);  
			if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])  
				windowSize*=[[UIScreen mainScreen] scale];  
	return windowSize;  
// return cached size, read if nessecary  
ofPoint	ofAppiPhoneWindow::getScreenSize() {  
	if(screenSize.x == NOT_INITIALIZED) {  
		CGSize s = [[UIScreen mainScreen] bounds].size;  
		screenSize.set(s.width, s.height, 0);  
	return screenSize;  
int ofAppiPhoneWindow::getWidth(){  
		return (int)getWindowSize().x;  
	return (int)getWindowSize().y;  
int ofAppiPhoneWindow::getHeight(){  
		return (int)getWindowSize().y;  
	return (int)getWindowSize().x;  

I think that’s the majority of the changes, but let me know if I missed anything. One of these days I really have to learn how to use git. Of course there is probably a better way to do this, but it worked for me.



You could do this and it will look fine, but you’re making the older devices do extra work for no reason. How much of an issue this is depends on your application; if you’re running into framerate issues on the older devices, this is the first change to make.

As oF007 has a lot of changes in this area and my own codebase has changed considerably from 0062, I think I’m going to hold of on giving any specific details until 007 drops.

The advice above sounds great. I’m looking forward to the changes in 007.

I chose check for retina display on load to load the right image, but then draw retina images at 320 x 480 res. If you know what the height/width of the image should be at 320 x 480 you don’t need to even do a check to see if it’s on a retina display during the draw function. Just load the retina image on application start and draw it at half res (same res as the 320 x 480 version). Seems to work well and doesn’t require extra work of doing if/else statements during update/draw.