Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合
来源:互联网 发布:剑灵龙族男捏脸数据 编辑:程序博客网 时间:2024/06/08 13:44
Blend是OpenGL中的一个非常重要的部分,它可以让每个输出的源和目的颜色以多种方式组合在一起,以呈现出不同的效果,满足不同的需求。
Blend相关函数及意义
在OpenGLES1.0中,Blend在OpenGLES固定的管线中,OpenGLES2.0相对1.0来说,更为灵活。在OpenGLES2.0中,与Blend相关的函数及功能主要有:
//调用此方法,传入GL_BLEND开启BLEND功能void glEnable(GLenum cap);//调用此方法,出入GL_BLEND关闭BLEND功能void glDisable(GLenum cap);//设置BLEND颜色,结合glBlendFuncSeparate或glBlendFunc使用void glBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);//设置BLEND方程式void glBlendEquation(GLenum mode);//对RGB和Alpha分别设置BLEND方程式void glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha);//设置BLEND函数void glBlendFunc(GLenum sfactor,GLenum dfactor);//对RGB和Alpha分别设置BLEND函数void glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha);
Blend的使用比较简单,但是如果不理解Blend的这些函数及参数的意义,使用了错误的参数,就难以获得我们所期望的混合结果了。
想要使用Blend,glEnable(GL_BLEND)
当然是必须的。与之对应的,不需要Blend的时候,我们需要调用glDisable(GL_BLEND)
来关闭混合。
另外的四个方法,看名字差不多就能知道他们的意义了。 glBlendFunc
和glBlendFuncSeparate
都是设置混合因子,反正就是这么个意思了。区别在于glBlendFunc是设置RGBA的混合因子,而glBlendFuncSeparate是分别设置RGB和Alpha的混合因子。设置混合因子是做什么的呢?继续看。 glBlendEquation
和glBlendEquationSeparate
都是设置Blend的方程式,也就是设置混合的计算方式了,具体参数后面说。他们的区别在同glBlendFunc
和glBlendFuncSeparate
的区别一样。
颜色、因子、方程式,组合起来就是:最终颜色=(目标颜色*目标因子)@(源颜色*源因子),其中@表示一种运算符。
至于glBlendColor则是在glBlendFunc和glBlendFuncSeparate的设置中,因子可以设置和常量相关的,这个常量就是由glBlendColor设置进去的。
glBlendFunc及glBlendFuncSeparate详细说明
glBlendFuncSeparate设置混合因子,参数及它们表示的主要如下,而glBlendFunc的参数也是这些,表示的意义就是RGB和A合并为RGBA就是了。在下表中,s0表示源,d表示目的,c表示有glBlendColor设置进来的常量。
glBlendEquation及glBlendEquationSeparate详细说明
glBlendEquationSeparate的设置混合操作,参数及其意义如下表所示。通过glBlendEquationSeparate或者glBlendEquation设置的方程中,源和目的颜色分别为
Blend代码示例
@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) { GLES20.glClearColor(0,0,0,0); mSrcFilter.create(); mDstFilter.create(); int[] textures=new int[2]; //导入一张图片设置为源纹理 GLES20.glGenTextures(2,textures,0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textures[0]); EasyGlUtils.useTexParameter(); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,srcBitmap,0); mSrcFilter.setTextureId(textures[0]); //再导入一张图片设置为目标纹理 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textures[1]); EasyGlUtils.useTexParameter(); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,dstBitmap,0); mDstFilter.setTextureId(textures[1]);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) { this.width=width; this.height=height; mSrcFilter.setSize(width,height); mDstFilter.setSize(width,height); MatrixUtils.getMatrix(mDstFilter.getMatrix(),MatrixUtils.TYPE_FITSTART, dstBitmap.getWidth(),dstBitmap.getHeight(),width,height); MatrixUtils.getMatrix(mSrcFilter.getMatrix(),MatrixUtils.TYPE_FITSTART, srcBitmap.getWidth(),srcBitmap.getHeight(),width,height);}@Overridepublic void onDrawFrame(GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); //开启Blend GLES20.glEnable(GLES20.GL_BLEND); //设置BlendFunc,第一个参数为源混合因子,第二个参数为目的混合因子 GLES20.glBlendFunc(nSrcPar,nDstPar); //设置BlendEquation,GLES2.0中有三种 GLES20.glBlendEquation(equaInt[nEquaIndex]); GLES20.glViewport(0,0,width,height); //先渲染目的纹理出来,再渲染源纹理出来,是源纹理去与目的纹理混合 mDstFilter.draw(); mSrcFilter.draw();}
目的纹理和源纹理使用的图片分别如下所示(作为源的图片为了表现混合效果,上中下三部分用了不一样的透明度,最下面部分不透明):
根据公式推敲下渲染的结果:
1. 当目标和源因子都设置为GL_ZERO,无论混合方程怎样设置,最终肯定啥也没有。
2. 当源设置为GL_ONE,目标设置为GL_ZERO,方程设置为加还是减,最终应该渲染的就是目标的颜色,也就是之渲染出金币。
3. 当源设置为GL_ONE,目标设置为GL_SRC_COLOR,方程设置为加,根据公式最终颜色=(目标颜色*目标因子)+(源颜色*源因子),得到最终有颜色的区域必定是源alpha不为0的区域,因为源是作为目标因子的,源*目标,最终源中alpha为0的区域,这个结果也为0,也就是最终的结果区域透明了。
其他的都根据公式了。最终不同参数下的混合结果所示,1、2、3分别于图1、2、3对应。
源码
所有的代码全部在一个项目中,托管在Github上,欢迎Star和Fork——Android OpenGLES 2.0系列博客的Demo
欢迎转载,转载请保留文章出处。湖广午王的博客[http://blog.csdn.net/junzia/article/details/76580379]
- Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合
- Android OpenGLES2.0(一)——了解OpenGLES2.0
- Android OpenGLES2.0(一)——了解OpenGLES2.0
- Android OpenGLES2.0(二)——绘制一个三角形
- Android OpenGLES2.0(四)——正方形和圆形
- Android OpenGLES2.0(五)——绘制立方体
- Android OpenGLES2.0(三)——等腰直角三角形和彩色的三角形
- Android OpenGLES2.0(六)——构建圆锥、圆柱和球体
- Android OpenGLES2.0(七)——着色器语言GLSL
- Android OpenGLES2.0(八)——纹理贴图之显示图片
- Android OpenGLES2.0(九)——利用OpenGL进行图片处理
- Android OpenGLES2.0(十)——OpenGL中的平移、旋转、缩放
- Android OpenGLES2.0(十一)——利用OpenGLES做Camera预览
- Android OpenGLES2.0(十二)——FBO离屏渲染
- Android OpenGLES2.0(十三)——流畅的播放逐帧动画
- Android OpenGLES2.0(十四)——Obj格式3D模型加载
- Android OpenGLES2.0(十五)——利用EGL后台处理图像
- Android OpenGLES2.0(十七)——球形天空盒VR效果实现
- java迭代器浅析
- Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo 矩阵快速幂+dp
- 字体图标使用方法——以Iconfont为例
- Lintcode翻转链表
- onclick="function()"和onclick="return function();"区别
- Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合
- UVA 11149
- Excel导出简单例子
- [leetcode]52. N-Queens II
- Error Domain=NSURLErrorDomain Code=-999错误
- Attribute和Extension
- 韩国乐天首家海外免税店关门大吉 韩媒:“祸”不单行
- CFcontest377-D 贪心,二分
- jedisLock—redis分布式锁实现