1.混合2D

Blend 混合是将源色和目标色以某种方式混合生成特效的技术。混合常用来绘制透明或半透明的物体。在混合中起关键作用的α值实际上是将源色和目标色按给定比率进行混合,以达到不同程度的透明。α值为0则完全透明,α值为1则完全不透明。混合操作只能在RGBA模式下进行,颜色索引模式下无法指定α值。物体的绘制顺序会影响到OpenGL的混合处理。

glEnable( GL_BLEND );   // 启用混合
glDisable( GL_BLEND );  // 禁用关闭混合

glBlendFunc( GLenum sfactor , GLenum dfactor );  // 混合函数
sfactor 源混合因子
dfactor 目标混合因子

glBlendFunc( GL_ONE , GL_ZERO );        // 源色将覆盖目标色
glBlendFunc( GL_ZERO , GL_ONE );        // 目标色将覆盖源色
glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ); // 是最常使用的

例如:

若源色为 ( 1.0 , 0.9 , 0.7 , 0.8 )。源色使用 GL_SRC_ALPHA
即 0.8*1.0 , 0.8*0.9 , 0.8*0.8 , 0.8*0.7
结果为 0.8 , 0.72 , 0.64 , 0.56
目标色为 ( 0.6 , 0.5 , 0.4 , 0.3 )。目标色使用GL_ONE_MINUS_SRC_ALPHA
即 1 - 0.8 = 0.2  0.2*0.6 , 0.2*0.5 , 0.2*0.4 , 0.2*0.3
结果为 0.12 , 0.1 , 0.08 , 0.06

由此而见,使用这个混合函数,源色的α值决定了结果颜色的百分比。
这里源色的α值为0.8,即结果颜色中源色占80%,目标色占20%。

2.混合3D

混合3D物体时,基本原理和混合2D物体一样,但需要将深度检测关闭或设置为只读
因为深度检测会剔除被遮挡的部分物体。
glEnable( GL_DEPTH_TEST );          // 启用深度缓存
glDisable( GL_DEPTH_TEST );         // 禁用深度缓存
glDepthMask( GL_FALSE );            // 深度缓存为 只读
glDepthMask( GL_TRUE );             // 深度缓存为 读/写

按以下步骤,可以在 3D 场景中使用混合和深度检测
1、使用深度检测
2、绘制不透明的物体
3、设只读 深度检测
4、绘制半透明的物体
5、设 读/写 深度检测

3.编程实践

#include <GL/glut.h>
#include <stdlib.h>static int leftFirst = GL_TRUE;static void init(void)
{glEnable (GL_BLEND);glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//glBlendFunc(GL_ONE, GL_ONE);   //禁用混合功能glShadeModel (GL_FLAT);glClearColor (0.0, 0.0, 0.0, 0.0);
}static void drawLeftTriangle(void)
{glBegin (GL_TRIANGLES);glColor4f(1.0, 0.0, 0.0, 0.55);glVertex3f(0.1, 0.9, 0.0); glVertex3f(0.1, 0.1, 0.0); glVertex3f(0.7, 0.5, 0.0); glEnd();
}static void drawRightTriangle(void)
{glBegin (GL_TRIANGLES);glColor4f(0.0, 1.0, 0.0, 0.55);glVertex3f(0.9, 0.9, 0.0); glVertex3f(0.3, 0.5, 0.0); glVertex3f(0.9, 0.1, 0.0); glEnd();
}void display(void)
{glClear(GL_COLOR_BUFFER_BIT);if (leftFirst) {drawLeftTriangle();drawRightTriangle();}else {drawRightTriangle();drawLeftTriangle();}glFlush();
}void reshape(int w, int h)
{glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h) gluOrtho2D (0.0, 1.0, 0.0, 1.0*(GLfloat)h/(GLfloat)w);else gluOrtho2D (0.0, 1.0*(GLfloat)w/(GLfloat)h, 0.0, 1.0);
}void keyboard(unsigned char key, int x, int y)
{switch (key) {case 't':case 'T':leftFirst = !leftFirst;glutPostRedisplay();    break;default:break;}
}int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (200, 200);glutCreateWindow (argv[0]);init();glutReshapeFunc (reshape);glutKeyboardFunc(keyboard);glutDisplayFunc (display);glutMainLoop();return 0;
}

输出结果如下:

   

左图为关闭“Blend”结果。右图为开启“Blend”结果。

