颜色的生成
前面我们使用了一个值0x7ff,将此值填入显卡地址后显示的是一个蓝色的点,那么这个值是怎么来的呢?
色彩是由红、绿、蓝三色按不同配比而组成的. 不同色彩的值经过一定形式组合后,会产生各种不同的色彩。
三种颜色的值从0到255,代表三色的强弱,分别对应值0x0 - 0xff。每种颜色是8位,三种颜色就占24位,但是我们的图形模式是16位颜色,其中r:g:b是按5:6:5占位,共16位,24位颜色需要转换成16位颜色,用以下方法转换:
r强度值0-255,也就是256种强度值,占八位
要换算成占五位值表示,其值范围0-31,也就是一共32种强度值,那么换算方法是r除以256再乘以32,
等于r除以8,相当于右移三位
g强度值0-255,也就是256种强度值,占八位
要换算成占六位值表示,其值范围0-63,也就是一共64种强度值,那么换算方法是g除以256再乘以64,
等于g除以4,相当于右移二位
b强度值0-255,也就是256种强度值,占八位
要换算成占五位值表示,其值范围0-31,也就是一共32种强度值,那么换算方法是b除以256再乘以32,
等于b除以8,相当于右移三位
函数实现如下:
// rgb合成函数
unsigned short rgb_mix( unsigned char r , unsigned char g , unsigned char b )
{
union{
unsigned int color ;
struct{
unsigned char b : 5 ;
unsigned char g : 6 ;
unsigned char r : 5 ;
}sa;
}ua;
ua.sa.r = r >> 3 ;
ua.sa.g = g >> 2 ;
ua.sa.b = b >> 3 ;
return ua.color ;
}
其中g出现了跨字节现象,g的高三位与b组合成了高八位,g的低三位与r组合成了低八位。
一些人说不能跨字节,这是不对的。
编译中会出现警告:note: offset of packed bit-field 'g' has changed in GCC 4.4
可以使用-Wno-packed-bitfield-compat来禁止这个警告。