Large texture/sprites, long loading times

Hi, I was wondering what techniques I could employ to reduce to the load time of my scene with several large 2048x2048 sprites/textures that make up the background. Currently it takes around 1 second to the load the scene on the device (iphone 4s).

Do I just have to accept it or is there ways to optimize this, couple of ideas I had off the top of my head:

  • Reduce memory size of the image by changing color mode/quality (each is about 1mb currently).
  • Use a texture atlas
  • Load images on the background thread
  • Accept it and add a loading screen?

Is there any built in ways in Cocos2D-x to reduce this?

Thanks.

There’s no magic available afaik, but maybe others have ideas. Since loading is more about extracting data from your image files the only real solution I can think of is to either resize the image (scale 2x w/1024x1024) or convert as many PNG as possible to one of the native GPU formats like PVR (for iOS devices).

Do you have a main menu and can you load all textures at once? You will probably still want a loading scene, but you could limit the time spent there if you have other things the user must go through to start playing, while not feeling like they’re waiting.

Do you really need all large textures loaded immediately? I would put everything necessary for the immediate view of a given scene (menu, level, etc) and load that first, then present the level and load the rest asynchronously and fade them in? It seems like if you need more speed you may need to rethink your background artwork design?

You could also load a low-res version that has all backgrounds in a single 2048x2048 or smaller texture and show those while you load in the higher-res. The web has gone through many of these ideas. Kinda depends on your design I suppose.

Yea there’s definitely a lot to consider, I like your idea of loading only the initial part of the level first and then loading the other parts asynchronously, depending on player position or whatever. It really depends how much the asynchronous loading affects performance.

I’m still interesting in learning more about using the background thread as I think that may be a viable option.

If anyone else has some input on these ideas that would be great.

I would never recommend asynchronous loading during the actual game play. Have tried that in many ways but it always gets the worse.
Plus you can use texture sprite sheet packing tools like “Texture Packer” etc.
You also should take a look where you can use 8bit, 24bit, 32bit images. this matters the most in your scenario

@bilalahmed_cs makes a good point, basically anything to reduce the image file size should reduce the file loading times.

@UKDeveloper99 also, I should have asked first what is wrong with adding a loading screen? This loading screen would be short with higher end devices. Many games have loading screens. You can load a simple scene, setup and start a loading screen, then use the async loading methods with a callback which should get run on the main thread and can be defined to replace the scene with the game scene. There should be a few discussion topics on loading screens.

The two options I would recommend when you can’t avoid long loading periods are

  • Async loading during a loading screen or animation.
  • Low resolution replaced by async high resolution during gameplay. (first few seconds of game may stutter, if you’re not careful, but al least you’ll have the game on screen)

Loading screens don’t need to be intrusive or flow breaking, for example Clash of Clans uses a cloud animation to cover the screen as it unloads/loads assets, hiding the fact that the app is loading and giving the user something pretty to look at in the meantime. You’d be surprised how a good loading screen can make the user feel like they’re not actually waiting at all.

Other things to do to decrease loading time:

  • use compressed textures that can be decoded by the GPU, this avoids the overhead of uncompressing at load time. For example PVR on iOS and ETC on Android (note: ETC1 does not contain an alpha channel, later versions do but are not as widely supported).
  • reduce the depth of the texture, depending on the content (as @bilalahmed_cs mentioned) low colour depth such as 8bit might suffice. You can do this both offline in your image files and at load time when you’re generating GL textures. Reducing overheads of file IO/decompression and texture binding respectively.
3 Likes