Android Retina Mode?

Android Retina Mode?
0.0 0


May I know if cocos2dx supports retina mode? By reading the code, it seems canSetContentScaleFactor() returns false for android.

Also, does the Retina mode only work when resolution is 960 x 640? How about Android phones with 800 x 480? It doesn’t look good on 800 x 480 Android phones by using 480 x 320 images.


Supporting multiple resolutions with Cocos2d-x and Marmalade

Retina mode & CCDirector::enableRetinaDisplay(bool) is only available for iOS.
On android, we have the auto-scale feature.
Please read this wiki page [[How does cocos2d-x support multi-resolution]]. on android is “scale display mode”, you can enable

// line23 of YourGame/android/jni/helloworld/main.cpp
view->create(480, 320);

For example, your resource is made in 480x320 pixels, and you enable this line view~~>create. When the game runs on 800x480 WVGA devices, it will rendered as 720x480 pixels, and leave 40 pixels at left & right.
In the other hand, if your resource is made in 800x480 pixels, and enable view~~>create(800, 480). It will rendered as 480x288 on HVGA (480x320) devices, and leave 16 pixels on top & bottom


Thanks for your prompt reply! It works by setting the view to 800x480. This is a great engine for people want to target both Android and iOS.

So now my code should based on the coordinate 800x480 instead of the default 480x320. Will the code still work on the iOS side (with or without the retina mode enabled)? I guess I need to set the view to 800x480 as well somewhere? Or I need to map my positions from 800x480 to 480x320 coordinate?



The auto-scale feature is only for android/win32/wophone, it cannot be used on iOS devices. You cannot set the view to 800x480 on iOS.
In your situation, you had to make resources in 480x320 for iphone3 + iphone4, 800*600 for ipad, and adjust the coordinates in the code.
The laziest way is to make resources in 480x320, it can be used in both iphone3/iphone4/android HVGA/android WVGA/android pads and more. The 2nd laziest resolution is 960*640, it can be work on iphone4 & all android devcies.


One more question. Let’s say I set the view to 800x480 (use autoscale). How it will render then on iPhone 3/4? Will the iPhone version simply ignore my custom set view size?
If not, then I’m stuck with 480x320 size even on Android phones and I have to manually scale/trick with the sprites if I want higher resolution textures for Android devices with WVGA and higher screen resolutions.
This is a pretty poor approach as nowadays all Android phone has at least a resolution of 800x480.
The other option is to always use the actual resolution but then again, I have to play with the sprite scales and asset resolutions for every different display time.
Finally one more question: if we enable the retina display for iPhone 4 does the coordinate system is still 480x320?

  1. iphone3/4 can not accept WVGA solution, it will leed to unknown result. The laziest way is to design 480x320 or iphone3, use the ios auto-scale on iphone4, and use engine auto-scale on android WVGA devices. If you want a perfect experience, artworks and multi coordinate values for different resolutions are required. I have no idea to deal with non-uniform scale
  2. You’re right, after enable retina display, the coordinate system is still 480x320 in cocos2d-x. It’s inherit from cocos2d-iphone. 480x320 is in the unit of “point”, while you can use xxxxInPixel to use 960x480 coordinate system. For example, in CCSprite.h
    virtual void setPosition(CCPoint pos); // use 480x320 even enableRetinaDisplay(true)
    virtual void setPositionInPixels(CCPoint pos); // 960x480 if retina enabled, 480x320 if retina disabled.


The problem with this approach is that with Android you cannot create high resolution resources using auto scale unless you manually scale the sprites.
As an example, AndEngine solves the problem in the following way:

  • you define the virtual screen resolution (let it be 960x640 in this case) and uses letter boxing (as auto scale does it currently)
  • when you create a sprite, its size will be determined by the virtual screen resolution, so a 960x640 sized sprite will always cover the whole screen, no matter if the actual resolution is HVGA, WVGA, WXGA or whatever
    This way you don’t have to deal with the actual screen resolution when defining your coordinate system and sprite sizes.
    As I understand, this is how cocos2d-x works if you use autoscale, however, the coordinate system is fixed to 480x320 in case of autoscale, you cannot define your own coordinate system and let the engine map it to the actual resolution, cocos2d-x can do this only for the fixed resolution 480x320.
    I don’t know why it is so as you could easily solve the problem with custom virtual resolution as you only need to replace the OpenGL viewport and OpenGL will take care of the rest.
    What do you think about this approach?


Yep, virtual resolution is a good design for auto-scale. I’m not sure if the game is scale to different ratio on width & height, can players accept this visual result?

In the other hand, some large companies who is quality-sensitive would like to load different images for different resolutions, and passby the auto-scale feature. Just like the `2x design in iphone retina, drawable-hdpi/ldpi/mdpi desgin in android. The trouble is how to fix these 2 mechanisms, auto-scale and load different resources?

Ideally, cocos2d-x must offer both of them. For example, a game is facing these resolutions:

  • 480x320 (HVGA)
  • 800x480 (WVGA)
  • 960*480 (Retina)
  • 1280*752 (android 3.0 tablet)
    The developer may offer 800x480 & 960x480 resources, so the engine must load resources from by a subfix (`2x, -hd) or different folders, and auto-scale the “best-fit” resolution to 480x320 & 1280x725. Besides the resources, the coordinate values would be complex.

I have no idea how to design this…


Well, actually I think you’ve already figured out what would be the theoretically best approach: virtual resolution + multiple resource resolutions :slight_smile:


:frowning: mixing them in one design is very hard, especially the coordinates.


I don’t know that well the source code of cocos2d-x, however it doesn’t seem so hard.
The coordinate system can be easily switched by simply replacing the OpenGL viewport.
On the other hand, the multiple resource resolution issue can be solved by the application by explicitly selecting a resource directory/suffix in the initialization phase.
What do you think?


Choose either of them and forbidden another is easy. The hard point is that, developers wish to use multi-resource selections on some resolutions, and use auto-scale feature on other resolutions.
We’re trying a design of 9 anchor points on the screen to deal with multi-resolution problem. If it works, we will write a document to guide this approach.


What happens if I manually set the content scale factor on Android?
I’ve tested it and seems to work, however, I suppose I should also change the implementation of the canSetContentScaleFactor method to return true also on Android.

If I can set the content scale factor also on Android, I only need to select the appropriate resources for different resolutions.


Come on, go ahead, the benefit of using an open source project is you can modify it to fit your unique requirements, why not?



can you tell us, what’s your current plan for this?

It would be very useful, if we could enable the HD-set for android, instead of autoscaling.

Maybe, you could add some additional configuration options, so game developers would have more choices to fit their requirements:

sharedDirector->enableImageAutoScale(false);  // disable the android's auto-scaling feature, if our game doesn't need it
sharedDirector->enableHdImageset(true);       // tell cocos, there is a HD image set and can be used.

It would also be useful, if we could disable the compatibility mode, which adds black bars on the screen border of android devices. Our game doesn’t require a specific screen resolution or aspect ratio, so what are our options, to get the black bars removed?


Random thought, the best approach perhaps is to remove the “RetinaMode” from cocos2d-x, and support two mechanisms:
# auto-scale mode,
# auto-load resource from different DPI folders. This approach would include RetinaMode internal, just change “depend on -hd, `2x subfix" to “depend on different folders”.

`Christian Fischer,
If you want to fix the black bars quickly, please refer to this blog, it was written in Chinese but you can read by the help of google translate. This blog describes an approach to use auto-scale feature an deal with different resolutions (render in full screen), which is used in the game”Fishing Joy":, and the article offers a zip ball download of sample code which you can learn from.


Sounds a bit like the android-strategy with it’s ldpi, mdpi, hdpi, … -resources. I think this would be a better approach than just make a difference between HD and non-HD. Android has a few more devices than iOS :slight_smile:
If we could control, which resource-folder will be used, this could also be useful for other situations to load different resources for some devices or language-specific resources.

Thx for the hint, I will take a look on this sources during next week at work.


Walzer Wang wrote:

The auto-scale feature is only for android/win32/wophone, it cannot be used on iOS devices. You cannot set the view to 800x480 on iOS.
In your situation, you had to make resources in 480x320 for iphone3 + iphone4, 800*600 for ipad, and adjust the coordinates in the code.
The laziest way is to make resources in 480x320, it can be used in both iphone3/iphone4/android HVGA/android WVGA/android pads and more. The 2nd laziest resolution is 960*640, it can be work on iphone4 & all android devcies.

is it possible to create resources in 480*320 and 960*640 (with -hd) and use the 960*640 resources on android devices?


@Leo Lou
This requirement is not supported. The default approach is create resources in 480*320 & 960*640(-hd), and use 480*320 (without -hd) on android devices.
You had to hack the code in engine internal to implement it by yourself.



So I started testing on an android 3.0 device (well, the emulator) and I noticed a problem with this feature. The auto-scaling appears to work correctly, except that the image is not cropped to the correct aspect ratio - instead of black bars at the edge of the screen as on a 2.x device, the GL view continues to render there. As on my game things slide in and out of the edge of the screen, this doesn’t look too pretty.

Hopefully I’ve explained this OK. Let me know if you want some reproduction info.