contentScaleFactor not working correctly


#21

The link clearly says - “All of your game’s coordinates are based on design resolution, no matter what the size of your device screen. If the UI layout of your game is the same on all resolutions, you only need a single set of coordinates.”

I think, the yours said “whole screen” means virtual screen. DesignResolution is the resolution you make your design upon. It’s gonna scale up or down and get cropped(if necesasary) based on device screen. Isn’t it?


#22

Design resolution will be the same in any case.
But visibleSize could be bigger or smaller.


#23

@ivcoder As you mentioned the link, I would like to point my Test Case 4 and point out whats happening with me.
Just look at AppDelegate.cpp and modify this

to

float scale = MIN(director->getFrameSize().height/designResolutionSize.height, director->getFrameSize().width/designResolutionSize.width);

In the link, Chart 1:
Resource Size = 960 * 640 ;
Design Resolution Size = 480 * 320 ;
Target Device Screen Size = 800 * 480
RH/DH = RW/DW=2.0f;
Policy = NoBorder

When, resource is getting mapped from Design Resolution to Target device, then
Scale Factor = 800 / 480 = 1.666667 (Since the width is same in that picture)

So, Resource Height = 320 * 1.666667 = 533 (Since device height is 480, that’s why it is shown as cropped or grayed) and Width = 800

Now, look at my case.

Resource Size = 1280 * 720 ;
Design Resolution Size = 1280 * 720 ;
Target Device Screen Size = 1920 * 1080
RH/DH = RW/DW=1.0f;
Policy = NoBorder

When, resource is getting mapped from Design Resolution to Target device, then
Scale Factor = 1920 / 1280 = 1.5 or Scale Factor = 1080 / 720 = 1.5

Resource Height = 720 * 1.5 = 1080 and Height = 1280 * 1.5 = 1920

But, the image is not fitting the screen. There is nothing to get cropped. Then why it is happening?


#24

Will there be cropping? No. Because device screen ratio is equal to design resolution ratio.
Will image fit to screen? No. Because screen size is 1280x720 and image size is 1920 x 1280.


#25

I’ll try and explain how this all works (from what I can tell):

  • glview->setDesignResolutionSize() sets the resolution of the screen for your app. If you have a design resolution of 1280x720, a node placed at (640, 360) will be at the center of the screen, and a node that has a size of 640x360 will take up exactly one quarter of the screen. The actual resolution of your device is ignored. The purpose of the design resolution is so that you can use the same co-ordinates and node sizes across all screen sizes (with the possible exception of different aspect ratios.)

  • director->setContentScaleFactor() sets how much nodes are scaled by. If you have a scale factor of 2, a sprite of size 320x200 will be scaled to 640x400. The purpose of the content scale factor is so that you can make sure nodes appear the same size on each screen, i.e. that they take up the same amount of screen space.

  • To make sure assets are scaled properly, you need to set the content scale factor to the value that makes the resolution the assets are designed for to the same as the design resolution when the two are multiplied. For example, if your assets are designed to fit a 640x360 screen and your design resolution is 1280x720, you need a content scale factor of 2, because 640 x 2 = 1280 and 360 x 2 = 720.


#26

If you want your image to fit the screen, then you need something like:
director->setContentScaleFactor(assetSize.width / designResolutionSize.width);.

If you need your image size to match your screen resolution, then you need something like:

director->setDesignResolutionSize(frameSize.width, frameSize.height, ResolutionPolicy::NO_BORDER);
director->setContentScaleFactor(assetSize.width / frameSize.width);

Or use the first option, but set designResolutionSize to the same as frameSize. Obviously you will want to add the MIN() back in.

The design resolution is whatever resolution you want the screen to be. The content scale factor is how much to scale your assets. If you want a sprite to fit the screen, then the content scale factor needs to be the value that will equal the design resolution when multiplied with the dimensions of the sprite.


#27
glview->setDesignResolutionSize(frameSize.width, frameSize.height, ResolutionPolicy::NO_BORDER);
designResolutionSize.height = frameSize.height;
designResolutionSize.width = frameSize.width;

float scale = MIN(frameSize.height/designResolutionSize.height, frameSize.width/designResolutionSize.width);
director->setContentScaleFactor(1/scale);

and calling scaling function for scaling from my Utils.cpp . Tested and working till now. :slight_smile:


#28

scale will always be 1, because you’re setting designResolutionSize to frameSize.


#29

Yes. I know, But please look at my previous Test Cases and see how am I using my Utils.cpp.


#30

Yes, but then the second two lines of code are pointless. If the content scale factor is 1 by default, then you don’t need them. If it isn’t 1, then you just need director->setContentScaleFactor(1);


#31

Yes, I already got that. And commented out.


#32

@slackmoehrle could you please confirm it first when you are writing the doc? It may be a bug or may be a wrong usage.


#33

If you just delete this code you will get the same effect.


#34

@zhangxm yes, @grimfate and @ivcoder posted some good thoughts here. I will incorporate them.

@aksh1203 I will set aside time tomorrow to test your test cases and incorporate feedback from @grimfate and @ivcoder to see what is going on. We will then add a chapter to out docs to better explain this for all users.


#35

If your graphics resources are created for 1280x720 resolution, then your Utils.cpp code equival to

director->setContentScaleFactor(MAX(glview->getFrameSize().width/1280.0f, glview->getFrameSize().height/720.0f));

Or you can use

glview->setDesignResolutionSize(1280.0f, 720.0f, ResolutionPolicy::NO_BORDER);

But in this case your coordinate system will always be equal (1280, 720), but part of the design resolution may not be visible.

Simply, is not it?

But I would recommend that you use setDesignResolutionSize(). In this case, you can use relative and absolute coordinates.
The cocos multi-resolution concept is pretty simple and beautiful when you will understand this.

Especially since @slackmoehrle promises to explain it better. :slight_smile:

@zhangxm I can confirm that this is wrong usage. If you can believe me, of course. :smile:


#36

@Priority10 thanks, i believe you, of course :slight_smile:


#37

Yes this was wrong usage.

I used the above mentioned code with my Utils.cpp. And it worked.


#38

Which block of code? You mean the whole setContentScaleFactor block of original AppDelegate.cpp or my last 2 lines which I commented out?


#39

No need to test my Test Cases now. It was wrong usage. I think we both were on same step i.e did not get the proper idea of multi res with designResiolution. Now it’s clear for me. :slight_smile:


#40

No actually.

This is not true. I was testing with this, but it did not help me since this code treated my screen size as 1280 * 720 on both devices.

But in Utils.cpp, I am just using it for my scaling purpose. It is not setting my screen size to 1280 * 720 since I used

Read this, (Small calculation related reply with only one snap after Test Case 4)

This actually helped me a lot to understand.