Created
April 6, 2014 04:26
-
-
Save jin1016/10001549 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __BLEND_VARIATION_H__ | |
#define __BLEND_VARIATION_H__ | |
/** | |
* アルファの扱い方によって発生するバリエーションを作りやすくするためのファンクタ | |
* blend_func は、 | |
* tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) | |
* を持つファンクタ | |
*/ | |
//-------------------------------------------------------------------------------------------------------- | |
// アルファの扱い | |
//-------------------------------------------------------------------------------------------------------- | |
// srcのアルファを使用するバージョン | |
template<class blend_func> | |
struct normal_op { | |
blend_func func_; | |
inline normal_op() {} | |
inline normal_op(tjs_uint32 opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
tjs_uint32 a = (s>>24); | |
return func_(d,s,a); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// 透明度を指定するバージョン | |
template<class blend_func> | |
struct translucent_op { | |
const tjs_int opa_; | |
blend_func func_; | |
inline translucent_op() : opa_(255) {} | |
inline translucent_op(tjs_uint32 opa) : opa_(opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
tjs_uint32 a = ((s>>24)*opa_)>>8; | |
return func_(d,s,a); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// destアルファを保護するバージョン | |
template<class blend_func> | |
struct hda_op { | |
blend_func func_; | |
inline hda_op(){} | |
inline hda_op(tjs_uint32 opa){} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
tjs_uint32 a = (s>>24) | |
return (func_(d,s,a)&0x00ffffff) | (d&0xff000000); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// destアルファを保護し、透明度を指定するバージョン | |
template<class blend_func> | |
struct hda_translucent_op { | |
const tjs_uint32 opa_; | |
blend_func func_; | |
inline hda_translucent_op() : opa_(255) {} | |
inline hda_translucent_op(tjs_uint32 opa) : opa_(opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
tjs_uint32 a = ((s>>24)*opa_)>>8; | |
return (func_(d,s,a)&0x00ffffff) | (d&0xff000000); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// destのアルファを使用するバージョン | |
template<class blend_func> | |
struct dest_alpha_op { | |
blend_func func_; | |
inline normal_op() {} | |
inline normal_op(tjs_uint32 opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
#ifdef NOT_USE_TABLE | |
tjs_uint32 sa = s >> 24; | |
tjs_uint32 da = d >> 24; | |
tjs_uint32 sopa; | |
if( da ) { | |
float at = (float)(da/255.0); | |
float bt = (float)(sa/255.0); | |
float c = bt / at; | |
c /= (float)( (1.0 - bt + c) ); | |
tjs_uint32 sopa = (tjs_uint32)(c*255); | |
} else { | |
sopa = 255; | |
} | |
tjs_uint32 destalpha = (unsigned char)( 255 - (255-da)*(255-sa)/ 255 ); | |
#else | |
tjs_uint32 addr = ((s >> 16) & 0xff00) + (d>>24); | |
tjs_uint32 destalpha = TVPNegativeMulTable[addr]<<24; | |
tjs_uint32 sopa = TVPOpacityOnOpacityTable[addr]; | |
#endif | |
return func_(d,s,sopa) + destalpha; | |
} | |
// (sa/da) / ( 1 - sa + (sa/da) ) | |
// 1 / (sa+da) | |
// 1 - (1-da)*(1-sa) | |
// 1 - sa - da + da*sa | |
// ca = a + ba | |
// ca = a + ba; | |
// ca = a + ba; | |
// ca = a + (((255-a)*da)/255 | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// destのアルファを使用する、透明度を指定するバージョン | |
template<class blend_func> | |
struct dest_alpha_translucent_op { | |
const tjs_int opa_; | |
blend_func func_; | |
inline translucent_op() : opa_(255) {} | |
inline translucent_op(tjs_uint32 opa) : opa_(opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
#ifdef NOT_USE_TABLE | |
tjs_uint32 sa = ((s>>24)*opa_)>>8; | |
tjs_uint32 da = d >> 24; | |
tjs_uint32 sopa; | |
if( da ) { | |
float at = (float)(da/255.0); | |
float bt = (float)(sa/255.0); | |
float c = bt / at; | |
c /= (float)( (1.0 - bt + c) ); | |
tjs_uint32 sopa = (tjs_uint32)(c*255); | |
} else { | |
sopa = 255; | |
} | |
tjs_uint32 destalpha = (unsigned char)( 255 - (255-da)*(255-sa)/ 255 ); | |
#else | |
tjs_uint32 addr = (( (s>>24)*opa_) & 0xff00) + (d>>24); | |
tjs_uint32 destalpha = TVPNegativeMulTable[addr]<<24; | |
tjs_uint32 sopa = TVPOpacityOnOpacityTable[addr]; | |
#endif | |
return func_(d,s,sopa) + destalpha; | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
#if 0 | |
// 不透明バージョン 特殊版を作った方が高速 | |
template<class blend_func> | |
struct opacity_op { | |
blend_func func_; | |
inline opacity_op(){} | |
inline opacity_op(tjs_uint32 opa){} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
return func_(d,s,255); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
// 不透明バージョン 透明度を指定する | |
template<class blend_func> | |
struct opacity_translucent_op { | |
const tjs_uint32 opa_; | |
blend_func func_; | |
inline opacity_translucent_op() : opa_(255) {} | |
inline opacity_translucent_op(tjs_uint32 opa) : opa_(opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
return func_(d,s,opa_); | |
} | |
}; | |
//-------------------------------------------------------------------------------------------------------- | |
#endif | |
#endif // __BLEND_VARIATION_H__ | |
#ifndef __ALPHA_BLEND_C_H__ | |
#define __ALPHA_BLEND_C_H__ | |
#include "blend_util_func.h" | |
#include "blend_variation.h" | |
//------------------------------------------------------------------------------ | |
/** | |
* alpha_blend_functor; // dstアルファ無視 | |
* alpha_blend_HDA_functor; // dstアルファ無視, dst アルファ保護 | |
* alpha_blend_o_functor; // dstアルファ無視, opacity 指定 | |
* alpha_blend_HDA_o_functor; // dstアルファ無視, dst アルファ保護, opacity 指定 | |
* | |
* alpha_blend_d_functor; // dstアルファ有効 | |
* alpha_blend_do_functor; // dstアルファ有効, opacity 指定 | |
* | |
* alpha_blend_a_functor; // dstアルファ有効, addalpha(pre-multiplied alpha) | |
* alpha_blend_ao_functor; // dstアルファ有効, opacity 指定, addalpha(pre-multiplied alpha) | |
*/ | |
//------------------------------------------------------------------------------ | |
struct alpha_blend_func { | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const { | |
tjs_uint32 d1 = d & 0xff00ff; | |
d1 = (d1 + (((s & 0xff00ff) - d1) * a >> 8)) & 0xff00ff; | |
d &= 0xff00; | |
s &= 0xff00; | |
return d1 + ((d + ((s - d) * a >> 8)) & 0xff00); | |
} | |
}; | |
typedef normal_op<alpha_blend_func> alpha_blend_functor; | |
typedef translucent_op<alpha_blend_func> alpha_blend_o_functor; | |
typedef hda_op<alpha_blend_func> alpha_blend_HDA_functor; | |
typedef hda_translucent_op<alpha_blend_func> alpha_blend_HDA_o_functor; | |
typedef dest_alpha_op<alpha_blend_func> alpha_blend_d_functor; | |
typedef dest_alpha_translucent_op<alpha_blend_func> alpha_blend_do_functor; | |
//------------------------------------------------------------------------------ | |
struct alpha_blend_a_functor { | |
premulalpha_blend_func blend_; | |
alpha_to_additive_alpha_func topremulalpha_; | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
return blend_( dest, topremulalpha_(s) ); | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
struct alpha_blend_ao_functor { | |
tjs_int opa_; | |
alpha_blend_a_functor blend_; | |
inline alpha_blend_ao_functor( tjs_int opa ) : opa_(opa) {} | |
inline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { | |
s = (s & 0xffffff) + ((((s >> 24) * opa_) >> 8) << 24); | |
return blend_(d,s); | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
#endif // __ALPHA_BLEND_C_H__ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment