2008年10月8日星期三

半透明实现

GrCopyArea nanox中很多场景都需要拷贝区域,最后一直走到memmove真实的内存拷贝
|----GdBlit
|----|----dstpsd->Blit 这里的psd根绝scr_xxx.c决定哪个SUBDRIVER
|----|----|----linear24_blit 在scr_fb.c中的fb_open函数会调用fb.c中的select_fb_subdriver,根据屏每个像素占几位来确定Blit函数,如果是24位,SUBDRIVER就是fblinear24,由此确定dstpsd->Blit函数是linear24_blit
|----|----|----|----memmove

static void
linear24_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
透明处理是下面这一段
alpha = op & 0xff;

while(--h >= 0) {
for(i=0; i < w; ++i) {
unsigned long s = *src++;
unsigned long d = *dst;

*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
s = *src++;
d = *dst;
*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
s = *src++;
d = *dst;
*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
}
dst += dlinelen_minus_w;
src += slinelen_minus_w;
}

既然要透明也就是要2个图片一起显示,走下来也就是2个点一起显示。
这里有src和dst点,dst是背景,src是显示在上面的图片,该Blit拷贝函数需要把src图片拷贝到dst背景上。分别用3条语句把RGB红绿蓝分开来做计算。
op是传进来的透明参数,原本应该是0-1的透明范围,为了避免浮点运算,alpha范围是0-0xff,计算后右移8位。
就看蓝色这一条:
当alpha为0xff时,显示的完全是s,也就是不透明,把src拷贝到dst了
当alpha为0时,显示的完全是d,也就是完全透明,只能看到dst背景图片
当alpha取中间值时,就是半透明了,还是蛮容易的吧。值越大越不透明

没有评论: