在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合。例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到OpenGLES混合。
在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合。例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到<code>OpenGLES混合</code>。

如上图所示,为石头墙、绿色矩形、蓝色云彩 三个矩形混合后的展示效果。三个矩形(Z轴深度由深到浅)分别为,石头墙、绿色矩形、蓝色云彩。
在OpenGLES中若使用混合,需要用到API函数方法(Java):
<code>void glBlendFunc( int srcfactor, int destfactor );</code>
(1) 其OpenGL函数原型为:
<code>void glBlendFunc(GLenum srcfactor, GLenum destfactor);</code>
(2) 其功能为:
控制<code>新画上来的颜色 (source values, RGBA)</code>和 已经在<code>帧缓冲区中的颜色 (destination values, RGBA)</code>的混合时<code>源与目标 在最终颜色通道中所占的比例</code>。
(3) 方法参数
<code>srcfactor:代表源因子,即新画上来的颜色。</code>
该参数由九个枚举型被接受使用:
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.
<code>destfactor:代表的是目标因子,即已经在帧缓冲区中的颜色。</code>
该参数由八个枚举型被接受使用:
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_ONE_MINUS_DST_ALPHA
举个栗子
参数含义
我们先看一个常用混合参数搭配:
以上参数搭配方式假设:
<code>(Sr, Sg, Sb, Sa)</code>代表<code>源颜色src(要绘制的颜色)</code>;
<code>(Dr, Dg, Db, Da)</code>代表<code>目标颜色Dest(缓冲区中颜色)</code>
如果源因子的不透明度为0.2(透明度0.8),alpha值的最大值为1,那么源与目标混合后的<code>最终颜色值</code>为:
启用混合与纹理矩形绘制顺序代码举例:
有了上边的例子,我们再回来看各个参数因子。
假设:
<code>(Dr, Dg, Db, Da)</code>代表<code>目标颜色Dest(缓冲区中颜色)</code>;
<code>(Kr, Kg, Kb, Ka)</code>代表缓冲区中各个通道R, G, B, A的最大值。
那么各个参数因子所代表的值如下表所示:
混合因子
各颜色通道色彩比例值
GL_ZERO
(0,0,0,0)
GL_ONE
(1,1,1,1)
GL_SRC_COLOR
(Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka)
GL_DST_COLOR
(Dr/Kr, Dg/Kg, Db/Kb, Da/Ka)
GL_ONE_MINUS_SRC_COLOR
(1,1,1,1) - (Sr/Kr,Sg/Kg,Sb/Kb,Sa/Ka)
GL_ONE_MINUS_DST_COLOR
(1,1,1,1) - (Dr/Kr,Dg/Kg,Db/Kb,Da/Ka)
GL_SRC_ALPHA
( Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka )
GL_ONE_MINUS_SRC_ALPHA
(1,1,1,1) - (Sa/Ka,Sa/Ka,Sa/Ka,Sa/Ka)
GL_DST_ALPHA
( Da/Ka, Da/Ka, Da/Ka, Da/Ka )
(1,1,1,1) - (Da/Ka,Da/Ka,Da/Ka,Da/Ka)
GL_SRC_ALPHA_SATURATE
(min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,1)
下边以三张纹理图片在不同混合因子设置下的效果图,对几种常见的混合效果进行举例说明。
其中 <code>离摄像机最远</code>的为一张 <code>Alpha=1.0</code> 的<code>石头墙</code>纹理图;
其次 为一张 <code>Alpha=0.6</code> 的<code>蓝色云彩</code>纹理图;
最后<code>离摄像机最近</code>的为一张 <code>Alpha=0.4</code>的绿色纹理图。
源颜色(最后绘制的绿色矩形)参数因子为GL_ONE,目标色(缓冲区中颜色)参数因子为GL_ZERO。
这种参数因子组合<code>混合比例 (1.0, 0.0)</code>:
源颜色(最后绘制的绿色矩形)覆盖目标色(缓冲区中颜色);
目标色(缓冲区中颜色)不起作用,
其运行效果如下图所示:
源颜色(最后绘制的绿色矩形)与 目标色(缓冲区中颜色)均为GL_ONE。
这种参数因子组合<code>混合比例 (1.0, 1.0)</code>:
<code>源颜色(最后绘制的绿色矩形)</code>与 <code>目标色(缓冲区中颜色)</code>在混合时,源与目标的色彩通道<code>颜色所占的比例相同</code>。
仔细观察以上效果图,可以看到三张图片叠加部分,几乎为白色。
源颜色(最后绘制的绿色矩形)参数因子为 GL_ONE,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_DST_ALPHA。
这种参数因子组合<code>混合比例 (1.0, 1.0-Da/Ka)</code>:
<code>源颜色(最后绘制的绿色矩形)</code>与<code>目标色(缓冲区中颜色)</code>,在混合时取<code>源颜色</code>与<code>(1- Da/Ka)比例</code>进行混合。
观察以上效果图:可以看到最上边绿色矩形占最终混合颜色的比例较高。
三张纹理绘制时:
前两张纹理混合时:源颜色为<code>蓝色云彩纹理矩形</code>,目标颜色为<code>石头墙纹理矩形</code>。
由于混合比例为 (1.0, 1.0-Da/Ka),混合后的最终颜色只显示<code>蓝色云彩纹理矩形</code>(石头墙纹理的ALPHA=1.0,最终石头墙颜色所占的比例 1.0-1.0=0.0,比例为0)。
其次<code>绿色纹理矩形</code>与<code>缓冲区中颜色</code>进行混合:源颜色为<code>绿色纹理矩形</code>,目标颜色为<code>缓冲区中颜色</code>。
混合后的最终颜色基本只显示<code>绿色纹理矩形</code>(蓝色云彩纹理矩形的ALPHA=0.6,(1-0.6)云纹理与绿色矩形混合后,几乎看不到云纹理的颜色)。
源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE。
这种参数因子组合<code>混合比例 (Sa/Ka, 1.0)</code>:
<code>源颜色(最后绘制的绿色矩形)</code>与<code>目标色(缓冲区中颜色)</code>,在混合时以源颜色值乘以Sa/Ka与目标颜色值相加。
观察以上效果图,可以看出目标墙面与云纹理混合后墙面纹理颜色值所占比例较高,三个纹理图片叠加部分有些像素点为白色。
这种方式是最常用的混合方式,源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_SRC_ALPHA。
这种参数因子组合<code>混合比例 (Sa/Ka, 1.0-Sa/Ka)</code>:
<code>源颜色(最后绘制的绿色矩形)</code>与 <code>目标色(缓冲区中颜色)</code>在混合时,取源颜色的 (Sa/Ka) 与目标颜色 (1.0-Sa/Ka) 相加计算最终的颜色值。
案例源码下载地址:
https://download.csdn.net/download/aiwusheng/64038379