游戏中,我们常常可以看到一些半透明的图像,那么这些图像是怎么生成的呢?是简单的贴位图做的吗?当然不是,要不美工不就惨死了。这其实是利用程序将两张图片进行混合后的效果,也就是图形的Alpha混合,要得到混合图片,就必须对每个点分别进行处理。让我们来看看如何进行Alpha混合。这里以16位色彩位例子:
16位色彩下,每个像素都用一个WORD来表示,有16位二进制。这16位,分成三段分别表示像素的R、G、B值。现在的显示卡有两种:555格式的RGB分别各占5位最高位空、565格式G的值占6位,其他两个分量各占5位。所以首先,我们要得到像素的RGB。
N
R
R
R
R
R
G
G
G
G
G
B
B
B
B
B
图1 555的RGB分量
R
R
R
R
R
G
G
G
G
G
G
B
B
B
B
B
图2 565的RGB分量
在DirectDraw下,可以通过锁定表面,得到表面的像素,将他保存到一个WORD*的变量里。当我们得到资源表面和目的表面的像素后,我们就可以开始进行Alpha混合了。16bit的Alpha混合首先必须分别对原和目的表面的像素分色。这可以通过位操作来实现,用像素值分别与RGB对应的特定值进行与操作将多余的其他色去掉,最后通过移位去掉后面的0。这里要注意555显示卡和565显示卡的区别。分色后,混合正式开始,我们将分色得到的R、G、B的各分色分别混合。下面先看一个公式:A=目的颜色、B=资源颜色、Alpha=混色深度(0 < alpha < 1)
混合后的颜色 = A * Alpha + B * ( 1-Alpha )
当Alpha=0,混合后的颜色=A。当Alpha=1,混合后的颜色=B。当Alpha介于0与1之间,混合后的颜色包含了资源和目的表面的两种颜色。调整Alpha的值,混合后的颜色就会跟着有规律的变化。但是,颜色是整数,所以,我们必须对公式进行一点简单的变化:
混合后的颜色 = ( A * Alpha + B * ( 32-Alpha ) ) / 321 < 32
这样的等价变化后所有的元素都变成了整数,混合颜色的调整级数为32(更高当然也是可以的,把公式中的32换成其他数,Alpha区值范围也变化),但是计算机处理乘法和除法是很慢的,而Alpha混合是对很多的点进行计算,上面的公式显然是不适合的,我们再来点变化:
混合后的颜色=( ( A-B ) * Alpha ) >> 5 + B
除以32等于右移5位,这就是调整级数取32的原因。计算机处理移位是很快的。至于那个乘以Alpha,我也不知道有什么简单的方法改成效率更高的算法。分别混合好R、G、B的色后,最后还需要将他们合成,这是个简单的步骤,与分色相反的移位,然后将三个色值按位或操作就可以了。处理了所有需要混色的像素后,记得将表面解锁。