多张图片混合成一张图片(alpha)
CCImage* body = new CCImage();
body->initWithImageFile("b.png", CCImage::kFmtPng);
CCImage* cloth = new CCImage();
cloth->initWithImageFile("y.png", CCImage::kFmtPng);
CCImage* hair = new CCImage();
hair->initWithImageFile("t.png", CCImage::kFmtPng);
unsigned char *bData = body->getData();
unsigned char *cData = cloth->getData();
unsigned char *hData = hair->getData();
int iIndex = 0;
for (int i = 0; i < body->getHeight(); i ++)
{
for (int j = 0; j < body->getWidth(); j ++)
{
int iBPos = iIndex;
unsigned int bodyB = bData[iIndex];
unsigned int clothB = cData[iIndex];
unsigned int hairB = hData[iIndex];
iIndex ++;
unsigned int bodyG = bData[iIndex];
unsigned int clothG = cData[iIndex];
unsigned int hairG = hData[iIndex];
iIndex ++;
unsigned int bodyR = bData[iIndex];
unsigned int clothR = cData[iIndex];
unsigned int hairR = hData[iIndex];
iIndex ++;
unsigned int bodyA = bData[iIndex];
unsigned int clothA = cData[iIndex];
unsigned int hairA = hData[iIndex];
iIndex ++;
//身体和衣服混合
bodyB = clothB*(clothA/255.f) + ((255.f-clothA)/255.f)*bodyB;
bodyG = clothG*(clothA/255.f) + ((255.f-clothA)/255.f)*bodyG;
bodyR = clothR*(clothA/255.f) + ((255.f-clothA)/255.f)*bodyR;
bodyA =((clothA/255.f)*(clothA/255.f)+((255.f-clothA)/255.f)*(bodyA/255.f))*255.f;
//身体和衣服混合后,再和头发混合
bodyB = hairB*(hairA/255.f) + ((255.f-hairA)/255.f)*bodyB;
bodyG = hairG*(hairA/255.f) + ((255.f-hairA)/255.f)*bodyG;
bodyR = hairR*(hairA/255.f) + ((255.f-hairA)/255.f)*bodyR;
bodyA =((hairA/255.f)*(hairA/255.f)+((255.f-hairA)/255.f)*(bodyA/255.f))*255.f;
//结果值
bData[iBPos] = (unsigned char)bodyB;
bData[iBPos + 1] = (unsigned char)bodyG;
bData[iBPos + 2] = (unsigned char)bodyR;
bData[iBPos + 3] = (unsigned char)bodyA;
}
}
CCTexture2D* texture = new CCTexture2D;
texture->initWithImage(body);
CCSprite* bSprite = CCSprite::spriteWithTexture(texture);
bSprite->setPosition(ccp(240,150));
addChild(bSprite, 1);
body->release();
cloth->release();
hair->release();
texture->release();
其实就一个公式:
目标值 = 上图alpha值*上图值 + (1-上图alpha值)*下图值 alpha = [0, 1];
cocos2d-x细节之自绘图形透明度问题
如若重载CCSprite的draw函数,记得设置blend混合模式,默认是没有透明度的。
示例如下:
void draw()
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //cocos2d默认混合模式
//根据圆的半径来计算分割份数,一般够用
ccDrawColor4F(color.r, color.g, color.b, color.a);
ccDrawSolidArc(CCPointZero, radius, radius*10, radsrc/180*M_PI, raddest/180*M_PI); //注意这里用坐标(0,0)!
}
如果没有glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),绘制的图形就不会有透明效果!
CCSprite有一个ccBlendFunc类型的blendFunc_结构体成员,可以用来设置描绘时的颜色混合方案。ccBlendFunc包含了一个src和一个dst,分别表示目标和源的运算因子。
混合后的RGBA为:(Rs*N_Rs+ Rd* N_Rd,Gs*N_Gs+ Gd* N_Gd,
常数 | 相关因子 | 融合因子结果 |
GL_ZERO | 源因子或目的因子 | (0,0,0,0) |
GL_ONE | 源因子或目的因子 | (1,1,1,1) |
GL_DST_COLOR | 源因子 | (Rd,Gd,Bd,Ad) |
GL_SRC_COLOR | 目的因子 | (Rs,Gs,Bs,As) |
GL_ONE_MINUS_DST_COLOR | 源因子 | (1,1,1,1)-(Rd,Gd,Bd,Ad) |
GL_ONE_MINUS_SRC_COLOR | 目的因子 | (1,1,1,1)-(Rs,Gs,Bs,As) |
GL_SRC_ALPHA | 源因子或目的因子 | (As,As,As,As) |
GL_ONE_MINUS_SRC_ALPHA | 源因子或目的因子 | (1,1,1,1)-(As,As,As,As) |
GL_DST_ALPHA | 源因子或目的因子 | (Ad,Ad,Ad,Ad) |
GL_ONE_MINUS_DST_ALPHA | 源因子或目的因子 | (1,1,1,1)-(Ad,Ad,Ad,Ad) |
GL_SRC_ALPHA_SATURATE | 源因子 | (f,f,f,1); f=min(As,1-Ad) |