分享
 
 
 

64K色模式下的快速Alpha混合算法

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

在32/64K色模式下,由于每个点的RGB值是放在一个字里,以16位色为例,一般是按RGB或BGR 565存放。传统的软件Alpha混合算法是先将RGB分离出来,分开运算,然后再合成。这造成了16位模式下的alpha混合比24位模式下慢 的现象,但使用16位色真的那么慢吗?我认为如果不使用MMX指令,15/16的比24位的快。因为我们可以使用一个小的技巧来同时计算RGB。而24位颜色,除非使用MMX指令,否则必须分开计算R、G、B。

先设颜色(color)是RGB 565的,那么按二进制看,这个颜色字是这样分布的:

RRRRR GGGGGG BBBBB

5位

6位

5位

RGB成分

而386以上CPU都有32位的寄存器,我们只需要将16位RGB变形为:

00000

GGGGGG

00000

RRRRR

000000

BBBBB

5位

6位

5位

5位

6位

5位

变形后的RGB成分

储存在32位寄存器中,(就是把绿色提到前16位里)由于64K色下颜色深度是32级的,所以alpha也只用分32级就能满足需要。那么对上面变形过的双字处理,可以同时算RGB了。(Color1*Alpha+Color2*(32-Alpha))/32能不能简化为(Color1-Color2)*Alpha/32+Color2?我思考过这个问题,以为减法将产生负数,这样再算乘法时有可能出问题,但是经过测试,这样简化似乎又没有问题。毕竟极小的误差是可以忽略的。

最近温习了一下汇编,今天用NASM写了个C可调用的Alpha混合函数(32位模式,我针对DJGPP写的)并进行了Pentium优化(针对双流水线,有错请指出)。大家看看,有BUG,还能优化或有更快的方法也请一定告诉我。顺便提一下,上面提到的化简没有体现到下面的程序中,而且,使用乘法本身是个错误。只是看看吧,如果你想实际运用,请参考Allegro程序库的做法。

; 对16位的color1与color2进行Alpha混合

; R=(r1*alpha+r2*(32-alpha))/32

; G=(g1*alpha+g2*(32-alpha))/32

; B=(b1*alpha+b2*(32-alpha))/32

; C 语言调用函数(32 位保护模式)Pentium双流水线优化

; By Cloud Wu (cloudwu@263.net)

;

(http://member.netease.com/~cloudwu)

; -------------------------------------------------------------------------

; unsigned long alpha (unsigned long c1,unsigned long c2,unsigned long alpha);

; -------------------------------------------------------------------------

; c1: 颜色1的RGB(565),c2: 颜色2的RGB(565),alpha: Alpha值(0~31)

; NASM 编译通过

[BITS 32]

[GLOBAL _alpha]

[SECTION .text]

_alpha:

; 初始化代码

push ebp

; ebp 压栈

mov ebp,esp

; 保存 esp 到 ebp

mov edi,0x7e0f81f

; dx=00000111111000001111100000011111

add esp,8

; esp 指向参数 c1

pop eax

; 弹出 c1 到 ax

pop ebx

; 弹出 c2 到 bx

; 处理颜色

mov cx,ax

; cx=r1..b1

mov dx,bx

; dx=r2..b2

sal eax,16

; eax=r1g1b1......

sal ebx,16

; ebx=r2g2b2......

mov ax,cx

; eax=r1g1b1r1g1b1

mov bx,dx

; ebx=r2g2b2r2g2b2

and eax,edi

; eax=..g1..r1..b1

pop esi

; 弹出 alpha

mul esi

; eax*=alpha

neg esi

; -alpha

and ebx,edi

; ebx=..g2..r2..b2

add esi,0x20

; 32-alpha

xchg eax,ebx

; 交换 eax,ebx

mul esi

; c2*=(32-alpha)

add eax,ebx

; c1*alpha+c2*(32-alpha)

mov esp,ebp

sar eax,5

; color=(c1*alpha+c2*(32-alpha))/32

;还原成 RGB 形式

pop ebp

and eax,edi

; color=..g..r..b

mov cx,ax

;

sar eax,16

;

or ax,cx

; color=rgb (eax)

ret

如果建一张256K的表来查表预处理RGB怎样?经过尝试,发现速度不仅没有提高,反而降低了。分析的结论是,256K的表太大了,以至于不能放到缓存(Cache)里,反而没有计算的方法快,毕竟计算的话,每行的代码都很快,而不必和内存打交道。真正加速的方法是什么?借鉴Allegro程序库里的方法,建立32个函数分别计算每个alpha值的情况。这样,alpha值变成固定的,从而可以使用LEA、ADD、SUB、SAL、SAR来替代缓慢的MUL。经过实践,我重写了Allegro程序库里的cblend15.c及cblend16.c,(使用程序库自己的Test.exe,机器配置为Cyrix Gx/120 S3/375 4M)测试数据如下:

原有的混合函数 使用新算法的混合函数 将Blender函数置为空

1402 per sec 1779 per sec 2002 per sec

呵呵,速度提高了一倍不是吗?Allegro库目前的版本已经使用了我写的blender函数。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有