本文是对Blend Func完全没有认识的人写的,就好象一天前的我一样。
废话我就留到后面才说吧。在ClanLib库中的CL_Surface与CL_Sprite中都会有
这个函数:
void set_blend_func(CL_BlendFunc src, CL_BlendFunc dest);
其CL_BlendFun可以在源代码是看到定义,如下:
enum CL_BlendFunc
{
blend_zero, // source or destination (0, 0, 0, 0)
blend_one, // source or destination (1, 1, 1, 1)
blend_dest_color, // source (Rd, Gd, Bd, Ad)
blend_src_color, // destination (Rs, Gs, Bs, As)
blend_one_minus_dest_color, // source (1, 1, 1, 1) - (Rd, Gd, Bd, Ad)
blend_one_minus_src_color, // destination (1, 1, 1, 1) - (Rs, Gs, Bs, As)
blend_src_alpha, // source or destination (As, As, As, As)
blend_one_minus_src_alpha, // source or destination (1, 1, 1, 1) - (As, As, As, As)
blend_dst_alpha, // source or destination (Ad, Ad, Ad, Ad)
blend_one_minus_dest_alpha, // source or destination (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)
blend_src_alpha_saturate, // source (f, f, f, 1) - f = min(As, 1 - Ad)
blend_constant_color, // source or destination (Rc, Gc, Bc, Ac)
blend_one_minus_constant_color, // source or destination (1, 1, 1, 1) - (Rc, Gc, Bc, Ac)
blend_constant_alpha, // source or destination (Ac, Ac, Ac, Ac)
blend_one_minus_constant_alpha // source or destination (1, 1, 1, 1) - (Ac, Ac, Ac, Ac)
};
Blend Func是一个象素运算,
下面是Blend Func的运算公式:
Rb = (Rs x Sr) + (Rd x Dr)
Gb = (Gs x Sg) + (Gd x Dg)
Bb = (Bs x Sb) + (Bd x Db)
Ab = (As x Sa) +(Ad x Da)
“x” 表示乘
“+” 表示加
RGBA 表示的是RGB象素颜色再加上Alpha透明通道
小写“s” 表示源 (source)
小写“d” 表示目标 (destination)
小写”c” 应该是常量的意思吧,不过目前不知怎么用。
小写”f” 不知道什么意思,不过唯一使用的地方有等价的式子:min(As, 1 - Ad)
大写字母“S”和“D”是(源和目标的) 混合因子
这里面所有值都为0 … 1
Rb Gb Bb Ab 表示最终运算后的象素值。
实例应用:
使用Alpha值
一般我们一个CL_Surface在draw的时候,什么都不设置,就能够使用透明象素。
那么我么什么都不设置就相当于:
set_blend_func (blend_src_alpha, blend_one_minus_src_alpha);
blend_src_alpha 为(As, As, As, As)
blend_one_minus_src_alpha 为(1, 1, 1, 1) - (As, As, As, As)
那么我们公式就可以写成
Rb = (Rs x
As
) + (Rd x
(1-As)
)
Gb = (Gs x
As
) + (Gd x
(1-As)
)
Bb = (Bs x
As
) + (Bd x
(1-As)
)
Ab = (As x
As
) + (Ad x
(1-As)
)
这样,当As为0时
Rb = Rd,Gb = Gd, Bb=Bd, Ab=1 这样透明效果也就实现了。
ClanLib中的Canvas例子
在Example中的Canvas中的例子中使用一个图象把目标图象中给掏空了。
其中关键代码:
// Set the cutter surface to extract instead of replace colours
cutter.set_blend_func(blend_zero, blend_one_minus_src_alpha);
cutter.draw(CL_Mouse::get_x(), CL_Mouse::get_y(), canvas_ground->get_gc());
// Set cutter back to normal (for showing the mousecursor)
cutter.set_blend_func(blend_src_alpha, blend_one_minus_src_alpha);
其中blend_zero
为 (0, 0, 0, 0)
blend_one_minus_src_alpha 为 (1, 1, 1, 1) - (As, As, As, As)
那么我们用公式就可以写成
Rb = (Rs x
0
) + (Rd x
(1-As)
)
Gb = (Gs x
0
) + (Gd x
(1-As)
)
Bb = (Bs x
0
) + (Bd x
(1-As)
)
Ab = (As x
0
) + (Ad x
(1-As)
)
当该As 为 0时,Ab = Ad 。当As 为 1时, Ad = 0。 这样最终就实现了掏空的画面。