OpenGL 红宝书 混合

6.1 混合

6.1.1 源因子和目标因子

假定源和目标混合因子分别为(Sr, Sg, Sb, Sa)和(Dr,Dg,Db,Da), 混合后的RGB值如下:

(RsSr + RdDr, GsSg + GdDg, BsSb + BdDb, AsSa + AdDa)

最后,将该四元组的各个分量截取到[0,1].

将源片元和目标象素合并起来的默认方式是,将它们的值相加.

选择源混合因子和目标混合因子的方式:

第一种方式是调用函数glBlendFunc(),并指定两个混合因子, 其中第一个参数为源RGBA的混合因子, 第二个参数为目标RGBA的混合因子.

第二种方法是调用glBlendFuncSeparate()并指定4个混合因子, 这样可以用不同的方式来混合RGB和alpha值.

void glBlendFunc(GLenum srcfactor, GLenum destfactor);

srcfactor指出如何计算源混合因子; destfactor指出如何计算目标混合因子.

void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcalpha, GLenum destalpha);

源混合因子和目标混合因子

常量: RGB混合因子                alpha混合因子

GL_ZERO: (0, 0, 0)             0

GL_ONE: (1, 1, 1)               1

GL_DST_COLOR: (Rd, Gd, Bd)

GL_SRC_COLOR: (Rs, Gs, Bs)  A

GL_ONE_MINUS_DST_COLOR: (1, 1, 1) - (Rd, Gd, Bd)

GL_ONE_MINUS_SRC_COLOR: (1, 1, 1) - (Rs, Gs, Bs)    1 - A

GL_SRC_ALPHA: (As,As,As,As)

GL_ONE_MINUS_SRC_ALPHA: (1, 1, 1, 1) - (As,As,As,As)

GL_DST_ALPHA: (Ad, Ad, Ad, Ad)

GL_ONE_MINUS_DST_ALPHA: (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)

GL_SRC_ALPHA_STATURATE: (f, f, f, 1); f = min(As, 1 - Ad)

另将GL*CONSTANT*作为参数时, 需要使用glBlendColor()指定一个常量(constant)颜色

void glBlenColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

设置执行混合操作时使用的常量颜色的红,绿,蓝和alpha值(Rc, Gc, Bc, Ac)

6.1.2 启用混合操作

glEnable(GL_BLEND);

6.1.3 使用混合方程来合并像素

采用标准混合方式时, 将帧缓存中的颜色和输入片元的颜色合并起来, 得到新的帧缓存颜色.

void glBlendEquation(GLenum mode);

上面的函数用来指定其他数学运算,以计算帧缓存颜色和片元颜色的差, 它们中的最大值或最小值.

指定如何混合帧缓存中的颜色和片元颜色.

Cs和Cd表示源颜色和目标颜色, S和D表示函数glBlendFunc()或glBlendFuncSeparate()指定的源混合因子和目标混合因子.

GL_FUNC_ADD                                     CsS + CdD

GL_FUNC_SUBTRACT                          CsS - CdD

GL_FUNC_REVERSE_SUBTRACT       CdD - CsS

GL_MIN                                        min(CsS, CdD)

GL_MAX                                        max(CsS, CdD)

要使用OpenGL扩展代码

1. 增加头文件

#include <GL/glext.h>

2. 定义函数指针

PFNGLBLENDEQUATIONPROC glBlendEquation = NULL;        //定义函数指针

3. 在内存中找到函数地址

PFNGLBLENDEQUATIONPROC glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");

使用深度透视,重绘的时候要注意清除深度缓存,否则会消失.

6.1.4 混合的用途

1. 均匀地混合两幅图像:

首先将源因子和目标因子分别设置为GL_ONE和GL_ZERO. 并绘制第一副图像.

然后将源因子设置为GL_SRC_ALPHA, 目标因子设置为GL_ONE_MINUS_SRC_ALPHA, 并在绘制第二幅图像时使用alpha值0.5. 这是最常用的混合方式.

如要设置第一副图像占75%, 第二幅图像占25%. 可以在绘制第二幅图像使用alpha值0.25.

2. 均匀地混合三幅图像, 目标因子设置为GL_SRC_ALPHA, 然后使用alpha值 0.3333333绘制这些图像.这样每幅图像的亮度只有原来的三分之一.

3. 逐渐加深图像的颜色: 源混合因子和目标混合因子分别设置为GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA, 并将画笔的alpha值设置为0.1

4. 通过将源混合因子设置为GL_DST_COLOR或GL_ONE_MINUS_DST_COLOR.将目标混合因子设置为GL_SRC_COLOR或GL_ONE_MINUS_SRC_COLOR,可以分别调整各个颜色分量.

相当于使用一个简单的滤光器.

如红色分量乘以0.8,绿色分量乘以0.4,蓝色分量乘以0.72. 相当于滤光器滤掉20%的红光, 60%的绿光和28%的蓝光.

5. 纯色背景三个半透明面组成的图像.最远的透过其后80%的颜色, 接下来的面40%,最近的90%.

首先用默认的源混合因子和目标混合因子绘制背景

然后源混合因子和目标混合因子为GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA, 并依次是哟个alpha值0.2绘制最远的面,0.6绘制中间面,0.1绘制最近的面.

6. 如果系统有alpha位面, 可以每次渲染一个物体, 然后将它们读取到内存中, 然后对渲染后的物体执行有趣的合成操作.

7. 通过给图像中的片元指定不同的alpha值,可以实现非矩形光栅图像的效果.

