write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
人类所有的力量 ,只是耐心加上时间的混合。 —— 巴尔扎克
混合的力量是很强大的,就如巴尔扎克所言,而图形处理中很多有趣且实用的效果在OpenGL中其实都可以用混合来实现,比如最最常用的半透明效果,这种效果在compiz的3D桌面效果中得到了极致的发挥,让人印象深刻,即使你从来不使用Linux,你也可以去看看很多人秀自己Linux桌面效果的视频,要知道,这效果出来的时候,连Vista都还不知道在哪。呵呵,可惜的是,一个桌面系统好不好,不仅仅是靠谁更炫来比较的。。。。。
概念
在OpenGL中混合是指啥?就如混合的一般意义一样,混合在OpenGL中指的是两个图形的组合,只不过这个组合的方式可以以很多种方式定义罢了。混合是属于那种概念较为简单,相关的接口不算太多,但是因为可定制内容较多,所以参数复杂,而且,利用各个参数的含义简单,但是要知道在什么时候使用什么样的参数却不简单的那类概念,与光照同类。
现实生活中最常见的例子就是透过玻璃看一个东西了,你看到的图像实际是玻璃反射的光和玻璃后物体反射的光穿过玻璃后在眼睛中一起形成的图像,在OpenGL中被描述成玻璃后物体反射的光与玻璃反射的光混合后产生的图像。
alpha这个以前我们一直没有使用的值在混合中发挥着关键的作用,一般我们将其称作透明度,但是事实上,在混合时,此值可以作为更多的用途,当然,仅仅作为透明度使用也完全没有问题。
出于对思维导图的兴趣,还是来个图:
使用
在OpenGL中,将新片段成为源,将已经存在的图形成为目标,使用时先通过glBlendFunc{Separate}指定如何计算源和目标的混合因子,然后通过glBlendEquation{Separate}指定如何混合(即指定混合模式),使用的步骤相当简单,除了按照惯例需要用glEnable(GL_BLEND)启用外,也就这两步,第二步还是在OpenGL 1.2中才加入的,原来只能为加模式,现在在我们忽略第二步时,默认使用加模式。其中附加Separate的函数表示分别指定RGB与alpha值。
《OpenGL Programming Guide
》:
glBlendFunc — specify pixel arithmetic
C Specification
void glBlendFunc( GLenum sfactor,
GLenum dfactor);
Parameters
sfactor
Specifies how the red, green, blue,
and alpha source blending factors are computed.
The following symbolic constants are accepted:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_CONSTANT_COLOR,
GL_ONE_MINUS_CONSTANT_COLOR,
GL_CONSTANT_ALPHA,
GL_ONE_MINUS_CONSTANT_ALPHA, and
GL_SRC_ALPHA_SATURATE.
The initial value is GL_ONE.
dfactor
Specifies how the red, green, blue,
and alpha destination blending factors are computed.
The following symbolic constants are accepted:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA.
GL_CONSTANT_COLOR,
GL_ONE_MINUS_CONSTANT_COLOR,
GL_CONSTANT_ALPHA, and
GL_ONE_MINUS_CONSTANT_ALPHA.
The initial value is GL_ZERO.
glBlendEquation — specify the equation used for both the RGB blend equation and the Alpha blend equation
C Specification
void glBlendEquation( GLenum mode);
Parameters
mode
specifies how source and destination colors are combined.
It must be GL_FUNC_ADD, GL_FUNC_SUBTRACT,
GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX.
的确,简单的使用真的是非常简单,(虽然参数的组合可以很多)事实上,见下例,仅仅那么几行代码,就实现了一个半透明效果。
//OpenGL初始化开始
void
SceneInit(int
w,int
h)
{
GLenum err = glewInit();
if
(err != GLEW_OK)
{
MessageBox(NULL, _T("Error"
), _T("Glew init failed."
), MB_OK);
exit(-1);
}
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR);
}
void
DrawSmoothColorPyramid(GLfloat adSize)
{
static
GLfloat fPyramidDatas[] = { 0.0, 1.0, 0.0, // 三角锥上顶点
-1.0, 0.0, 1.0, // 底面左前顶点
1.0, 0.0, 1.0, // 底面右前下顶点
0.0, 0.0, -1.0}; // 底面后下顶点
GLfloat fPyramidSizeDatas[sizeof
(fPyramidDatas)/sizeof
(GLfloat)] = {0};
// 计算大小
for
( int
i = 0; i < 12; ++i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}
static
GLfloat fPyramidColors[] = { 0.0, 0.0, 0.0, 0.7,
1.0, 0.0, 0.0, 0.7,
0.0, 1.0, 0.0, 0.7,
0.0, 0.0, 1.0, 0.7};
static
GLubyte ubyIndices[] = { 0, 1, 2, // 正面
0, 3, 1, // 左侧面
0, 2, 3, // 右侧面
1, 3, 2}; // 底面
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, fPyramidSizeDatas);
glColorPointer(4, GL_FLOAT, 0, fPyramidColors);
for
(int
i = 0; i < 4; ++i)
{
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, ubyIndices+i*3);
}
}
//这里进行所有的绘图工作
void
SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
DrawSmoothColorPyramid(0.5);
DrawSmoothColorPyramid(1);
glPopMatrix();
glLoadIdentity();
gluLookAt(gViewPosX, gViewPosY, gViewPosZ, gViewDirX, gViewDirY, gViewDirZ, gViewUpDirX, gViewUpDirY, gViewUpDirZ);
glFlush();
}
此例是从原来的2009-10-25/glCullFace改过来的,基本思路是在一个小的三角锥外再画一个大的三角锥,即如下几句:
glPushMatrix
();
DrawSmoothColorPyramid
(0.5);
DrawSmoothColorPyramid
(1);
glPopMatrix
();
除此外,新添的关键代码就是
glEnable
(GL_BLEND
);
glBlendFunc
(GL_SRC_ALPHA
, GL_DST_COLOR
);
两句了,分别是开启混合,并将混合的因子设为源混合因子使用RGB+alpha值,目标混合因子颜色即原颜色,并且,我们使用了默认的混合加模式。很简单吧?就两句代码而已。
另外,特别注意的是,此时我在颜色数组中添加进了alpha参数(原来没有)
static GLfloat fPyramidColors[] = { 0.0, 0.0, 0.0, 0.7,
1.0, 0.0, 0.0, 0.7,
0.0, 1.0, 0.0, 0.7,
0.0, 0.0, 1.0, 0.7};
此时表示三角锥的颜色alpha值为0.7.
我们看看实现的半透明效果是怎么样的。
先看左边的截图,根本看不到小的三角锥,原因很明显,因为外面的三角锥后绘制,将其内部先绘制的小三角锥完全的覆盖掉了,但是右边的截图我们清晰的看到了内部的小三角锥,呵呵,因为我们启用了半透明效果(用混合实现)嘛。
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-11-11/glHalfTrans/ 目录,获取方式见文章最后关于获取博客完整源代码的说明。
自从决定以概念的讲解和演示为主后,本系列文章就像原来那样常常力图展示所有参数的概念和效果了,此处对混合的使用可以说是最最简单的了,我甚至都没有去调用glBlendEquation{Separate}函数,但是实际的使用可以相当复杂,各个参数的作用大家就去参考《OpenGL Programming Guide
》罗:)
本系列其他文章见OpenGL专题 《Win32 OpenGL系列专题
》
参考资料
1. 《OpenGL Reference Manual
》,OpenGL参考手册
2. 《OpenGL
编程指南》(《OpenGL Programming Guide
》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis
著,徐波译,机械工业出版社
3. 《Nehe OpenGL Tutorials》,Nehe著,在http://nehe.gamedev.net/
上可以找到教程及相关的代码下载,(有PDF版本教程下载)Nehe自己还做了一个面向对象的框架,作为演示程序来说,这样的框架非常合适。也有中文版
,各取所需吧。
4. 《OpenGL入门学习》 ,eastcowboy著,这是我在网上找到的一个比较好的教程,较为完善,而且非常通俗。这是第一篇的地址:http://bbs.pfan.cn/post-184355.html
完整源代码获取说明
由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:
https://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门
》
要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:
http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
自做的opengl半透明效果,其中还包含obj模型加载,mipmap纹理。因为要有一个场景演示半透明效果;半透明效果给出了两种不同的混合因子的效果。
Android端使用OpenGL ES 2.0 实现的入门版混合半透明效果demo
OpenGL Win32 OpenGL Win32 OpenGL Win32
OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合OpenGL 混合...
WIN32 opengl环境搭建
opengl1.0 win32的一些例子,完全是win32底层写,只依赖基本的OpenGL库,win32创建窗口 比较底层适合学习
WIN32 opengl缩放图形。VS2012
WIN32 opengl三角形绘制。VS2012
第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章...
OpenGL编程精粹.pdf
OpenGL编程进阶 OpenGL编程进阶 OpenGL编程进阶 OpenGL编程进阶
所有学习资料(win32 opengl html)全部是chm格式
OpenGL 编程指南 第七版 源码 红宝书源码,未经任何修改
1. 绘制若干个透明和非透明茶壶,并体现出它们之间正确的混合效果; 考察目的: 1. OpenGL 中 alpha 混合的使用; 2. 混合绘制透明和不透明物体的正确方法; 3. 运算符的重载和基本 STL 的使用;
OpenGL编程指南 第8版 高清 中文 完整版,PDF格式的。是目前网络上最清晰的完整版本。这本书是学习OpenGl的必备资料,非常好的书。 由Khronos小组编写的官方指南,OpenGL领域的权威著作,素有“OpenGL红宝书”美誉...
win32 opengl画线。配置好了glut.h。vs2012
OpenGL编程指南第八版高清中文完整版 OpenGL编程指南第八版高清中文完整版