位置: 编程技术 - 正文

OpenGL——颜色混合 glBlendFunc函数(opengl调色)

编辑:rootadmin

推荐整理分享OpenGL——颜色混合 glBlendFunc函数(opengl调色),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:opengl 颜色,opengl颜色填充,opengl颜色代码表,opengl颜色表,opengl颜色混合模式,opengl颜色混合,opengl颜色混合,opengl颜色混合,内容如对您有帮助,希望把文章链接给更多的朋友!

OpenGL——颜色混合 glBlendFunc函数(opengl调色)

参考来源: 红色就是源颜色,绿色才是目标颜色。在绘制时,应该注意顺序,使得绘制的源颜色与设置的源因子对应,目标颜色与设置的目标因子对应。不要被混乱的顺序搞晕了。OpenGL 会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的颜 色。(也可以不是相加,新版本的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(GLenum sfactor,GLenum dfactor);源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者sfactor表示源因子,后者dfactor表示目标因子。这两个参数可以是多种&#;,下面介绍比较常用的几种。GL_ZERO: 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。GL_ONE: 表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。GL_SRC_ALPHA:表示使用源颜色的alpha&#;来作为因子。GL_DST_ALPHA:表示使用目标颜色的alpha&#;来作为因子。GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha&#;来作为因子(1-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&#;采用不同的混合因子。但这些都不是我们现在所需要了解的。毕竟这还是入门教材,不需要整得太复杂~举例来说:如果设置了glBlendFunc(GL_ONE, GL_ZERO);,则表示完全使用源颜色,完全不使用目标颜色,因此画面效果和不使用混合的时候一致(当然效率可能会低一点点)。如果没有设置源因子和目标因子,则默认情况就是这样的设置。如果设置了glBlendFunc(GL_ZERO, GL_ONE);,则表示完全不使用源颜色,因此无论你想画什么,最后都不会被画上去了。(但这并不是说这样设置就没有用,有些时候可能有特殊用途)如 果设置了glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,则表示源颜色乘以自身的alpha &#;,目标颜色乘以1.0减去源颜色的alpha&#;,这样一来,源颜色的alpha&#;越大,则产生的新颜色中源颜色所占比例就越大,而目标颜色所占比例则减 小。这种情况下,我们可以简单的将源颜色的alpha&#;理解为“不透明度”。这也是混合时最常用的方式。如果设置了glBlendFunc(GL_ONE, GL_ONE);,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。例如红色(1, 0, 0)和绿色(0, 1, 0)相加得到(1, 1, 0),结果为黄色。实现三维混合也许你迫不及待的想要绘制一个三维的带有半透明物体的场景了。但是现在恐怕还不行,还有一点是在进行三维场景的混合时必须注意的,那就是深度缓冲。深度缓冲是这样一段数据,它记录了每一个像素距离观察者有多近。在启用深度缓冲测试的情况下,如果将要绘制的像素比原来的像素更近,则像素将被绘制。否则, 像素就会被忽略掉,不进行绘制。这在绘制不透明的物体时非常有用——不管是先绘制近的物体再绘制远的物体,还是先绘制远的物体再绘制近的物体,或者干脆以 混乱的顺序进行绘制,最后的显示结果总是近的物体遮住远的物体。然而在你需要实现半透明效果时,发现一切都不是那么美好了。如果你绘制了一个近距离的半透明物体,则它在深度缓冲区内保留了一些信息,使得远处的物体将无法再被绘制出来。虽然半透明的物体仍然半透明,但透过它看到的却不是正确的内容了。要解决以上问题,需要在绘制半透明物体时将深度缓冲区设置为只读,这样一来,虽然半透明物体被绘制上去了,深度缓冲区还保持在原来的状态。如果再有一个物体 出现在半透明物体之后,在不透明物体之前,则它也可以被绘制(因为此时深度缓冲区中记录的是那个不透明物体的深度)。以后再要绘制不透明物体时,只需要再 将深度缓冲区设置为可读可写的形式即可。嗯?你问我怎么绘制一个一部分半透明一部分不透明的物体?这个好办,只需要把物体分为两个部分,一部分全是半透明 的,一部分全是不透明的,分别绘制就可以了。即使使用了以上技巧,我们仍然不能随心所欲的按照混乱顺序来进行绘制。必须是先绘制不透明的物体,然 后绘制透明的物体。否则,假设背景为蓝色,近处一块红色玻璃,中间一个绿色物体。如果先绘制红色半透明玻璃的话,它先和蓝色背景进行混合,则以后绘制中间 的绿色物体时,想单独与红色玻璃混合已经不能实现了。总结起来,绘制顺序就是:首先绘制所有不透明的物体。如果两个物体都是不透明的,则谁先谁后 都没有关系。然后,将深度缓冲区设置为只读。接下来,绘制所有半透明的物体。如果两个物体都是半透明的,则谁先谁后只需要根据自己的意愿(注意了,先绘制 的将成为“目标颜色”,后绘制的将成为“源颜色”,所以绘制的顺序将会对结果造成一些影响)。最后,将深度缓冲区设置为可读可写形式。调用glDepthMask(GL_FALSE);可将深度缓冲区设置为只读形式。调用glDepthMask(GL_TRUE);可将深度缓冲区设置为可读可写形式。一些网上的教程,包括大名鼎鼎的NeHe教程,都在使用三维混合时直接将深度缓冲区禁用,即调用glDisable(GL_DEPTH_TEST);。这样做并不正确。如果先绘制一个不透明的物体,再在其背后绘制半透明物体,本来后面的半透明物体将不会被显示(被不透明的物体遮住了),但如果禁用深度缓冲,则它仍然将会显示,并进行混合。NeHe提到某些显卡在使用glDepthMask函数时可能存在一些问题,但可能是由于我的阅历有限,并没有发现这样的 情况。 那么,实际的演示一下吧。我们来绘制一些半透明和不透明的球体。假设有三个球体,一个红色不透明的,一个绿色半透明的,一个蓝色半透明的。红色最远,绿色 在中间,蓝色最近。根据前面所讲述的内容,红色不透明球体必须首先绘制,而绿色和蓝色则可以随意修改顺序。这里为了演示不注意设置深度缓冲的危害,我们故 意先绘制最近的蓝色球体,再绘制绿色球体。 为了让这些球体有一点立体感,我们使用光照。在(1, 1, -1)处设置一个白色的光源。代码如下:(原参考处只提供了实现光照和小球绘制的部分,其余部分是自己所写,可能存在考虑不当的地方,也希望大家能给予指正或提出建议,谢谢)运行结果(图1):若将上面两处glDepthMask删去,结果会看到最近的蓝色球虽然是半透明的,但它的背后直接就是红色球了,中间的绿色球没有被正确绘制。运行结果(图2):现在我们可以对比下图1和图2, 发现当我们在绘制半透明物体时将深度缓冲区设置为只读时:glDepthMask(GL_FALSE);继不透明红色球绘制好后,半透明蓝色球也被绘制上去了,此时深度缓冲区还保持在原来的状态(即记录的是红色球处的深度)。之后半透明绿色球出现在半透明蓝色球之后,在不透明红色球之前,则它也可以被绘制(因为此时深度缓冲区中记录的是那个不透明红色球的深度)。 当我们将上面两处glDepthMask删去时,默认为启用深度缓冲测试的情况下,此时绘制完红色球、蓝色球之后,接着绘制绿色球的时候,将发现要绘制的蓝色球像素比画完的蓝色球像素要远,则绿色球被遮挡部分将不进行绘制。注意:要记住此处说的像素远近就是上文中提到的绘制的物体同观察点的距离远近(即跟视点的距离)。小结:文中介绍了OpenGL混合功能的相关知识。混合就是在绘制时,不是直接把新的颜色覆盖在原来旧的颜色上,而是将新的颜色与旧的颜色经过一定的运算,从而产生新的颜色。新的颜色称为源颜色,原来旧的颜色称为目标颜色。传统意义上的混合,是将源颜色乘以源因子,目标颜色乘以目标因子,然后相加。源 因子和目标因子是可以设置的。源因子和目标因子设置的不同直接导致混合结果的不同。将源颜色的alpha&#;作为源因子,用1.0减去源颜色alpha&#;作 为目标因子,是一种常用的方式。这时候,源颜色的alpha&#;相当于“不透明度”的作用。利用这一特点可以绘制出一些半透明的物体。在进行混合时,绘制的顺序十分重要。因为在绘制时,正要绘制上去的是源颜色,原来存在的是目标颜色,因此先绘制的物体就成为目标颜色,后来绘制的则成为源颜色。绘制的顺序要考虑清楚,将目标颜色和设置的目标因子相对应,源颜色和设置的源因子相对应。在进行三维混合时,不仅要考虑源因子和目标因子,还应该考虑深度缓冲区。必须先绘制所有不透明的物体,再绘制半透明的物体。在绘制半透明物体时前,还需要将深度缓冲区设置为只读形式,否则可能出现画面错误。最后的最后,个人自问自答环节:学习的过程中,我一直在想当我们将两个颜色混合后获得的新颜色是存放在哪的呢?之后又是怎样被使用到绘制的过程中呢?而后,看了其它资料,&#;乎,这里并没有所谓的存放在哪之类的考究,也许可以理解为当我们glEnable(GL_BLEND)功能,设置好glBlendFunc函数后,就表示在之后的绘制物体完成后将最终生成混合的效果。也许这部分是由图形硬件设备部分解决的也说不定呢。假如你看到了最后的这个Q&A环节,希望能得到你的指点,在此感激言谢。

openGL/ESv2 通过JNI的简单示例代码 //OpenGLES2.0code#includenativehelper/jni.h#defineLOG_TAG"GL2JNIgl_code.cpp"#includeutils/Log.h#includeEGL/egl.h#includeGLES2/gl2.h#includeGLES2/gl2ext.h#includestdio.h#includestdlib.h#includemath.hst

glCopyBufferSubData glCopyBufferSubDataglCopyBufferSubData将数据从一个缓冲区拷贝到另一个缓冲区函数原型:voidglCopyBufferSubData(GLenumreadTarget,GLenumwriteTarget,GLintptrreadOffset,GLintptrwriteOf

glUnmapBuffer glUnmapBufferglUnmapBuffer释放缓冲区对象与客户端地址空间的关系GLbooleanglUnmapBuffer(GLenumtarget);参数:target:指定了缓冲区的类型,具体类型可以参考glBufferDat

标签: opengl调色

本文链接地址:https://www.jiuchutong.com/biancheng/369445.html 转载请保留说明!

上一篇:在mingw/GNU上编译opengl代码问题(mingw 编译)

下一篇:openGL/ESv2 通过JNI的简单示例代码(opengl es programming guide)

  • 一般纳税人增值税税率
  • 私立幼儿园需要纳税吗
  • 增值税纳税申报时间
  • 外商投资企业要实缴资本么
  • 出口免税收入的计税依据
  • 货物运输印花税减免
  • 高速公路费如何冲抵
  • 公司买的电器可以抵扣吗
  • 营业外收入缴纳税款
  • 怎么在网站上打印
  • 如何合理把公司的钱拿出来
  • 年末发票
  • 质量保证金的预留比例是多少
  • 购买固定资产未收到发票怎么办
  • 停车场需要对车辆负责吗
  • 国税发200931号文件解读
  • 应扣缴税额是什么意思
  • 递延所得税企业合并
  • 电子发票收款人和复核人可以是一个人吗
  • 有未分配利润就有盈余返还吗?
  • 个税缴纳期数填1是什么意思
  • 实收资本的账务处理例题
  • 进口商品关税调整
  • centos7安装部署cacti教程
  • 未分配利润怎么消化掉 避开所得税
  • 计提本月应付的租金
  • wifi信号弱了
  • uniapp怎么做适配
  • 蒙特城堡干红葡萄酒价格
  • Spring Security(七)-- AuthenticationProvider
  • openlayers6教程
  • 好家伙41集
  • Github ChatGPT-Web:了解最新AI技术的前沿应用!
  • tsar命令 收集服务器系统信息
  • 自查补缴增值税附表一怎么填写
  • 残保金计税基数是什么
  • 进项大于销项怎么结转增值税
  • mysql5.7设置编码
  • 收到汇算清缴的退税需要交税吗
  • 非房地产企业的基建管理办法
  • 购买固定资产会计凭证
  • 汇算清缴利润调增70万会预警吗
  • 小规模减免的增值税
  • 主营业务成本的增加在哪一方
  • 公司不注销会坐牢吗
  • 律师事务所账务处理例题
  • 专项应付款如何核算
  • 申购费从哪里扣
  • 融资租赁首付款的性质
  • 单位缴纳的社保计入什么科目
  • 一般纳税人购入固定资产进项抵扣
  • 个体从业人数怎么填
  • 会计凭证传递的基本要求
  • 公司买车贷款要看法人征信吗
  • 提供劳务的收入计入什么科目
  • mysql a.
  • sql server连接方式
  • sql server如何进行安全设置
  • linux软件安装源
  • win8 preparing automatic repair
  • linux 的ll
  • vb.net with
  • Win10预览版怎么变回正式版
  • win10系统回收站损坏了怎么恢复
  • windows重置网卡cmd
  • linux bin和sbin
  • linux日志内容
  • Windows7 64位系统如何添加打印机图文教程
  • linux安全工具
  • 使用jquery实现的项目
  • Apache服务器的安全缺陷
  • sed查找字符串
  • shell脚本中判断grep的结果
  • unity behavior designer
  • 请不要重复犯我在学习Python和Linux系统上的错误
  • jquery 设置css
  • jQuery中text() val()和html()的区别实例详解
  • JavaScript的Number对象的toString()方法
  • 国家税务局何时上班
  • 长春税务局待遇如何
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设