关于 Unsupported PVR Pixel Format:0x12 的解决方案,没耐性就直接看文末的两幅截图吧~^ ^.
The texture size must be a power of two (1, 2, 4, 8,16, 32, 64,128, 256 and so on up to 2048 or 4096 depending a little on the hardware),
though you don't need to have a square texture, 128x512 is perfectly valid.however, most cards still have this limit, so it's best to stick with it.
参考自:http://nehe.gamedev.net/wiki/NewLesson5.ashx
稍作翻译:
纹理的宽高必须是2的n次幂,最大限制受硬件的影响。
如,在iphone3g 里面,这个最大限制是1024*1024,
在 iphone4g 里面,这个最大限制是 2048*2048。
另外,纹理不一定要是正方形的,128 * 512 就非常完美的满足了这点需求。
第三,英伟达 GF6*** 以上的显卡已经取消了必须为2的N次幂的限制,
但大多数卡是不能做到这点的,所以还是遵从该规则比较好。。
今天遇到一个bug,伙计用TexturePacker出了满足如上条件的图片,
图片采用了 .pvr.ccz 的格式,所盛装图片数据的像素格式为 RGBA8888
本来我们的分工是我开发游戏场景,他开发菜单场景。
但是在他将做好的 菜单场景发给我的时候,我拿XCode4。2跑了一下,是不存在任何问题的。
但结果将他的菜单部分和我的游戏场景部分一整合,发现就乱了套了。
他的菜单场景加载图片的时候竟然很奇葩的报出了空指针错误。。。
当时我就郁闷了,明明分开的时候他的菜单场景跑的是那么的流畅,
而今我仅仅是将两份代码放到了一起,却出现了这等怪事情。
我摘录一段控制台输出放在这里,以示警戒:
cocos2d: Filename(imgp_menu_board_eles-hd.png) contains -hd suffix. Removing it. See cocos2d issue #1040
cocos2d: WARNING: Unsupported PVR Pixel Format: 0x12. Re-encode it with a OpenGL pixel format variant
cocos2d: CCSpriteFrameCache: Trying to use file 'animat_chapter_ele_ice.png' as texture
cocos2d: CCFileUtils: Warning HD file not found: animat_chapter_ele_ice-hd.png
cocos2d: CCTexture2D. Can't create Texture. UIImage is nil
cocos2d: Couldn't add image:animat_chapter_ele_ice.png in CCTextureCache
cocos2d: CCSpriteFrameCache: Couldn't load texture
cocos2d: CCSpriteFrameCache: Frame 'animat_chapter_ele_ice0.png' not found
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
百思不得其解之余,我又硬着头皮在cocos2d的源码里面翻来弄去,
我的 cocos2d的版本是 v1.0.0-rc3
之前我还以为 cocos2d 1.0 不支持非正方形的 pvr 格式图片。
后来有一次看到伙计竟然能够正常使用非正方形的 pvr 格式图片,才知道原来是可以这么做的。
我有这种想法主要源于我一开始是用 mac 自带的 TextureTool 来生成 pvr 图片的。
那个工具只支持生成正方形的 pvr 图片,再加上我这个人本来记性就不太好,弄着弄着就搞混了,
后面竟然一度认为 opengl 纹理图片需满足正方形的条件,汗~
扯远了拉回。分析一下上面的控制台输出:
不得不承认我是被那个 大写的 WARNING 给吓着了,还以为是系统将pvr图片从一个项目复制到另一个项目的时候,
发生了什么错误,然后导致了 pvr 图片损坏掉的情况。
无法确定之余,我又将整合项目中的相关图片给删除掉再重新添加了一次。
这次却依然报出同样的错误,还是报警告,说
Unsupported PVR Pixel Format: 0x12. Re-encode it with a OpenGL pixel format variant
我弄了很久,从12点一直弄到凌晨1点半,
终于发现,原来他妈的根本就不是这个 Unsurpported 的缘由。
说道这里我不得不问候一声 cocos2d 作者的先祖。。。
有点儿打瞌睡了,长话短说吧,
主要还是因为Animation plist 文件里面的 metadata节点没有包含textureFileName 子节点。
cocos2d实现纹理缓冲的机制请仔细查看相关类的实现,
我只提一点,为使OpenGL所绑定的纹理图片不被重复缓冲,
作者采用了这样的一种设计——弄一个字典用资源图片的所在路径对应opengl所绑定的纹理。
如我前面所述,cocos2d 确实还没有只能到你给个动画的名字他就能按你所想将图片加载成纹理。
cocos2d 在将一个动画 plist 文件中的数据搞进 textureCache 的时候,
如果该 plist 文件的 metadata 中没有包含相关 animation 图片集 的名称数据(textureFileName节点所对应的图片名称)
将会在 plist 文件名称的基础上去除后缀,将后缀改为 png。
这下就有点儿眉目了,对照控制台的一句输出:
Trying to use file 'animat_chapter_ele_ice.png' as texture
我仔细在工程的资源文件里面找了几遍,毫无 “animat_chapter_ele_ice.png” 的身影。
于是,我大胆的猜测这个可能就是导致问题的罪魁祸首。
在我将 textureFileName = animat_chapter_ele_ice.pvr.ccz 这个键值对应的数据放进 metadata 节点以后,
整合后的工程立马正常的运转了起来!
之前:
之后:
2012。04。09。16。17,诚心向 cocos2d 作者道歉!
我发现还是我的原因:
if( ! success )
CCLOG(@"cocos2d: WARNING: Unsupported PVR Pixel Format: 0x%2x. Re-encode it with a OpenGL pixel format variant", formatFlags);
我将上面的代码做出了一点修改:if( ! success )
NSLog(@"CCTexturePVR.m unpackPVRData failed!!");
CCLOG(@"cocos2d: WARNING: Unsupported PVR Pixel Format: 0x%2x. Re-encode it with a OpenGL pixel format variant", formatFlags);
哎,蛋疼啊~如果人人都能遵循即使 if 语句后面只跟一行代码也用大括号包起来的风格。
我也就不至于在此摔跟头了。看来这个警告根本就是由我自己不正确地改动代码整出来的,正确的写法应该如下:
if( ! success ) {
NSLog(@"CCTexturePVR.m unpackPVRData failed!!");
CCLOG(@"cocos2d: WARNING: Unsupported PVR Pixel Format: 0x%2x. Re-encode it with a OpenGL pixel format variant", formatFlags);
}