cocos2d-x细节之自绘图形透明度问题
cocos2d吧
全部回复
仅看楼主
level 7
liuxijob 楼主
多张图片混合成一张图片(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,分别表示目标和源的运算因子。
如果我们对一个Sprite使用setBlendFunc方法,如:
[Sprite setBlendFunc:(ccBlendFunc){GL_ONE,GL_ZERO} ];
会以这个Sprite作为源,Sprite所在位置的其它像素作为目标,进行混合运算:
源的RGBA变量:Rs,Gs,Bs,As;
目标的RGBA: Rd,Gd,Bd,Ad;
源的各个运算因子: N_Rs,N_Gs,N_Bs,N_As;
目标的各个运算因子: N_Rd,N_Gd,N_Bd,N_Ad;
混合后的RGBA为:(Rs*N_Rs+ Rd* N_Rd,Gs*N_Gs+ Gd* N_Gd,
Bs*N_Bs+ Bd* N_Bd,As*N_As+ Ad* N_Ad)
其中的运算因子包括:
GL_ONE:1.0
GL_ZERO:0.0
GL_SRC_ALPHA:源的Alpha值作为因子
GL_DST_ALPHA:目标Alpha作为因子
GL_ONE_MINUS_SRC_ALPHA:1.0减去源的Alpha值作为因子
GL_ ONE_MINUS_DST_ALPHA:1.0减去目标的Alpha值作为因子
我们可以在CCSprite的init方法中看到,默认的状态下使用GL_ONE,GL_ONE_MINUS_SRC_ALPHA这两个参数,这也是我们看到的情况,Sprite会覆盖下面的描绘,但如果有透明的地方,则会显示下面的色值。让我们看一下说使用各个参数的效果: 0:不改变混合,使用默认的情况: [img pic_type=1 width=undefined height=undefined]http://www.58player.com/picture/136517.jpg[/img]
1:如果设置glBlendFunc(GL_ONE,GL_ZERO), 表面完全使用源颜色,即和不混合一样的效果,但是如果Sprite本身有透明的地方,则透明的地方会变成黑色。因为此时不显示目标的颜色。即使透明度为0也没有意义。 [img pic_type=1 width=undefined height=undefined]http://www.58player.com/picture/136518.jpg[/img]
2:如果设置glBlendFunc(GL_ZERO, GL_ONE),表示不使用源颜色,那么该Sprite便不被画出来。 [img pic_type=1 width=undefined height=undefined]http://www.58player.com/picture/136519.jpg[/img]
3:使用ALPHA相关的因子,会根据透明度来计算,比如透明度高的颜色占较大比重等。如默认情况。
附:
常数
相关因子
融合因子结果
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)
2014年07月25日 01点07分 1
1