OpenGL超级宝典笔记——累积缓冲区与其他颜色操作
2019独角兽企业重金招聘Python工程师标准>>>
累积缓冲区
OpenGL除了颜色缓冲区、深度缓冲区、模板缓冲区之外,还有累积缓冲区。累积缓冲区允许你把渲染到颜色缓冲区的值,拷贝到累积缓冲区。在多次拷贝操作到累积缓冲区时,可以用不同方式的把颜色缓冲区内容和当前累积缓冲区的内容进行重复混合。当在累积缓冲区完成一幅图像之后,可以拷回颜色缓冲区,然后通过SwapBuffers显示到屏幕上。
累积缓冲区的操作通过void glAccum(GLenum op, GLfloat value);控制。第一个参数表示对累积缓冲区所进行的操作。第二个参数是浮点数用于指定缩放因子。
OpenGL支持的累积缓冲区的操作如下表:
操作 | 描述 |
GL_ACCUM | 把颜色缓冲区的颜色值进行缩放后,累加到累积缓冲区 |
GL_LOAD | 把颜色缓冲区的颜色值进行缩放后,替换掉累积缓冲区的颜色值 |
GL_RETURN | 把累积缓冲区的颜色值缩放后,拷贝回颜色缓冲区 |
GL_MULT | 把累积缓冲区的颜色值缩放后,替换掉原累积缓冲区的颜色值 |
GL_ADD | 把累积缓冲区的颜色值缩放后,累加到累积缓冲区 |
由于累积缓冲区会带来大内存的开销,所以在实时应用程序中比较少用。但在非实时的应用程序中,可以产生实时应用程序无法做到的效果。例如,你可以多次渲染场景,并在每次渲染时进行抖动零点几个像素,这样就可以产生整个场景的反走样的效果,比多重采样的效果还要好。还可以模糊前景或背景,然后清晰的渲染一个物体来模拟,照相机景深的效果。
下面的例子是一个球体在地板上滚动,运动模糊的效果。
#include "gltools.h"
GLfloat fLightPos[4] = { -100.0f, 100.0f, 50.0f, 1.0f }; GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 0.0f };GLfloat fLowLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat yRot;
void DrawGround(){ GLfloat fExtent = 20.0f; GLfloat y = -0.0f; GLfloat step = 0.5f;
GLfloat x, z;int iColor = 0; glShadeModel(GL_FLAT);for (x = -fExtent; x <= fExtent; x += step) { glBegin(GL_TRIANGLE_STRIP);for (z = fExtent; z >= -fExtent; z -= step) {if ((iColor % 2) == 0) { glColor4f(0.0f, 0.0f, 0.0f, 0.5f); }else { glColor4f(1.0f, 1.0f, 1.0f, 0.5f); } glVertex3f(x, y, z); glVertex3f(x + step, y, z);
iColor++; } glEnd(); } glShadeModel(GL_SMOOTH);
}
void DrawGemometry(){ glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawGround();
glColor3f(1.0f, 0.0f, 0.0f); glTranslatef(0.0f, 0.3f, -3.5f); glRotatef(-yRot*2.0f, 0.0f, 1.0f, 0.0f); glTranslatef(1.0f, 0.0f, 0.0f); glutSolidSphere(0.1f, 17, 13); glPopMatrix();}
void RenderScene(){ yRot = 35.0f; GLfloat pass = 10.0f;for (int i = 0; i < 10; ++i) { yRot += 0.75f; DrawGemometry();
//复制到累积缓冲区if (i == 0) { glAccum(GL_LOAD, 0.5f); }else {//累加到累积缓冲区 glAccum(GL_ACCUM, (0.5f * 1 / pass)); } }
glAccum(GL_RETURN, 1.0f); glutSwapBuffers();}
void ChangeSize(GLsizei w, GLsizei h){if (h == 0) h = 1;
glViewport(0, 0, w, h);
GLfloat faspect = (GLfloat)w/(GLfloat)h;
glMatrixMode(GL_PROJECTION); glLoadIdentity();
gluPerspective(35.0f, faspect, 1.0f, 50.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, -0.4f, 0.0f);
glutPostRedisplay();}
void SetupRC(){ glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW);
//设置光照 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glLightfv(GL_LIGHT0, GL_POSITION, fLightPos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
//开启颜色追踪 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128);}
int main(int args, char **argv){ glutInit(&args, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ACCUM); glutInitWindowSize(800, 600); glutCreateWindow("motion blur");
glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();return 0;}
DrawGeometry函数绘制了场景中的所有几何图元。在RenderScene中反复调用这个函数,并把结果累积到累积缓冲区中。在最后,拷贝回到颜色缓冲区,然后glutSwapBuffers显示到屏幕上:
其他颜色操作
颜色掩码
在计算后的最终颜色将要写入到颜色缓冲区时,OpenGL允许你通过glColorMask函数来屏蔽掉其中的一个或多个通道值。
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
参数分别代表红、绿、蓝、alpha通道。当传的参数是GL_TRUE时,表示允许往这个通道的写值,如果为GL_FALSE则阻止往该通道写值。
颜色逻辑操作
许多2D的图形API允许源颜色和目的颜色进行逻辑操作。OpenGL也支持这种操作:
void glLogicOp(GLenum op);
还需要通过glEnable(GL_COLOR_LOGIC_OP);来开启。OpenGL在默认情况下是关闭的。关闭操作是相应的glDisable
op允许的操作如下表:
参数值 | 操作 |
GL_CLEAR | 0 |
GL_AND | s & d |
GL_AND_REVERSE | s & ~d |
GL_COPY | s |
GL_AND_INVERTED | ~s & d |
NOOP | d |
XOR | s xor d |
OR | s | d |
NOR | ~(s | d) |
GL_EQUIV | ~(s xor d) |
GL_OR_REVERSE | s | ~d |
GL_COPY_INVERTED | ~s |
GL_OR_INVERTED | ~s | d |
GL_NAND | ~(s & d) |
SET | all 1s |
Alpha 测试
Alpha测试允许你告诉OpenGL那些在Alpha测试不通过的输入片段将被废弃。那些被废弃的片段不会写入到颜色缓冲区,深度缓冲区,模板缓冲区和累积缓冲区中。那些alpha值很低的片段可能是不可见的,因此我们可以过滤掉它,不写入到缓冲区中,可以提高性能。
alpha测试值和比较函数可以通过glAlphaFunc指定:
void glAlphaFunc(GLenum func, GLclampf ref);
ref的取值范围为[0.0, 1.0].可以指定的比较方式如下表:
比较方式 | 描述 |
GL_NEVER | 永远不通过 |
GL_ALWAYS | 一直通过 |
GL_LESS | 小于ref |
GL_LEQUAL | 小于等于ref |
GL_EQUAL | 等于ref |
GL_GEQUAL | 大于等于ref |
GL_GREATER | 大于ref |
GL_NOTEQUAL | 不等于ref |
行为与glDepthFunc函数相似。可以通过glEnable/glDisable来开启和关闭alpha测试,参数值是GL_ALPHA_TEST。
抖动
抖动允许只有少量离散颜色的显示系统来模拟更宽范围的颜色。例如,灰色可以通过白点和黑点的混合来模拟。白点多于黑点呈现浅灰色,黑点多于白点呈现深灰色。这种技巧对于只支持8位和16位的显示系统非常有用。抖动的效果可以大幅度地改善低端颜色系统的图像质量。在默认情况下,抖动是打开的。可以通过glEnable(GL_DITHER)/glDisable(GL_DITHER)来打开或关闭它。在高颜色分辨率的显示系统中,OpenGL的实现可能不需要抖动,会禁用抖动来避免性能的开销。
转载于:https://my.oschina.net/sweetdark/blog/172316
OpenGL超级宝典笔记——累积缓冲区与其他颜色操作相关推荐
- OpenGL超级宝典笔记——遮挡查询 [转]
目录[-] 遮挡查询之前 包围体 遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率.遮挡查询就是 ...
- Opengl超级宝典笔记——空间绘图画点
2019独角兽企业重金招聘Python工程师标准>>> <h2>3D概念</h2> <ol> <li>像素,计算机显示器中的最小元素. ...
- 【转】OpenGL超级宝典笔记——纹理映射Mipmap
原文地址 http://my.oschina.net/sweetdark/blog/177812 , 感谢作者,若非法转载请联系本人. 目录[-] Mipmapping Mipmap过滤 构建Mip层 ...
- OpenGL超级宝典笔记——光照参数与材料属性
2019独角兽企业重金招聘Python工程师标准>>> <h3>添加光照</h3> <p>glEnable(GL_LIGHTING);</p ...
- OpenGL 超级宝典笔记 —— 纹理高级(一)
辅助颜色 一般情况下,我们设置纹理的环境为 GL_MODULATE 模式,在这种情况下,受到光照的几何图形会和纹理的颜色进行结合.正常情况下,OpenGL 进行光照计算,并根据标准的光照模型进行单个片 ...
- OpenGL 超级宝典笔记 —— 雾
应用雾 雾是 OpenGL 支持的一种易于使用的特殊效果.在使用雾时,OpenGL 把雾的颜色与完成所有其他颜色计算的几何图元进行混合.雾与几何图元的混合程度取决于几何图元离观察者的距离.雾可以使物体 ...
- OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28
OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28 文章目录 OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 ...
- OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13
OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13 文章目录 OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13 1 帧缓存运算 1.1 裁剪测 ...
- OpenGL超级宝典学习笔记——操作矩阵
为了更强大的功能和灵活性,我们有时需要直接操作矩阵.在OpenGL中4x4的矩阵用包含16个浮点数值的一维数组来表示,而不是用二维的4x4的数组来表示.OpenGL之所以这么做,因为使用一维数组更高效 ...
最新文章
- python opencv local_threshold_Python-OpenCV中的cv2.threshold
- 【原创】A进程窗口嵌入到B进程窗口中显示
- 8种相似度度量方式的原理及实现【笔记自用】【1】
- Unite 2018 | 浅谈伽玛和线性颜色空间
- mysql数据库的系统操作基本操作
- mysql 检查_检查MySQL的健康状况
- mysql2005本地连接_sql2005连接配置详细图解
- android 指定进程名称,android 根据进程名杀死指定、特定进程
- elastic-job 新手指南官网指南
- 实习分享 | 来康康字节小姐姐的经验
- iOS和安卓合并二维码
- C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)
- 【0304】密码分类
- android 手机查看分辨率,adb命令查看报名和查看手机分辨率
- 微服务项目架构演变过程
- 《Go语言精进之路,从新手到高手的编程思想、方法和技巧1》读书笔记和分享
- 播放器地址抓取 php,从优酷土豆视频地址中获取swf播放器分享地址 - PHP示例代码...
- ATmega16开发板教程(2)——KEY点灯
- 解决iOS下拉回弹方法二
- 力天创见智慧客流方案
热门文章
- jsp中如何运行java_从上帝视角看Java如何运行
- python t检验_A or B A/B测试-python独立双样本t检验
- python运维面试题_PYTHON运维开发面试题整理
- 获取远程数据本地缓存到PHP数组
- 性能优化技巧 - 内存关联计算
- Nginx强制https访问
- Linux学习之CentOS(三十四)--配置域主DNS服务器
- 安装CDH5时出错 5.68.168.192.in-addr.arpa domain name pointer bogon.
- [tomcat7源码学习]结束Bootstrap进入Catalina
- JBoss Seam 3.0.0.Beta2 发布