分享
 
 
 

256色调色板与Alpha混合

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

256色视频模式由于采用了调色板,在显存里存放的像素值实际上是是调色板的索引号,256色的BMP文件也与之类似,其数据域里存放的也是调色板的索引号,这种情况下给我们的Alpha混客带来极大的不方便。

在实际的应用中,通常是选定一个固定的调色板,然后在这个调色板下进行绘图操作。这是因为一副图像在不同的调色板下有不同的显示效果,两个采用不同调色板的位图在一般情况下是不能同屏显示的。所以通常的情况是选择一个通用的调色板,在把各个位图都抖动处理为使用这个通用调色板的位图,从而解决了同屏显示的问题。这样看来,如何选择一个通用的调色板就是关键了。

大家都知道VGA/SVGA的调色板寄存器通常为6 bits,每个寄存器存放一个颜色分量,一个RGB颜色向量就需要三个寄存器来存放,因此最多能表示 2^6*2^6*2^6=256k 种颜色,这个颜色范围是很大的。而VGA/SVGA只有256组调色板寄存器,,因此要在(0,0,0)-(63,63,63)这样一个向量空间中,精选出256个颜色向量。这有点和线性代数中求向量空间的基(极大无关组)类似。我们的任务也类似于要在(0,0,0)-(63,63,63)这个颜色空间中找出一个基。简单的说就是要找出256个颜色向量,组成一个颜色调色板,并且要使这256个颜色均匀分布于(0,0,0)-(63,63,63)这个空间中,并且还要保证其独立性。详细的做法这里不再探讨,而只给出一个比较通用的调色板。

R(i)=(i/32%8)*9;

G(i)=(i/4%8)*9;

B(i)=(i%4)*21;

其中i为寄存器组号,R(i)、G(i)、B(i)分别为该寄存器的RGB颜色分量值,这是一个从i到R(i)、G(i)、B(i)的变换式。

由此可以写出其逆变换式:

i=R/9*32+G/9*4+B/21;

做一下优化,可以不做乘法和除法运算,得到如下式子:

R(i)=(((i>>5)%8)<<3)+((i>>5)%8);

G(i)=(((i>>2)4%8)<<3)+((i>>2)4%8);

B(i)=((i%4)<<4)+((i%4)<<2)+(i%4);

i=((R/9)<<5)+((G/9)<<2)+B/21;

根据这两个变换式我们可以写出两个宏,用于求取对应(R,G,B)的颜色号i,和颜色号i对应的(R,G,B)值。

#define RGB(r,g,b) ((((r)/9)<<5)+(((g)/9)<<2)+(b)/21)

#define ARGB(r,g,b) RGB(r+4,g+4,b+10)

#define GETRGB(i,pr,pg,pb) {*(pr)=(((i>>5)%8)<<3)+((i>>5)%8);*(pg)=(((i>>2)4%8)<<3)+((i>>2)4%8);(*pb)=((i%4)<<4)+((i%4)<<2)+(i%4);}

其中ARGB(Adjusted RGB)宏是对RGB宏的矫正,因为RGB宏存在误差。

这样我们就建立起了i与(R,G,B)的对应关系,这我为我们的Alpha混合铺平了道路。

现在再谈谈Alpha混合。Alpha混合指的是给定两个点P1、P2,其RGB颜色分量分别为(r1,g1,b1)和(r2,g2,b2),假定P1位于P2的后面,P2的透明度为a(0%<a<100%),要求我没透过点P2看到P1的颜色值是多少。假定该值为P3(r3,g3,b3),其计算公式如下:

r3=(1-a)*r2+a*r1;

g3=(1-a)*g2+a*g1;

b3=(1-a)*b2+a*b1;

这就是通常所说的Alpha混合。

优化一下得到:

r3=r2+a*(r1-r2);

g3=g2+a*(g1-g2);

b3=b2+a*(b1-b2);

少做了一次乘法运算。但由于a为浮点数,运算起来仍然很慢,所以一般不采用上面的公式,而采用整数级的Alpha混合,如下:

r2=r2+n*(r1-r2)/256;

g2=g2+n*(g1-g2)/256;

b2=b2+n*(b1-b2)/256;

以上为256级Alpha混合公式,由于VGA/SVGA调色板寄存器为6bits,所以做256色的Alpha混合意义不大。

而采用一下的64级Alpha混合公式:

r2=r2+n*(r1-r2)/64;

g2=g2+n*(g1-g2)/64;

b2=b2+n*(b1-b2)/64;

进一步优化为L:

r2=r2+(n*(r1-r2)>>6);

g2=g2+(n*(g1-g2)>>6);

b2=b2+(n*(b1-b2)>>6);

仅做了一次乘法运算,这样程序应该能跑得飞快了。

下面给出混合一个点的Alpha算法:

int Alpha(int p1,int p2,int n)

{

int c1[3];

int c2[3];

int c3[3];

GETRGB(p1,c1,c1+1,c1+2);

GETRGB(p2,c2,c2+1,c2+2);

c3[0]=c2[0]+(n*(c1[0]-c2[0])>>6);

c3[1]=c2[1]+(n*(c1[1]-c2[1])>>6);

c3[2]=c2[2]+(n*(c1[2]-c2[2])>>6);

return ARGB(c3[0],c3[1],c3[2]);

}

对半透明混合,可有如下更快的公式:

r2=r2+((r1-r2)>>1);

g2=g2+((g1-g2)>>1);

b2=b2+((b1-b2)>>1);

这个公式没有乘法和除法,半透明在游戏中运用也很广。

以下是半透明的Alpha混合:

int Alpha(int p1,int p2,int n)

{

int c1[3];

int c2[3];

int c3[3];

GETRGB(p1,c1,c1+1,c1+2);

GETRGB(p2,c2,c2+1,c2+2);

c3[0]=c2[0]+((c1[0]-c2[0])>>1);

c3[1]=c2[1]+((c1[1]-c2[1])>>1);

c3[2]=c2[2]+((c1[2]-c2[2])>>1);

return ARGB(c3[0],c3[1],c3[2]);

}

对于n级Alpha混合中的乘法运算,我们也有办法进一步优化,可以采用移位乘法的技术来实现快速的乘法运算,但性能提升不大,有兴趣的朋友可以自己查阅相关资料,这里不再详述。

(注:以上的实现在我的一个名为VGA13H Graphics Lib的函数库里面有源程序,大家可以在我的网站上下载,地址:http://rockcarry.126.com

作者:陈凯

2004.10.10

版权所有、不得转载

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有