Sprite::create() and high DPI/retina displays

Hi Cocos2D-x forums! I’m new here. My question is about asset sizes and how they’re handled with high DPI displays (like Retina). I have a texture image with many sprites on it, and I want to create a sprite out of one of them. So, after reading the API docs, I did this:

auto testSprite = Sprite::create(“testTexture.png”, Rect(8, 0, 8, 12));

I wanted an 8x12 pixel sprite out of the sheet, starting at (8, 0). However, it seems to have scaled up that Rect I provided, as much more of the texture than I expected is included – about 2x in each dimension, but not exactly – but I couldn’t find anywhere in the API docs that said how different density displays were handled in conjunction with that particular factory method. So I was hoping someone could clarify that for me.

Obviously this is the C++ API, but I believe it applies to all, and so I’ve filed it accordingly.

Thanks!

Hi @Driverman,

Check the concept of design resolution and content scale factor. Usually we will keep different set of resources for 2x images. In Appdelegate class we will set resource search path based on Device.

Refer : http://www.cocos2d-x.org/wiki/Multi_resolution_support
http://cocos2d-x.org/wiki/Detailed_explanation_of_Cocos2d-x_Multi-resolution_adaptation

Regards,
Gurudath

Thanks @Gurudath! I’ll check that out. It seems to be filed under “Outdated Docs” currently, which is probably why I didn’t find it. Are there other resources in that folder that I can still refer to? Because there’s a few other things I’ve been poking around for.

Hi @Gurudath, that second article explains the theory well enough, which is fine. But it doesn’t explain what Cocos2d-x expects in terms of file naming conventions now, unless I’m missing something. It refers to the past “-hd” convention and also “@2x” but it never canonically states how to accomplish this. If someone could break it down for me, I’d be happy to help create new/current documentation for this.

I see now that this is probably related:

searchPath.push_back(largeResource.directory);, in combination with contentScaleFactor.

But how do I declare searchPath? It’s not specified anywhere in here. This documentation is seriously lacking, no offense intended to anyone on this forum or the project creators. So my new question is: it seems like I have to roll my own logic as to which assets to load. Is that correct?

Hello @Driverman,

Okay.
We usually follow this method. Under resource folder we will create Two different directory with the name (HD & NORMAL). We will keep all the resource under these two folder with the same same.

In Appdelegate class based on Device type(i.e Normal or HD) We will set the resource path.
i.e For HD : searchPath.push_back(“HD”);
For Normal : searchPath.push_back(“NORMAL”);

For retina device images will fetch from HD folder, for Non retina device image will fetch from Normal folder.

Regards,
Gurudath

What are your resolution definitions?

Anyway, I found this article which provided the info I needed about what type searchPaths was and how to provide it:

http://www.cocos2d-x.org/wiki/Mechanism_of_loading_resources

The short of it is:

std::vector<std::string> searchPaths;

// logic that defines your paths here, ie searchPaths.push_back("HD") or whatever

FileUtils::getInstance()->setSearchPaths(searchPaths);

Yes. Correct.

Design resolution sample code you can refer in link:
http://www.cocos2d-x.org/wiki/Multi_resolution_support

Thanks for the help @Gurudath.

I think it’d be ideal if there was one resource that pulled this all together. Right now, there’s three or four wiki articles at least that the information was spread out across. If others agree with that assessment, I could look into putting that together.

@Driverman,

I prefer sonar system tutorial page as well.
http://www.sonarlearning.co.uk/coursepage.php?topic=game&course=cocos2d-x-v3

They have made video tutorial as well.

@Gurudath, I don’t like videos for learning development related stuff. They’re good for stuff like woodworking and mechanical work, where you need to see what’s going on, but with development I prefer clearly written text with concise code examples. Everyone’s different, but I know a lot of people who prefer text as well. That’s why I’d prefer that the wiki be clear and to the point, which I don’t feel it is with regard to content scaling/multiple resolutions, currently.

Okay, so what’s interesting is that, now, with my updated assets, everything works almost perfectly, except that the pixels on the X axis are off by one. That is, I would expect this call:

auto testSprite = Sprite::create("font.png", Rect(8, 0, 8, 12));

to create a Sprite starting with the pixel at coordinate (8, 0) and going down/right to (but not including) the pixel at coordinate (16, 12). However, it actually seems to start after (8, 0) so the upper leftmost pixel in the sprite corresponds to (9, 0), which is wrong. Changing my call to:

auto testSprite = Sprite::create("font.png", Rect(7, 0, 8, 12));

makes it work perfectly. That’s not what I’d expect, because the Y axis is behaving inclusively of the top left pixel, but the X axis is seemingly excluding it somehow with the scaling. It feels like a bug in the content sizing to me.

@Driverman,

Some time we are also facing problem with understanding the concept. we might look for some links.
It will be help full for all of us, if you make brief description about the concept by considering all the cases with example.

Regards,
Gurudath

@Driverman

Am not so sure about this line of code: auto testSprite = Sprite::create(“font.png”, Rect(8, 0, 8, 12));

What is that rect indicates?

As you mentioned, I have a texture image with many sprites on it, and I want to create a sprite out of one of them. Have you created spritesheet for combining many images?

Rect shows the region of that texture I want to be displayed in that Sprite. It’s effectively a spritesheet, yes. I shouldn’t need to use a SpriteSheet explicitly, though – this should work. I read in another thread that SpriteSheet is somewhat outdated anyway.

Okay.

Am not so sure about the difference in one pixel.
It may be because of content scale factor. For Retina device scale factor will be 2 and for normal device scale factor will be 1.

Oh right. I forgot it’s probably not a perfect 2x or 3x multiplier. I’ll check that out.

Works perfectly now. I adjusted my dimensions slightly to be even multiples, and everything is working as intended.