OpenGL编程指南14:混合半透明Blend相关推荐

  1. 《OpenGL编程指南》一第2章 着色器基础

    本节书摘来自华章出版社<OpenGL编程指南>一书中的第2章,作者 Bill Licea-Kane ,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第2章 着色 ...

  2. OpenGL编程指南7:视图-

    1.前言 计算机图形学的要点就是创建三维物体的二维图像(图像必须是二维的,因为他是在平面的屏幕上显示的).但是,当我们决定怎样在屏幕上绘图时,必须使用三维坐标的方式考虑. 为了把一个物体的三维坐标变成 ...

  3. OpenGL编程指南5:学习绘制不同风格的曲线

    1.不同风格曲线绘制 #include <vgl.h> //宏定义;当定义的宏不能用一行表达完整时,可以用"\"表示下一行继续 #define drawOneLine( ...

  4. OpenGL编程指南4:双缓冲实现运行

    1.前言 绘制一个旋转的方块,主要为了说明glutSwapBuffers()函数的用法. 同时也为了学习如何使用GLUT控制输入设备,并打开或关闭空闲处理函数. 2.OpenGL编程及程序剖析 /** ...

  5. OpenGL编程指南3:GLUT:OpenGL使用工具库

    1.前言 我们知道的,OpenGL包含了很多的渲染函数,这些函数的设计目的就是独立与任何窗口系统或操作系统.因此,他并没有包含打开窗口或者从键盘或鼠标读取事件的函数.遗憾的是,如果连最基本的打开窗口的 ...

  6. opengl编程指南第8版源码编译详细说明

    1. 到:https://github.com/openglredbook/examples 下载完全版的源码examples-master.zip,大小有131MB左右,不要下载缩略版的,否则\bi ...

  7. 《OpenGL编程指南(原书第8版)》——计算着色器

    原文  http://www.csdn.net/article/2014-11-21/2822754 主题 OpenGL 数学 概述 由于图形处理器每秒能够进行数以亿计次的计算,它已成为一种性能十分惊 ...

  8. 《OpenGL编程指南》一第3章 OpenGL绘制方式

    本节书摘来自华章出版社<OpenGL编程指南>一书中的第3章,作者 Bill Licea-Kane ,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第3章 Op ...

  9. 《OpenGL编程指南》一3.2 OpenGL缓存数据

    本节书摘来自华章出版社<OpenGL编程指南>一书中的第3章,第3.2节,作者 Bill Licea-Kane ,更多章节内容可以访问云栖社区"华章计算机"公众号查看 ...

最新文章

  1. http 301 和 302的区别
  2. 通过命令行启动 Microsoft File Transfer Manager
  3. android 得到毫秒时间戳,android – Location.getTime()总是返回没有毫秒的时间戳
  4. 把Hybris Commerce本地tomcat的keystore给本机的tomcat使用
  5. SpringMVC 生成json报 HTTP Status 406.错误的解决方法
  6. CSS之background-origin属性
  7. php csv转excel 双引号,PHP高效导出Excel(CSV)
  8. 【Kafka】Kafka Schema Registry 原理
  9. suse安装mysql_SuSE12安装MySQL5.7.22:编译安装方式、单实例
  10. mysql 小技巧
  11. 获取OlapConnection连接
  12. win10安装MySQL5.7教程,linux安装MySQL教程,SQLyog安装教程
  13. 图形编程技术笔记整理1.1-1.6
  14. 联通发布沃Phone,全球为之震动
  15. java-php-python-ssm网上拍卖系统计算机毕业设计
  16. [Luogu P3975] [TJOI2015]弦论
  17. Spring boot (21)多数据源引起的循环引用和AutoConfigureAfter失效的问题
  18. 【win11】关闭 Windows 安全中心中的Defender 防病毒保护
  19. Flink DataStream读写Kafka
  20. about hashCode again understand

热门文章

  1. 2、xen虚拟机的安装
  2. 快速开发平台业务表字段设置的用法
  3. C++中return语句的用法
  4. hdu 1255(线段树+离散化)
  5. NYOJ 359 Delete it 字符串处理
  6. hdu 2570 迷障(贪心)
  7. 代码审计之CVE-2018-7600-Drupal远程代码执行漏洞-Render API
  8. oracle 如何查看oracle数据库版本
  9. 卡常神器——register 与 快速读入输出
  10. JPA(二):HellWord工程