透明片元的alpha值设置为0, 不透明片元的alpha值设置为1.0.

8. 混合也可以用于实现反走样.

6.1.5 一个混合的例子

6.1.6 使用深度缓存的三维混合

方法: 启用深度缓存, 并在绘制半透明物体时, 将深度缓存设置为只读的.

首先, 将深度缓存设置为正常状态, 并绘制所有的不透明物体, 然后将深度缓存设置为只读的, 并使这些深度值保持不变. 绘制半透明物体时,将深度同不透明物体的深度值进行比较,这样, 如果他们位于不透明物体后面,不绘制他们, 如果它们离视点更近, 也不会消除不透明物体, 因为深度缓存的值是无法修改的,而是与不透明物体混合在一起.

函数glDepthMask()可以控制深度缓存的读写状态. 参数GL_FALSE将深度缓存设置为只读. 参数GL_TRUE设置为可写.

http://www.cppblog.com/summericeyl/archive/2009/03/08/75941.html

OpenGL: 混合相关推荐

  1. OpenGL混合功能实例

    OpenGL 混合功能实例 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <sb7.h> #include <vmath.h& ...

  2. OpenGL 混合Blending

    OpenGL混合Blending 混合Blending简介 丢弃片段 混合 渲染半透明纹理 不要打乱顺序 混合Blending简介 OpenGL中,混合(Blending)通常是实现物体透明度(Tra ...

  3. Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染

    Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染 上一篇文章讲到了利用C++这个桥梁,我们实现了QML和Java的交互.Qt 5大力推崇的QML/JS开发,让轻量.高速开发的QML/J ...

  4. qt opengl 混合实现半透明

    在二维绘图里面的半透明很简单,把alpha通道的值不设置为1或者255就能看见后面的物体:后面物体的清晰度根据设置值的大小来决定.而在opengl中要实现半透明效果也很简单,但相比二维绘图还是要麻烦一 ...

  5. 11、OpenGL - 混合(颜色混合)

    混合 OpenGL 渲染时会把颜色存在颜色缓冲区中,每个片段的深度值也是放在深度缓冲区. 当深度缓冲区被关闭时,新的颜色将简单的覆盖原来颜色缓冲区存在的颜色值. 当深度缓冲区再次打开时,新的颜色片段只 ...

  6. Simens NX(原UG)与OpenGL混合开发 /Program with NX and OpenGL

    关于 NX3.0跟随点窗口的方法研究 作者:xusir98 程序主要过程 : 1. 找出 NX 视图的显示窗口 2. HOOK NX 视图的鼠标操作 3. 在 HOOK 的回调函数中利用 OPENGL ...

  7. qt android opengl,案例:实现Qt和OpenGL混合渲染 | 求索阁

    Qt自有一个绘图的引擎,这个引擎的核心就是QPainter,我们知道QPainter在渲染二维图形和文字有很大的优势,而OpenGL是当前流行的三维渲染器,怎样才能将两者结合起来,制作更为丰富的应用程 ...

  8. opengl 反走样 混合 多重采样 blend multisample

    1. 反走样         在光栅图形显示器上绘制非水平且非垂直的直线或多边形边界时,或多或少会呈现锯齿状或台阶状外观.这是因为直线.多边形.色彩边界等是连续的,而光栅则是由离散的点组成,在光栅显示 ...

  9. OpenGL入门学习(十二) 【转】

    片断测试其实就是测试每一个像素,只有通过测试的像素才会被绘制,没有通过测试的像素则不进行绘制.OpenGL提供了多种测试操作,利用这些操作可以实现一些特殊的效果. 我们在前面的课程中,曾经提到了&qu ...

最新文章

  1. jQuery使用手册
  2. VMware 虚拟化编程(8) — 多线程中的 VixDiskLib
  3. sqlite库——c语言实现匹配已知字符串中某个字段(该字段在其他表中),在其他表中获取值并显示
  4. ajax mysql点赞_ajax 实现点赞功能
  5. linux 之免交互操作
  6. 学习笔记(56):Python实战编程-Menu
  7. java 8 lambda_Java 8 Lambda演练
  8. tekla钢结构算量_Tekla有用吗?Tekla软件在钢结构项目中有什么作用?
  9. 微型计算机原理与接口技术(慕课版),微机原理与接口技术
  10. 维度表和事实表的区别
  11. PM3环境搭建和M1卡复制
  12. linux mysql免安装版配置_Linux下MySQL免安装版安装配置记录
  13. STM32比较器的使用
  14. 多线程_线程插队_join()方法与锁的释放
  15. Android Q 上的Biometric生物识别
  16. kanzi案例Coin
  17. bsy代码学习--微信网页授权
  18. C#预览(GOCAD)DWG文件方法
  19. JDK源码解析 - java.util.ArrayList
  20. ios python 越狱_iOS越狱--USB连接SSH

热门文章

  1. C# winform 问题百解(样式、datagridview(dgv)、json、http)
  2. ROS-RouterOS hAP ac2+usb 4G上网卡+小米新推的无线上网卡是绝配
  3. 螺吡喃(SP)和有色开环的部花菁结构(MC)光致变色示意图
  4. 实现网站常见的轮播图
  5. 北京大学CMA—让CMA考试更简单
  6. 「经典阅读」在职场,多少人输在了处关系上
  7. docker私有仓库,仓库管理器
  8. linux清理网卡流量,Linux实时显示网卡流量的工具nload
  9. html怎么编写化学符号,水的化学符号怎么写
  10. DIY中柏EZpad4s时尚版显示屏排线