OpenGL glBlendFunc 之 cocos2dx - ccBlendFunc 研究

glBlendFunc();--混合


OpenGL 会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的颜色。下面用数学公式来表达一下这个运算方式。

假设源颜色的四个分量(指红色,绿色,蓝色,alpha值)是(Rs, Gs, Bs, As),

目标颜色的四个分量是(Rd, Gd, Bd, Ad)

源因子为(Sr,Sg, Sb, Sa)

目标因子为(Dr,Dg, Db, Da)

则混合产生的新颜色可以表示为: (Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da) 当然了,如果颜色的某一分量超过了1.0,则它会被自动截取为1.0,不需要考虑越界的问题。

源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,下面介绍比较常用的几种。

GL_ZERO
: 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。
GL_ONE
: 表示使用1.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值来作为因子。

 

除此以外,还有GL_SRC_COLOR(把源颜色的四个分量分别作为因子的四个分量)、GL_ONE_MINUS_SRC_COLOR、 GL_DST_COLOR、GL_ONE_MINUS_DST_COLOR等,前两个在OpenGL旧版本中只能用于设置目标因子,后两个在OpenGL 旧版本中只能用于设置源因子。新版本的OpenGL则没有这个限制,并且支持新的GL_CONST_COLOR(设定一种常数颜色,将其四个分量分别作为 因子的四个分量)、GL_ONE_MINUS_CONST_COLOR、GL_CONST_ALPHA、 GL_ONE_MINUS_CONST_ALPHA。另外还有GL_SRC_ALPHA_SATURATE。新版本的OpenGL还允许颜色的alpha 值和RGB值采用不同的混合因子。



举例来说:

1、如果设置了glBlendFunc(GL_ONEGL_ZERO);则表示完全使用源颜色,完全不使用目标颜色

 

2、如果设置了glBlendFunc(GL_ZERO, GL_ONE);,则表示完全不使用源颜色,因此无论你想画什么,最后都不会被画上去了。

 

3、如果设置了glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,则表示源颜色乘以自身的alpha值,目标颜色乘以1.0减去源颜色的alpha值,这样一来,源颜色的alpha值越大,则产生的新颜色中源颜色所占比例就越大,而目标颜色所占比例则减小。这种情况下,我们可以简单的将源颜色的alpha值理解为“不透明度”。这也是混合时最常用的方式。

 

4、如果设置了glBlendFunc(GL_ONE, GL_ONE);,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。例如红色(1, 0, 0)和绿色(0, 1, 0)相加得到(1, 1, 0),结果为黄色。

 

5、如果设置了glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); cocos2dx 有alpha通道默认方式。如果源alpha 越来越大,表示显示当前区域越来越接近源的颜色

 

6、如果设置了glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); cocos2dx 没有alpha 通道默认方式。表示是比较典型的半透明效果,如果源色 alpha0,则取目标色,如果源色alpha1,则取源色,否则视源色的alpha大小各取一部分。源色的alpha越大,则源色取的越多,最终结果源色的表现更强;源色的alpha越小,则目标色“透过”的越多。

 

注意: 所谓源颜色和目标颜色,是跟绘制的顺序有关的。假如先绘制了一个红色的物体,再在其上绘制绿色的物体。则绿色是源颜色,红色是目标颜色。

            如在cocos2dx

      CCSprite* objSrc;   //----->目标颜色

CCSprite* objDst;  //----->源颜色

objDst->setBlendFunc(xxx);

objSrc->addChild(objDst);

 

如果顺序反过来,则红色就是源颜色,绿色才是目标颜色。在绘制时,应该注意顺序,使得绘制的源颜色与设置的源因子对应,目标颜色与设置的目标因子对应。不要被混乱的顺序搞晕。

 

大概就是这样:第一个参数指出源图元的alpha的取值计算方法,第二个参数指出目标处的alpha的计算方法。 


个人理解: 
两个参数的取值都可以是如下常量之一: 
GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, andGL_SRC_ALPHA_SATURATE 
比如GL_ZERO表示alpha取值为0,GL_ONE表示1,GL_DST_COLOR表示取目标区域的颜色值,GL_SRC_ALPHA表示取源区域的alpha值等等。

例如: 
glBlendFunc(GL_SRC_ALPHA, GL_ONE); 
表示把渲染的图像叠加到目标区域,也就是说源的每一个像素的alpha都等于自己的alpha,目标的每一个像素的alpha等于1。这样叠加次数越多,叠加的图元的alpha越高,得到的结果就越亮。因此这种融合用于表达光亮效果。

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
表示把渲染的图像融合到目标区域。也就是说源的每一个像素的alpha都等于自己的alpha,目标的每一个像素的alpha等于1减去该位置源像素的alpha。 因此不论叠加多少次,亮度是不变的。


Cocos2dx 应用:

效果:


该效果由两张图片通过混合达成。

资源图片:

    

 

代码:

CCSprite* objSpriteBg = CCSprite::create(背景图片);

CCSprite* objSpriteLight =CCSprite::create(光圈图片);

CCBlendFunc objBlendFunc = {GL_SRC_ALPHA, GL_ONE};

objSpriteLight->setBlendFunc(objBlendFunc);

objSpriteBg->addChild(objSpriteLight);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值