一、混合相关概念
1、颜色(color):编程中一般将颜色分为4个变量RGBA(红、绿、蓝、透明度)
源(source):即将要画上去的颜色
目标(destination):已经存在帧缓冲区中的颜色
混合:将源和目标按照一定比例绘制到帧缓冲区中
源混合因子:将来与源相乘作为源的混合比例控制参数
目标混合因子: 将来与目标相乘作为目标的混合比例控制参数
2、混合公式:
混合=源*源混合因子+目标*目标混合因子
用向量表示为:
混合=(R源*R源因 ,G源*G源因,B源*B源因,A源*A源因)+(R标*R标因,G标*G标因,B标*B标因,A标*A标因)
=(R源*R源因+R标*R标因,G源*G源因+G标*G标因,B源*B源因+B标*B标因,A源*A源因+A标*A标因)
注:上述公式中源和目标的最终混合方式不一定是加法,现版本中opengl中的混合方式包括减法、取较大值、取较小值、逻辑运算等。
3、opengl 提供的混合因子常量
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值来作为因子。
4、常用混合因子组合
这里对概念理解上需要提醒一下,所谓混合不是把两张图像先混合好了再填进帧缓冲区,而是把当前要绘制的图像跟已经存在帧缓冲区中的图像混合,比如你要混合两张图像,在绘制第一张图像时它也是作为源绘制的,尽管在绘制第二张图像时它将变成目标。
(1)均匀混合两幅图像
首先将源因子和目标因子分别设置为GL_ONE和GL_ZERO,绘制第一幅图像;然后将源因子设置为GL_SRC_ALPHA,目标因子设置为GL_ONE_MINUS_SRC_ALPHA,并在绘制第二幅图像时将alpha值设置为0.5。
(2)三张图像均匀混合
将目标因子设置为GL_ONE,将源因子设置为GL_SRC_ALPHA,然后将三张图像的alpha值全设置为0.33333来绘制即可。
二、混合实例
一直感觉opengl就像一架宇航器,内部构造复杂,命令参数众多,但他最终呈现给宇航员的是一些操作按钮,学会如何高效率的使用这些按钮协调工作就能够自由地畅游在3D渲染的广袤世界里。
启动混合
启动类命令一般在初始化类函数中调用,比如在android的opengl es里就是在onSurfaceCreated回调函数里调用的。
gl.glEnable(GL10.GL_BLEND);//开启混合
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_DST_ALPHA);//指定混合因子
// gl.glBlendFunc(GL10.GL_SRC_COLOR, GL10.GL_DST_ALPHA);
之后绘制的所有图像都是按照这种混合因子混合的,不用混合时调用gl.glDisable(GL10.GL_BLEND)就行了。
上面讲了一大堆,在代码中只有短短两句就搞定了。。。你也别气愤,opengl很多地方都是这样的,可就算你把原理弄明白了,想调出你想要的效果还是不那么容易的。
注意:打开混合,需要关闭深度测试,这是我测试时发现的,原因我也不清楚,知道的麻烦回帖告之,先谢过!
//混合开关
if (key)
{
gl.glEnable(GL10.GL_BLEND); // 打开混合
gl.glDisable(GL10.GL_DEPTH_TEST); // 关闭深度测试
}
else
{
gl.glDisable(GL10.GL_BLEND); // 关闭混合
gl.glEnable(GL10.GL_DEPTH_TEST); // 打开深度测试
}
混合部分到此完毕!