位置: 编程技术 - 正文

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)

  • 没有发票就不能入账吗
  • 公司出售厂房需要交哪些税
  • 进项税为什么记在借方通俗讲法
  • 企业所得税怎么缴纳
  • 基本账户转到一类卡
  • 一般纳税人企业是什么意思
  • 盈亏平衡点产量越高,项目风险越大
  • 房地产企业收到预收款如何纳税
  • 服务费和佣金的关系
  • 公司为职工在异地买医保
  • 货车挂靠企业需要交增值税吗?
  • 周年庆典布置现场
  • 补缴的以前年度的税费及滞纳金用更正申报企业所得税吗
  • 销售固定资产可以开专票吗
  • 企业每月纳税申报流程
  • 职工福利费当年怎么扣
  • 未在规定期限内发出追索通知
  • 收到退以前年度教育费附加税
  • 建筑材料增值税税率
  • 尚未开发的土地使用权摊销
  • 进项留抵退税会计科目
  • 各行业增值税税负率表2022年
  • 法院执行款可以开发票吗
  • 税控盘提示未抄报税
  • 公司购买进口产成品关税会计分录怎么做?
  • 华为鸿蒙双击背面打开健康码
  • 劳务人员劳务费
  • deepin怎么使用
  • Win7系统如何创建宽带连接
  • 银行承兑汇票开出后多久可以签收
  • PHP:Memcached::getAllKeys()的用法_Memcached类
  • 商业企业低值易耗品科目核算的内容
  • 税收保全有哪些
  • 外资企业股权转让给外资企业
  • windows7电脑时间不对
  • 劳务公司账务处理办法
  • 毛地黄长什么样
  • zendstudio怎么创建php项目
  • 利息增值税及附加计算
  • ssm框架集成
  • 【AutoGPT】你自己运行,我先睡了—— ChatGPT过时了吗?
  • des算法加密解密过程
  • thinkphp钩子场景
  • Laravel5中防止XSS跨站攻击的方法
  • 微服务组件面试题
  • 企业所得税能否票据入账
  • 冲以前年度成本分录
  • 公司租赁车辆的保险费可以扣除
  • 阿里云ecs重装
  • python generation
  • 11-ElementUI
  • 一万元,两分的利息,一年利息是多少
  • 固定资产入账原值含税价吗
  • 公墓造价成本
  • 纳税申报人的对象是哪些
  • 其他应收款审计说明怎么写
  • 建筑业 分包
  • 已付款未收到货怎么办
  • 厂房的使用寿命
  • windowsxp电脑开机
  • Win10系统如何打开任务管理器
  • ie11打不开闪退解决办法win 7
  • 微软推送win11
  • cocos2dx运行原理
  • js中不用var声明
  • jquery异步获取数据
  • perl cgi
  • javascript运算
  • 用shell脚本实现菜单页面
  • 编写批处理
  • unity字符串
  • 配置ip地址的方法有哪几种
  • js实现兼容性较好的方法
  • jquery操作文本可以使用什么方法
  • javascript图片
  • jquery动态改变样式
  • python模拟ajax
  • 小规模税控盘服务费怎么填增值税申报表
  • 营业税发票现在可以冲红么
  • 企业筹建期间发生的费用应计入什么账户
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设