I am about to convert my iPhone OpenGL ES based app into a universal (iPhone + iPad) app, using iOS 4.2. What advice would you give me? Are there any notable pitfalls in doing so?
Make sure you get the bounds rectangle for the screen dimensions rather than hardcoding the view size or anything based on window coordinates.
[[UIScreen mainScreen] bounds];
Recognize that if your application wasn't fill-limited (i.e. the hardware can only fetch so many texels and display so many fragments per second) on the iPhone 3GS or earlier (640x480) screen. That it very well may be fill limited on iPad or iPhone 4 (1024x768 or 960x640) screen size respectively.
Related
I m developing a universal app.I want to know will the screen resolutions (320 * 480) for iphone and (768 *1024 )in iPad will work for all iphone's (iPhone 3g,iPhone4 etc) and all iPads.Because based on these screen resolutions I m setting textField's, UILabel's width in both iPhone and iPad.Will these work for retinas and nonretinas ?
Retina iPhones and iPads use the same coordinate system as non-Retina devices. Presently all iPads have a logical coordinate space of 768x1024, and all iPhones except the iPhone 5 have a logical coordinate space of 320x480. Your code should work fine on both Retina and non-Retina devices.
On an iPhone 5, your app will be shown with black bars at the top of the screen unless you tell iOS that you want to use the full screen by including a Default.png for the extended screen resolution.
You can check the screen resolution with [[UIScreen mainScreen] bounds]. This value will be the same on Retina and non-Retina devices. You can detect a Retina device by checking the value of [[UIScreen mainScreen] scale]; the value here is the number of physical pixels per unit of logical coordinate space (1.0 for non-Retina, 2.0 for Retina).
UIKit and CoreGraphics work with points rather than pixels.
Both the retina and non-retina devices have the same number of points, but a different amount of pixels. This means that the same point values can mean a different pixel value on different devices.
To answer your question, yes the same layout UILabel widths will display the same on retina and non retina devices.
From the Apple Developer Documentation :
In iOS, all coordinate values and distances are specified using floating-point values in units referred to as points. The measurable size of a point varies from device to device and is largely irrelevant. The main thing to understand about points is that they provide a fixed frame of reference for drawing.
Have a look at the Points vs. Pixels section in the View Programming Guide:
http://developer.apple.com/library/ios/documentation/windowsviews/conceptual/viewpg_iphoneos/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW15
You can always use the capabilities to get the OS and do what you need to your interface.
var pattern:RegExp = /iphone5/i;
var str:String = Capabilities.os;
if (str.search(pattern)==0)
{
trace('iPhone5 Detected. Alter height.');
}else{
trace('No need to change dimensions if developing at 960x640');
}
I have been looking everywhere for this but with no luck.
How do I prepare my cocos2d based game for bigger 4 inch display of the iPhone 5?
My app is working but i want to enhance it for the bigger 4 inch display.
Cocos2d uses its own suffixes for retina display images. For retina display of the iPhone 4 and 4S it is image-hd.png. Is there a suffix for iPhone 5? How do I accomplish this?
Cheers.
There is no extra file suffix for iPhone 5, after all it's only 176 pixels (88 points) wider. It's treated like a regular Retina phone, hence cocos2d will load the -hd files.
The rest is just about positioning your images depending on the device. The simplest way is to just treat the 44 points on either side as a "dead zone" where no user input can occur and where there's no guarantee the user can see game objects.
Update:
cocos2d 2.1 added the -widehd suffix. It was said that 2.1 final release will have the suffix renamed to -iphone5hd.
In light of future screen sizes I sould personally set and use a -568hd suffix because other phones beside iPhone 5 may have the same resolution. Naming the suffix after a specific iPhone model is a tad short-sighted to say the least.
Add it to AppDelegate:
[CCFileUtils setiPadRetinaDisplaySuffix:#"your suffix"];
[CCFileUtils setiPadSuffix:#"your suffix"];
[CCFileUtils setiPhoneFourInchDisplaySuffix:#"your suffix"];
[CCFileUtils setiPhoneRetinaDisplaySuffix:#"your suffix"];
Not sure why everyone is saying there isn't.
The suffix is -568h for iPhone5/iPod Touch 5th (so the 4 inch retina displays).
The total list:
-hd (iPhone 4/4S, iPod Touch 4th)
-568h (iPhone 5, iPod Touch 5th)
-ipad (iPad 1st/2nd)
-ipadhd (iPad 3rd/4th)
Add this to AppDelegate with your chosen suffix:
if((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && ([[UIScreen mainScreen] bounds].size.height == 568)) {
[sharedFileUtils setiPhoneRetinaDisplaySuffix: #"-your suffix"];
}
It took me awhile to figure this out, since I'm new to cocos2d. So I thought a recap might be helpful for those like me. In cocos2d 2.1, all you have to do is creating graphics for the target screen sizes and follow cocos suffix naming convention. Note that cocos's suffix convention is not the same as iOS's.
In my case, I have a background image that occupies the full screen. So, I made...
background.png at 480x320 for iPhone
background-hd.png at 960x640 for iPhone retina (3.5")
background-iphone5hd.png for iPhone5 retina (4")
And use the following code to load the image into CCSprite. Cocos will figure out which image to use for you.
CCSprite *background = [CCSprite spriteWithFile:#"background.png"];
background.position = ccp(background.textureRect.size.width/2,
background.textureRect.size.height/2);
[self addChild:background];
For an element like a character that doesn't occupy the full screen, cocos2d will pickup character-hd.png automatically in iPhone5. There is no need to create character-iphone5hd.png version.
You can read more about this in version 2.1 release note at
https://github.com/cocos2d/cocos2d-iphone/wiki/cocos2d-v2.1-release-notes
This is how i did it for cocos2d v2.1-beta4.
In CCFileUtils.h i added:
- (void)setIphone5HDSuffix:(NSString *)suffix;
In CCFileUtils.m:
- (void)setIphone5HDSuffix:(NSString *)suffix
{
[_suffixesDict setObject:suffix forKey:kCCFileUtilsiPhone5HD];
}
In AppDelegate.m:
[sharedFileUtils setIphone5HDSuffix:#"your_suffix"];
And that's enough!
Did you follow the following post, adding the default image for it, named Default-568h#2x.png with a resolution of 1136x640?
How to develop or migrate apps for iPhone 5 screen resolution?
If it does not work, I found this post on cocos2d forum, containing a lot of infos:
iPhone 5 1136 x 640 screen resolution: http://www.cocos2d-iphone.org/forum/topic/39491
Now cocos2d support iPhone wide screen also.
-wide.png for iphone 5
-widehd.png for iPhone 5 HD
I was just playing around with suffixes in Cocos2D 2.1-rc1 and was able to get it to automatically load a iPhone5 file with the "-iphone5hd" suffix, not changing anything in AppDelegate in the sharedFileUtil section of code. Hope that helps, also.
I have a camera taken picture, and I'd like to resize it to the exact size of a view. But... bounds.size on an iPhone 4 does not take account of the retina display.
I'd like a code that can give me the real pixel size of the view, so it can work on any device without having to test / to know the kind of hardware it runs on.
Do you know how I may do this ?
Every view has the contentScaleFactor property, which is typically 1.0 (3G, 3GS, iPad) or 2.0 (retina screens). Another approach is to use [[UIScreen mainScreen] scale], which has the same values.
note to remain compatible with iOS versions prior to 4.0, you have to check if the method is available using respondsToSelector:#selector(contentScaleFactor) before getting the value.
I want to use different images in my iPhone application, depending on whether the current device is an iPhone 3G, iPhone 4, or iPad. I've tried getting the screen resolution (size) of the device, but it always returns 320 X 480 for the different iPhones.
How do I determine which type of device I'm running on so that I can provide the correct images?
I do not want to get the iPhone OS version.
There's most likely no need to do what you're attempting to do, as iOS has built in support for loading images at the appropriate size for the iPhone (retina and pre-retina resolutions) and iPad.
Read the Resource Programming Guide (specifically the "Specifying High-Resolution Images in iOS" and "iOS Supports Device-Specific Resources" section) and the iOS Application Programming Guide for more information.
Incidentally, both the pre and post retina iPhone/Pods have a point resolution of 320 X 480. Apple distinguishes between point sizes (resolution independent) and pixel size to help things along the way.
If you want this info for the purposes of selecting the proper graphics for your resolution, then middaparka's answer is what you're looking for.
However, if you happen to need device model or resolution info for a different purpose, then UIDevice and UIScreen may be what you want.
NSString *myDeviceModel = [[UIDevice currentDevice] model];
CGRect myScreenSize = [[UIScreen mainScreen] bounds].size;
i think below one solve my problem
https://github.com/erica/uidevice-extension/blob/master/UIDevice-Hardware.m
Thanks
I've had experience writing a cocoa touch app as a universal app (for ipad, iphone) and it wasn't too hard. I only needed to use different .xib for each device but atleast it was the same binary.
Is it possible to have a universal opengl es app as well? Is it difficult given I have to have the resolution different for each devices (iphone 3gs, iphone 4, ipad)? So most probably my code would be different for each device???
While difficulty is a subjective measure, I would argue that it is a simpler process to develop an OpenGL-ES-centric application for the various devices than one based on more standard user interface elements. Where an iPad version of a standard iPhone application may require a completely different interface layout, if you are doing fullscreen OpenGL ES drawing, you just simply need to have the rendering layer scale to the appropriate screen size.
For example, take a look at the code to my Molecules application (it's available under a BSD license). It is a universal iPhone / iPad application and shares a lot of code between the two interfaces. In fact, almost none of the OpenGL ES portion changes based on the platform.
When it comes to something like the Retina displays, you just need to add one little bit of code in your CAEAGLLayer-hosting view's initialization to account for the new scale factor:
if ([self respondsToSelector:#selector(setContentScaleFactor:)])
{
self.contentScaleFactor = [[UIScreen mainScreen] scale];
}
Nothing else needs to change, and your OpenGL ES content will now render at the higher resolution.
Probably the biggest issue you will encounter is that by going to the higher-resolution displays you may find yourself being fill rate limited where you weren't before on the older iPhones. If you see the Renderer Utilization getting near 100% in the OpenGL ES instrument, that's what is happening. For the Retina displays, you may then want to not render at the full 2X scale factor, but something a little lower.
I can't speak to your particulars, but I have a universal app and it uses OpenGL-ES. For my purposes, glViewport() call takes care of things.