转自http://yuxiangjismtp.blog.sohu.com/96152801.html
无论是在颜色索引或者RGBA模式中,每一个像素都是用一定数量的颜色数据进行存储的。这个数量是由帧缓存中的位面决定的。一个位面为一个像素的一个位的数据。假如是8位面的颜色,每个像素就有8个颜色位,因此就有2的8次方位,也就是256种不同的颜色值或者说每个像素可以有256种颜色。
位面通常分成R、G和B三种组成部分(也就是说,一个24位面系统分别分配8位给红色、绿色和蓝色),但是不总是这样。为了获得你的系统中给红色、绿色、蓝色和混合通道,或者颜色索引值,分配的位面数,你可以使用glGetIntegerv()函数和参数GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS, and GL_INDEX_BITS,进行获取。
注意:在大多数计算机屏幕上人眼感知颜色亮度不是线性变化的。设想只有红色成分的颜色,其绿色和蓝色成分都为0。当其亮度从0.0到1.0之间变化时,撞击像素的电子数量逐渐增加,但是问题是0.5的亮度看起来是0.0和1.0中间的那个亮度吗?为了测试这个,我们写一个程序,在一个棋盘格上画出亮度从0.0到1.0之间逐渐变化的调色板,和颜色为0.5的那个区域进行比较。距离屏幕一个合理的距离,两个区域可能看起来是相同的亮度。假如它们看起来明显不同,你就需要使用你的系统中的任何一种校正机制进行校正。例如,许多系统有一个表格用于调整亮度,以使得0.5的亮度看起来接近0.0和1.0中间的亮度。这个映射通常使用一个指数函数,指数指向一个灰度系数(术语称为灰度校正)。红、绿、蓝使用相同的灰度能够得到一个相当好的结果,但是三个不同的灰度值也许能够得到稍微更好的结果。(关于这个话题的更详细信息,参看Foley, van Dam, et al. Computer Graphics: Principles and Practice. Reading, MA: Addison-Wesley Developers Press, 1990。)
RGBA显示模式
在RGBA模式中,硬件分配一定数量的位面给R、G、B和A成分(每个成分的数量不一定一样)如图4-2所示。R、G、B的值通常以整型存储,而不是浮点数,并且它们被扩展成可以方便存储和获取的位数。例如,在一个R成分有8位的系统中,从0到255的成分就可以存储,这样,0,1,2,……,255就对应R的值0/255 = 0.0, 1/255, 2/255, ..., 255/255 = 1.0。无论位面的数量是多少,0.0总是最小的亮度值,1.0总是表示最大的亮度值。
图4-2:位面中的RGB值
注意:alpha值在屏幕上的显示没有直接的效果。它可以用来做许多事情,包括混色和透明,且它可以给R、G、B一个效果。(参看第6章的“混合”,获得更多关于alpha值的信息)
每个像素能够显示的不同颜色依赖于位面的数量和硬件解释这些位面的能力。不同颜色的数量不能超过2的n次方,这里n为位面数。这样,一个有24位面的机器能够显示多达1677万种不同的颜色。
抖动
高级
一些图形硬件使用抖动来增加显示上的颜色数。抖动是一种使用混合多种颜色来创造出另一种颜色效果的技术。为了说明抖动是如何工作的,想象一下你的系统只有1位来表示R、G和B,这样就只能显示八种颜色:黑、白、红、蓝、绿、黄、青、洋红。为了显示粉色的区域,硬件就可以使用棋盘格的方式,交替使用红色和白色像素填充这个区域。假如你的眼睛离屏幕足够远,它就不能分辨出每个像素,这样这个区域就呈现出粉色-红色和白色的均分。使用较多的红色就会得到更红的粉色,使用更多的白像素就得到更白一点的粉色。
使用这个技术,这儿没有粉色的像素。获得粉色效果的唯一方式就是用多种像素来填充这个区域-你不能抖动一个像素。假如你指定一个不存在的颜色用于填充多边形,硬件就会用多种相近的颜色进行混合填充,使之看起来的效果就像你想要的。(记住,尽管这样,假如你在帧缓存里读取一个像素,你得到的就是真正的红色和白色像素值,因为这没有粉色。参看第8章获得关于像素读取的信息)
图4-3图示了一些简单的黑白像素的抖动,得到灰度梯度。从左到右,上面的4X4的的图案分别表示百分之50、百分之19、百分之69灰度的抖动模式。每个模式下,你可以看到简单重复这个模式,但是这个黑白方块仍然相对于像素太大了。假如你从屋子的另一端查看,你可以看到它们的混合效果,看起来就是三个梯度的灰色。
图4-3:黑白抖动成灰色
如果RGB各用8位,你不用抖动就可以获得相当高质量的图像。然而不会只是因为你的机器有24个颜色位面,就不需要抖动了。例如,如果你是运行在双帧模式下,位面就要分成两个12的集合,这样,RGB分别只有4位了。没有抖动,每个分量4位的颜色在许多环境下只能提供另人不是很满意的效果了。
你可以通过传递GL_DITHER给glEnable或glDisable来打开或关闭抖动功能。注意不像其它许多特征,抖动是默认开启的。
颜色索引显示模式
在颜色索引模式下,OpenGL使用一个颜色表(或查找表),就像用一个调色板来调出场景需要的各种颜色。画家的调色板提供了很多小格子用于调色;类似的,计算机的颜色表提供很多索引,供RGB值进行混合,如图4-4所示。
图4-4:颜色表
画家是从调色板上选择一种颜色,然后填充到相应区域的格子里。计算机为每一个像素将颜色索引值存进位面。然后这些位面值对应到颜色表,屏幕就用颜色表里面查找到相应的RGB值进行绘制,如图4-5。
图4-5:使用颜色表来绘制图像
在颜色索引模式中,同时存在的颜色受到颜色表的大小和位面个数的限制。颜色表的大小是由硬件分配给它的空间决定的。颜色表的大小通常为2的多少次方个,通常的大小从256(2的8次方)到4096(2的12次方),其中指数为使用的位面个数。如果颜色表中有2的n次方个索引值,和m个可用的位面,那么可用的个数为2的n次方和2的m次方中的小的那个。
在RGBA模式中,每个像素的颜色是独立于其它像素的。但是在颜色索引模式中,相同索引值的像素共享相同的颜色表位置。如果颜色表中的内容改变了,那么相同索引值的像素将改变颜色。
选择RGBA模式还是颜色索引模式
你要基于可用的硬件和应用程序的需要来决定使用哪种颜色模式。对大多数系统而言,RGBA模式比颜色索引模式能够同时表示更多的颜色。同样,对于大多数效果,例如阴影、光照、纹理映射、雾化,RGBA模式比颜色索引模式提供更加丰富的功能。
在下列的情况下你宁可使用颜色索引模式:
- 假如你正导入一个已经存在的程序,它主要使用颜色索引模式,也许不转为RGBA模式会更容易一些。
- 假如你只有很少的位面可用,RGBA模式对于阴影的过渡将显得非常粗糙。例如,你只有8位面,在RGBA模式下,你只能给红色分3位面,绿色分3位面,蓝色分2位面。你只能够得到8个级别的红色和绿色,甚至只有4个级别的蓝色。颜色之间的变化将是非常明显的。
- 在这种情况下,假如你有受限的渐变需求,你可以使用颜色查找表来装入更多渐变的颜色。例如,假如你需要蓝色的渐变,你可以使用颜色索引模式在颜色查找表中保存256级的蓝色,这比在RGBA模式下只有4级的蓝色值好多了。当然,这个例子中你的颜色表就被用光了,所以就没有红色和绿色的渐变颜色和其它混合颜色了。
- 在这种情况下,假如你有受限的渐变需求,你可以使用颜色查找表来装入更多渐变的颜色。例如,假如你需要蓝色的渐变,你可以使用颜色索引模式在颜色查找表中保存256级的蓝色,这比在RGBA模式下只有4级的蓝色值好多了。当然,这个例子中你的颜色表就被用光了,所以就没有红色和绿色的渐变颜色和其它混合颜色了。
颜色所以模式有许多使用中的诀窍,例如颜色表动画和分层绘制。(参看第14章获取更多信息)
总之,一旦有可能就使用RGBA模式。它在纹理映射、光照、渐变、雾化、反走样和混合方面都工作的更好。
在显示模式之间切换
在最好的情况下,你也许想不用在RGBA模式和颜色索引模式中进行选择。例如,你也许想使用颜色模式进行颜色表动画,然后在需要的情况下,立即切换到RGBA模式下进行纹理映射。
或者类似的,你也许想在单帧和双帧之间进行切换。例如,你也许只有很少的位面;比如8个位面。在单帧模式下,你就会有256种颜色,但是当你使用双帧模式来消除动画时的闪烁是,你就只有16种颜色了。也许你想要绘制一个移动的物体,而没有闪烁,你就要牺牲颜色数来换取使用双帧模式(也许会因为物体运动得太快了,观察者注意不到这种差别)。但是当物体静止下来后,你就在单帧模式下进行绘制以获得更多的颜色。
不幸的是,大多数窗口系统不会允许这么容易的切换。例如,在X窗口系统中,颜色显示模式是X Visual的一个属性,X Visual是在窗口在创建之前指定的。一旦它指定后,就不能在窗口的生存周期里进行改变。当你创建好一个双帧的、RGBA模式的窗口后,你就不能再去动它了。
这个问题的一个技巧的解决办法是创建多个窗口,每个使用不同的显示模式。然后你控制窗口的显示与不显示(例如,mapping和unmaping一个X窗口,或managing和unmanaging一个Motif或Athena的控件),然后在适当的位置绘制物体,最后显示窗口。