起因很简单,公司的一个项目临近上线,再做各种tunning. 当试图减小包尺寸的时候注意到,到他传奇中的png有很大一部分使用一张jpg和一张灰度图实现的,由于jpg众所周知的高压缩比,所以用这个方案感觉很有吸引力啊,于是大家开始集思广益,先是有童鞋提出了这样一个方案
CCSprite* CCSprite::createMaskJpg( const char *pfile, const char *Mask) |
CCImage *jpgImage = new CCImage(); |
jpgImage -> initWithImageFile(pfile,CCImage::kFmtJpg); |
unsigned char *jpgData = jpgImage -> getData(); |
CCImage *pngImage = new CCImage(); |
pngImage -> initWithImageFile(Mask,CCImage::kFmtPng); |
unsigned char *pngData = pngImage->getData(); |
int len = jpgImage->getDataLen(); |
int width = jpgImage->getWidth(); |
int height = jpgImage->getHeight(); |
unsigned char *outPic = new unsigned char [len * 4]; |
for ( int i = 0; i < len * 4; i++) |
CCTexture2D *texture = new CCTexture2D(); |
texture->initWithData(outPic,kCCTexture2DPixelFormat_RGBA8888,width,height,CCSizeMake(( float )width, ( float )height)); |
return createWithTexture(......... |
大概齐是这个意思,大家凑活着看,大意就是根据mask中的像素信息来绘制最终的输出图片,但这个应该是要求mask中要有正确的透明通道信息……那要灰度干啥用。好吧这块我没看明白他想如何做。
我略一思考下意识的觉得应该使用shader做比较方便,无非就是想法怎么能吧mask中的灰度信息映射到原图的透明通道上嘛,于是乎我查了下灰度图的rgba构成,发现丫不管怎么计算rgb这三个值都是相同的,从全黑到全白,我了个日,全黑的不就是我要的透明的么,抬手就给整个了shader.

直接用的dota的图做测试,效果赞啊,
美中不足就是需要同时加载两张纹理,在设备内存这寸土寸金的地方不容这么霍霍啊。。
那既然不让同时用两张纹理动态计算,我在送纹理到GL前把转换做完不就好了么。。
搞之

让TextureCache在addImage的时候,试图加载下同名文件的alpha_mask作为一个CCImage传进来,要是有就作上述转换,没有就还走原来的。
打完收功