Just my two cents but I would still recommend using Power of Two. I have at least one older Android device that I test against and it requires POT. In addition, I believe there are performance gains in sticking to POT.
I’m not terribly knowledgeable on the subject so if you don’t get a response here I would suggest looking outside this forum as the issue isn’t cocos2d-x specific but rather an OpenGL thing. You can find sites that list the capabilities of most mobile devices, so you then have to decide if you want to restrict yourself for the sake of supporting older/obscure phones or enjoy the freedom of making your textures any dimension you want and focus on modern/mainstream phones.
really? could you post the URL to that? If we are recommending it, I guess it is because we are checking if it is supported in runtime. If it is not, then we resize the texture.
besides that, almost all features are supported in both sizes, except Texture2D::setTextureParamters() which it only accepts POT textures with certain parameters.
Instead of recommending “use NPOT textures”, I would recommend “use the smallest possible size… cocos2d will resize if needed”.
Since our games have a lot of animations it is very important to know if it is safe to use NPOT, we know we can always use POT textures and split the textures to avoid wasting too much empty space but if we do that we are increasing draw calls, right? And of course splitting textures means more work.
It would be great to know more about this and have more developers to discuss
The yes is:
More textures means more texture switches, which means potentially more draw calls, which means a bit slower (depending on how many switches it has to do). You can’t batch sprites when they use different texture ids.
The no part is:
You don’t have to split it in more files. Every NPOT texture can be converted to a POT texture… it will contain more empty space… it might consume more memory (that depends on the GPU driver), but you don’t have to split it in more files.
The maximum texture size is always a POT number. eg: 2048, or 4096, or…
Anyway, I think you are safe with NPOT texture. The only exception is this:
/* from CCTexture2D.h */
/** Sets the min filter, mag filter, wrap s and wrap t texture parameters.
If the texture size is NPOT (non power of 2), then in can only use GL_CLAMP_TO_EDGE in GL_TEXTURE_WRAP_{S,T}.
@warning Calling this method could allocate additional texture memory.
@since v0.8
* @code
* When this function bound into js or lua,the input parameter will be changed
* In js: var setBlendFunc(var arg1, var arg2, var arg3, var arg4)
* In lua: local setBlendFunc(local arg1, local arg2, local arg3, local arg4)
* @endcode
*/
void setTexParameters(const TexParams& texParams);
Yeah, I know. But imagine this situation. We have a large enemy with tons of animations that after optimizing the assets that enemy sprites require a texture a bit larger than 1024x1024… Just a bit! If we want that texture in POT size that means we should have a single texture of 1024x2048 probably wasting a lot of extra MB of empty space. What we can do is split the extra sprites in a smaller texture and have 2 textures for that enemy like this. 1024x1024 and another one of 256x256 with just a little empty space.
In a game like Kingdom Rush that have tons of characters? Towers, animations etc etc memory is very important for us and we try to waste the less we can.
Of course if we put toons of enemies together in the same textures the empty spaces are reduced considerable but in our new game we need to have all the towers in just one texture per tower and we have problems with wasting spaces using POT and we don’t want to split them.
Thanks a lot for your answer.
I have one more question about this: what kind of problems can we experiment if we use NPOT these days? I know that in the old days some devices can’t handle NPOT textures, is this a problem today?
Here at the office we have all iOS devices (iPhone 4 to 6s, and all iPads from 1 to the latest) and we don’t have problems there. We also have 30 or more android devices and also no problems but it’s a misery if we will have problems there on some devices we don’t have.
I guess most modern / semi-modern devices support NPOT textures.
But the only problem that I can think of is if you want to use setTextureParameter() with certain parameters (see my previous answer).
Also, we check in runtime if the device supports NPOT. If it doesn’t we convert the texture to POT in runtime.