OpenGL学习笔记(六)

龙云尧个人博客,转载请注明出处。

CSDN地址:http://blog.csdn.net/michael753951/article/details/71407260

个人blog地址:http://yaoyl.cn/nehexue-xi-bi-ji-liu-2017-05-08-13-54/


混合

我们在很多场合都过这样的经历,在设置某些色块的颜色的时候,我们不光要设置它的RGB值,还可能需要设置它的Alpha值。一般理解上,我们都认为这个Alpha值代表了当前色块的透明度。这样只是最外在的理解,其实图像的透明是一个颜色的混合过程,当有两种颜色混叠的时候,这个Alpha是用来控制两种颜色的混色程度的一种值。

颜色的混合公式为(Rs*As + Rd (1 - As), Gs*As + Gd (1 - As), Bs*As + Bs (1 - As), As*As + Ad (1 - As))。其中As表示前景色的Alpha值,Rs表示前景色的R值,Rd表示背景色的R值,Gs & Gd,Bs & Bd类似。最终计算出来的RGB值就是混合之后显示出来的RGB值。

举个例子,我们已经知道背景色是(255,255,255),现在有一个(128,128,128)的色块需要层叠在背景色块之上,并且我们先假设Alpha值为1.0,那我们很容易计算出来最终的显示的RGB值为(128,128,128),这个时候我们就从直观上认为前景色完全不透明。而如果Alpha为0.0,计算结果显然为(255,255,255),这个时候我们就认为前景色完全透明。其他的Alpha值类似。

当我们有多张图片需要层叠的时候,并且每一层都有一个Alpha值的时候,我们需要怎么计算呢?

从我们的直观上可以想象出来,当我们在看一堆颜色混合而成的颜色的时候,首先是离我们最近的pic1作为前景,其后面的pic2-picn糊混合结果作为背景,混合出来的结果。而pic2-picn是如何混合的呢?它是由pic2作为前景,pic3-picn混合结果作为背景混合出来的结果。如此递归下去知道最后两张图片混合完成。

好了,到这里我们应该很了解在OpenGL中颜色混合的原理了。接下来动手试试。

首先需要修改LoadGLTextures方法中的文件名,因为本次实验使用的是一张新的位图。将"Data/Crate.bmp"改成"Data/glass.bmp"即可。

然后我们需要修改InitGL方法。在使用glEnable(GL_LIGHT1);激活光源之后,我们添加新的两行glColor4f和glBlendFunc方法。

不过需要注意的是,在使用glColor4f以全亮度进行绘制的时候,它会和光照系统glLightfv产生的效果互相排斥。具体的排斥方式请参看【 opengl纹理,光照,glColor4f(),混合】.

另外在glBlendFunc中,为什么会取GL_SRC_ALPHA,GL_ONE,以及GL_SRC_ALPHA,GL_ONE这两个参数会对最终的效果产生什么影响。我们可以参考【 颜色混合opengl】

最后,我们修改WinMain就能够结束本次实验。接着上一次实验的代码.

1
2
3
4
if (keys[VK_LEFT])    // Left方向键按下了么?
{
yspeed-=0.01f; // 若是, 减少yspeed
}

我们增加如下的代码。这几行监视B键是否按下。如果是的话,计算机检查混合选项是否已经打开。然后将其置为相反的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Blending Code Starts Here
if (keys['B'] && !bp)
{
bp = TRUE;
blend = !blend;
if (blend)
{
glEnable(GL_BLEND); // Turn Blending On
glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off
}
else
{
glDisable(GL_BLEND); // Turn Blending Off
glEnable(GL_DEPTH_TEST); // Turn Depth Testing On
}
}
if (!keys['B'])
{
bp = FALSE;
}
// Blending Code Ends Here

到这里本次课程就结束了,我们试着按下B键查看透视效果怎样,另外我们还可以看看当前代码下,打开光源和不打开光源下,按下B键查看透视效果会有什么区别。思考为什么(光源和glColor4f的冲突)。

section6.1

如果我们将InitGL中的glBlendFunc(GL_SRC_ALPHA,GL_ONE);改成glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);又会有什么效果。同样请思考为什么(注意混合方式glBlendFunc中,不同参数下,图像混合的计算方式)。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信