在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合,比如想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就要用到glBlendFunc()函数。
拿半透明效果来说,如果现在已经绘制了红色和白色两个矩形,想在上面画一个半透明的绿色矩形。
此时假设,绿色矩形的不透明度为20%,那么红色矩形与绿色矩形混合后的颜色为:
blendColor01 = (1-20%) *RED+20%GREEN
白色矩形与绿色矩形混合后的颜色为:
blendColor02 = (1-20%) * WHITE +20%GREEN
下面详细的解释一下glBlendFunc()的函数原型,各种参数的意义,以及用法。
1. 混合函数的函数原型
混合函数的原型为:
void glBlendFunc(GLenum srcfactor, GLenum destfactor);
它的功能就控制新画上来的颜色(source values, RGBA),和已经在帧缓冲区中的颜色(destination values, RGBA)是如何混合的。
2. 参数:
srcfactor代表源因子,即新画上来的颜色。九个枚举型被接受使用:
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,
GL_SRC_ALPHA_SATURATE.
destfactor代表的是目标因子,即已经在帧缓冲区中的颜色。八个枚举型被接受使用:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
3.每个枚举变量代表的意义
假设(Rs, Gs, Bs, As)代表“源颜色(src)”;(Rd, Gd, Bd, Ad)代表“目标颜色(dest)”;颜色的各个通道R, G, B, A的最大值是(kR,kG, kB, kA); i = min ( As, KA, Ad) /KA
各个枚举量所代表的值如表3-1所列:
表3-1 各混合因子枚举量的含义
混合因子 |
代表的含义 |
GL_ZERO |
( 0,0,0,0 ) |
GL_ONE |
( 1,1,1,1 ) |
GL_SRC_COLOR |
( RS/ KR,Gs/KG, Bb/ KB, AS / KA) |
GL_DST_COLOR |
( Rd/ KR, Gd/KG, Bd/KB, Ad/KA) |
GL_ONE_MINUS_SRC_COLOR |
( 1,1,1,1 ) - ( RS/KR, GS/KG, BS/KB, AS/ KA ) |
GL_ONE_MINUS_DST_COLOR |
(1,1,1,1) - ( Rd/KR, Gd/KG, Bd/KB, Ad/ KA ) |
GL_SRC_ALPHA |
( AS/KA, AS/KA, AS/KA, AS/KA ) |
GL_ONE_MINUS_SRC_ALPHA |
(1,1,1,1) - ( AS/KA, AS/KA, AS/KA, AS/KA ) |
GL_DST_ALPHA |
( Ad/KA, Ad/KA, Ad/KA, Ad/KA ) |
GL_ONE_MINUS_DST_ALPHA |
(1,1,1,1) - ( Ad/KA, Ad/KA, Ad/KA, Ad/KA ) |
GL_SRC_ALPHA_SATURATE |
(i,i,i,1) |
此处以最常用的混合因子搭配方式,即源因子为GL_SRC_ALPHA,目标因子为GL_ONE_MINUS_SRC_ALPHA的搭配形式,举例说明混合后的颜色如何生成。
常用混合方式的代码:
gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
假设源因子的不透明度为0.2,alpha值的最大值为1,那么源与目标混合后的最终的颜色值为:
( 0.2*Rs+(1-0.2)*Rd , 0.2*Gs+ (1-0.2)* Gd , 0.2* Bs+(1-0.2)*Bd , 0.2*As+(1-0.2)*Ad )
4. 下表列举几种常用混合方式的效果:
下面以三张纹理图片在不同混合因子设置下的效果图,对几种常见的混合效果进行介绍。其中离摄像机最远的为一张Alpha值为1的墙面纹理图,其次为一张Alpha为0.6的天空纹理图,离摄像机最近的为一张不透明度为0.6的绿色纹理图。
(1) 默认混合方式为( GL_ONE, GL_ZERO )
这种方式意味着目标色不起作用,仅仅用源色覆盖目标色,效果如下4-1所示。
图4-1默认混合方式为( GL_ONE, GL_ZERO )的效果图
(2)第二种混合方式为(GL_ONE, GL_ONE)
这种方式意味着源颜色与目标颜色,在混合时所占的比例相同,效果如图4-2所示。
图4-2默认混合方式为( GL_ONE, GL_ ONE)的效果图
仔细观察效果图,可以看到三张图片叠加部分,几乎为白色。
(3)第三种混合方式为(GL_ONE, GL_ONE_MINUS_DST_ALPHA)
这种方式意味着源颜色与目标颜色,在混合时取源颜色与 (1- Ad/KA)进行混合,效果如图4-3所示。
图4-3混合方式为(GL_ONE, GL_ONE_MINUS_DST_ALPHA)的效果图
观察效果图,可以看到最上边绿色矩形占最终混合颜色的比例较高,由于墙面的ALPHA为1,所以墙面与云混合后,只显示云的颜色;由于云纹理的ALPHA值为0.6,因此(1-0.6)云纹理与绿色矩形混合后,几乎看不到云纹理的颜色。
(4)第四种混合方式为(GL_SRC_ALPHA, GL_ONE)
这种方式意味着源颜色与目标颜色,在混合时以源颜色值乘以AS/KA与目标颜色值相加,效果如图4-4所示。
图4-4混合方式为(GL_SRC_ALPHA, GL_ONE)时的运行的效果图
观察效果图,可以看出目标墙面与云纹理混合后墙面纹理颜色值所占比例较高,三个纹理图片叠加部分有些像素点为白色。
(5)第五种混合方式为(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
这种方式是最常用的混合方式,在混合时取源颜色的(AS/KA)与目标颜色的(1- AS/KA)相加计算最终的颜色值,效果如图4-5所示。
图4-5混合方式为(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)的效果图