位置: 编程技术 - 正文

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)

  • 专票税号不对可以认证吗
  • 免租期租金怎么处理
  • 收到外境来电
  • 开房租租赁发票怎么记账
  • 装水表财务是什么费用
  • 小微企业十万免税从什么时候开始
  • 企业筹办期间可以贷款吗
  • 企业丢失账簿稽查局可以处罚吗
  • 固定资产后续支出
  • 存货可变现净值与成本孰低 考虑销量吗
  • 股东转账实收资本怎么填
  • 仓库的数量为负数怎么办
  • 税务稽查补缴的税款怎么处理
  • 营改增后增值税专用发票抵扣规定
  • 建材公司将自产产品卖出
  • 事业单位开发成本占比
  • 行政事业单位如何加强内部控制
  • 出口企业出口退税
  • win10为什么毛病这么多
  • 实收资本或股本账户属于企业的什么账
  • 股份公司注销流程及费用
  • 电脑主板bios设置
  • 报销金额和发票金额不一致怎么做账
  • win11dev预览修复工具
  • 微软手机
  • 一般纳税人购进农产品如何抵扣进项税额
  • 收入的特征包括什么
  • 用友结算成本处理的作用
  • 货运代理开票
  • 小企业成本管理方法
  • 今日除夕吉时
  • laravel 5.3中自定义加密服务的方案详解
  • 有利润但不交企业所得税
  • docker-p
  • cvpr best
  • gpt3 模型大小
  • 利用php抓取蜘蛛网
  • 应付款项怎么填列
  • 命令行窗口
  • 营改增后增加了什么征税项目
  • 工程结算期末有余额吗?
  • 资产减值损失是什么意思
  • 利用职务之便谋取私利是什么罪
  • 销售自己使用过的物品
  • 支付债券发行费怎么算
  • 餐饮发票要钱吗
  • 金蝶可以自动结转增值税吗
  • PostgreSQL教程(十):性能提升技巧
  • mysql错误代码1067
  • 收到企业所得税汇算清缴退税账务处理
  • 计提税金如何做凭证
  • 出口退税相关税法文件
  • 收到费用发票分录
  • 开外经证怎么预约办理
  • 已抵扣的进项税额转出会计分录账务处理
  • 国外公司与国内公司签约
  • 接受捐赠的固定资产计入什么科目
  • 投标保证金分为几种
  • 应纳税额与应纳所得额
  • 怎么从会计小白做到总账会计
  • 什么叫建账
  • 银行本票具体操作流程
  • 深入浅出了解啥意思
  • ubuntu安装软件教程
  • linux命令放在哪个路径
  • win10系统jdk环境变量
  • 支持iphone
  • win10周年更新版是什么意思
  • 开源镜像下载到本地
  • cocos2d schedule
  • jquery easy ui
  • Unity3D游戏开发(第2版)
  • js几种类型
  • 快速排序的算法流程图
  • 新疆地方税务局举报电话
  • 资源税的征税范围一般包括
  • 重庆税务总局发票查询
  • 消费发票上的金额含税吗
  • 工商年检报告书怎么打印
  • 河南省2020年12月纳税申报截止日期
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设