📄 tutorial_08.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><!-- 这篇文章由Dancingwind翻译,作者的联系方式zhouwei02@mails.tsinghua.edu.cn --><title>NeHe OpenGL教程第八课,DancingWind翻译</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
A:link {COLOR: #ccaaff; TEXT-DECORATION: none}
A:visited {COLOR: #ccaaff; TEXT-DECORATION: none}
A:active {COLOR: #ccaaff; TEXT-DECORATION: none}
A:hover {COLOR: #ffccaa; TEXT-DECORATION: none}
</style></head><body bgcolor="#000000" text="#ffffff"><br><br>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td height="130" width="326"><img src="Tutorial_08_files/logo.png" height="130" width="326"></td>
<td align="center" valign="middle" width="75%"><font color="#ffccaa" size="+3"><b><i>第08课</i></b></font></td>
</tr></tbody></table>
<!-- 上边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<!-- 中部-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<!-- 中部左边框-->
<td background="Tutorial_08_files/l.gif"><img src="Tutorial_08_files/l.gif" height="28" width="28"></td>
<!-- 中部文字部分-->
<td valign="top" width="100%">
<table border="0" width="100%">
<tbody><tr>
<td width="22%"><img src="Tutorial_08_files/lesson08.jpg" height="180" width="240"></td>
<td width="78%"><p><font class="head">混合:</font></p>
<p><font size="3">在这一课里,我们在纹理的基础上加上了混合,它看起具有透明的效果,当然解释它不是那么容易,当希望你喜欢它。</font></p></td>
</tr>
</tbody></table>
</td>
<!-- 中部右边框-->
<td background="Tutorial_08_files/r.gif"><img src="Tutorial_08_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<!-- 下边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_08_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_08_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_08_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_08_files/l.png"><img src="Tutorial_08_files/l.png"></td>
<td valign="top" width="100%">简单的透明<br>
OpenGL中的绝大多数特效都与某些类型的(色彩)混合有关。混色的定义为,将某个象素的颜色和已绘制在屏幕上与其对应的象素颜色相互结合。至于如何结
合这两个颜色则依赖于颜色的alpha通道的分量值,以及/或者所使用的混色函数。Alpha通常是位于颜色值末尾的第4个颜色组成分量。前面这些课我们
都是用GL_RGB来指定颜色的三个分量。相应的GL_RGBA可以指定alpha分量的值。更进一步,我们可以使用glColor4f()来代替
glColor3f()。<br>
绝大多数人都认为Alpha分量代表材料的透明度。这就是说,alpha值为0.0时所代表的材料是完全透明的。alpha值为1.0时所代表的材料则是完全不透明的。
<p>混色的公式<br>
若您对数学不感冒,而只想看看如何实现透明,请跳过这一节。若您想深入理解(色彩)混合的工作原理,这一节应该适合您吧。『译者注:其实并不难^-^。原
文中的公式如下,CKER再唠叨一下吧。其实混合的基本原理是就将要分色的图像各象素的颜色以及背景颜色均按照RGB规则各自分离之后,根据-图像的
RGB颜色分量*alpha值+背景的RGB颜色分量*(1-alpha值)-这样一个简单公式来混合之后,最后将混合得到的RGB分量重新合并。』<br>
公式如下:<br>
(Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)<br>
OpenGL按照上面的公式计算这两个象素的混色结果。小写的s和r分别代表源象素和目标象素。大写的S和D则是相应的混色因子。这些决定了您如何对这些象素混色。绝大多数情况下,各颜色通道的alpha混色值大小相同,这样对源象素就有
(As, As, As, As),目标象素则有1, 1, 1, 1) - (As, As, As, As)。上面的公式就成了下面的模样:<br>
(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As
+ Ad (1 - As))<br>
这个公式会生成透明/半透明的效果。</p>
<p>OpenGL中的混色<br>
在OpenGL中实现混色的步骤类似于我们以前提到的OpenGL过程。接着设置公式,并在绘制透明对象时关闭写深度缓存。因为我们想在半透明的图形背后绘制
对象。这不是正确的混色方法,但绝大多数时候这种做法在简单的项目中都工作的很好。<br>
Rui Martins 的补充: 正确的混色过程应该是先绘制全部的场景之后再绘制透明的图形。并且要按照与深度缓存相反的次序来绘制(先画最远的物体)。<br>
考虑对两个多边形(1和2)进行alpha混合,不同的绘制次序会得到不同的结果。(这里假定多边形1离观察者最近,那么正确的过程应该先画多边形2,再
画多边形1。正如您再现实中所见到的那样,从这两个<透明的>多边形背后照射来的光线总是先穿过多边形2,再穿过多边形1,最后才到达观察者
的眼睛。)<br>
在深度缓存启用时,您应该将透明图形按照深度进行排序,并在全部场景绘制完毕之后再绘制这些透明物体。否则您将得到不正确的结果。我知道某些时候这样做是很令人痛苦的,但这是正确的方法。<br>
我们将使用第七课的代码。一开始先在代码开始处增加两个新的变量。出于清晰起见,我重写了整段代码。<br>
</p></td>
<td background="Tutorial_08_files/r.gif"><img src="Tutorial_08_files/r.gif" height="28" width="28"></td>
</tr>
</tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>bool blend; <font color="#ffffaa">// 是否混合</font><font color="#aaffaa" size="3"><font color="#ffffaa">?</font></font>
bool bp; <font color="#ffffaa">// B 键按下了么?</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_08_files/l.gif"><img src="Tutorial_08_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">然后往下移动到 LoadGLTextures() 这里。找到" if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))
"这一行。我们现在使用有色玻璃纹理来代替上一课中的木箱纹理。</td>
<td background="Tutorial_08_files/r.gif"><img src="Tutorial_08_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> if (TextureImage[0]=LoadBMP("Data/glass.bmp")) <font color="#ffffaa">// 载入玻璃位图</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_08_files/l.gif"><img src="Tutorial_08_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">在InitGL()代码段加入以下两行。第一行以全亮度绘制此物体,并对其进行50%的alpha混合(半透明)。当混合选项打开时,此物体将会产生50%的透明效果。第二行设置所采用的混合类型。<br>
Rui Martins 的补充: alpha通道的值为 0.0意味着物体材质是完全透明的。1.0 则意味着完全不透明。 </td>
<td background="Tutorial_08_files/r.gif"><img src="Tutorial_08_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_08_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_08_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_08_files/br.gif" height="28" width="28"></td>
</tr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -