image_mixer: Added INVERT blending mode.
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@960
362d55ac-95cf-4e76-9f9a-
cbaa9c17b72d
"\n#define BlendReflect(base, blend) Blend(base, blend, BlendReflectf) \n "\r
"\n#define BlendGlow(base, blend) BlendReflect(blend, base) \n "\r
"\n#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + vec3(1.0)) \n "\r
"\n#define BlendReflect(base, blend) Blend(base, blend, BlendReflectf) \n "\r
"\n#define BlendGlow(base, blend) BlendReflect(blend, base) \n "\r
"\n#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + vec3(1.0)) \n "\r
- "\n#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O)) \n "\r
+ "\n#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O)) \n "\r
+ "\n#define BlendInvert(base, blend) (vec3(1.0, 1.0, 1.0) - blend) \n "\r
"\n "\r
"\n "\r
"\n vec3 BlendHue(vec3 base, vec3 blend) "\r
"\n "\r
"\n "\r
"\n vec3 BlendHue(vec3 base, vec3 blend) "\r
"uniform bool has_local_key; \n"\r
"uniform bool has_layer_key; \n"\r
"uniform int blend_mode; \n"\r
"uniform bool has_local_key; \n"\r
"uniform bool has_layer_key; \n"\r
"uniform int blend_mode; \n"\r
+ "uniform int alpha_mode; \n"\r
"uniform int interlace_mode; \n"\r
"uniform int pixel_format; \n"\r
" \n"\r
"uniform int interlace_mode; \n"\r
"uniform int pixel_format; \n"\r
" \n"\r
" case 26: return BlendSaturation(back, fore); \n"\r
" case 27: return BlendColor(back, fore); \n"\r
" case 28: return BlendLuminosity(back, fore); \n"\r
" case 26: return BlendSaturation(back, fore); \n"\r
" case 27: return BlendColor(back, fore); \n"\r
" case 28: return BlendLuminosity(back, fore); \n"\r
+ " case 29: return BlendInvert(back, fore); \n"\r
" } \n"\r
" \n"\r
" return BlendNormal(back, fore); \n"\r
" } \n"\r
" \n"\r
" return BlendNormal(back, fore); \n"\r
" fore.rgb = ContrastSaturationBrightness(fore.rgb, brt, sat, con); \n"\r
" fore.rgb = get_blend_color(back.bgr, fore.rgb); \n"\r
" fore.rgb = fore.bgr; // rgb to bgr \n"\r
" fore.rgb = ContrastSaturationBrightness(fore.rgb, brt, sat, con); \n"\r
" fore.rgb = get_blend_color(back.bgr, fore.rgb); \n"\r
" fore.rgb = fore.bgr; // rgb to bgr \n"\r
" return vec4(fore.rgb * fore.a + back.rgb * (1.0-fore.a), back.a + fore.a); \n"\r
"} \n"\r
" \n"\r
" return vec4(fore.rgb * fore.a + back.rgb * (1.0-fore.a), back.a + fore.a); \n"\r
"} \n"\r
" \n"\r
shader_->set("has_local_key", local_key ? 1 : 0);\r
shader_->set("has_layer_key", layer_key ? 1 : 0);\r
shader_->set("blend_mode", transform.get_blend_mode());\r
shader_->set("has_local_key", local_key ? 1 : 0);\r
shader_->set("has_layer_key", layer_key ? 1 : 0);\r
shader_->set("blend_mode", transform.get_blend_mode());\r
+ shader_->set("alpha_mode", transform.get_alpha_mode());\r
shader_->set("interlace_mode", transform.get_mode());\r
shader_->set("pixel_format", pix_desc.pix_fmt); \r
\r
shader_->set("interlace_mode", transform.get_mode());\r
shader_->set("pixel_format", pix_desc.pix_fmt); \r
\r
std::wstringstream str(color_str_.substr(1));\r
str >> std::hex >> value;\r
\r
std::wstringstream str(color_str_.substr(1));\r
str >> std::hex >> value;\r
\r
frame_ = std::move(frame);\r
}\r
\r
frame_ = std::move(frame);\r
}\r
\r
, mode_(video_mode::invalid)\r
, is_key_(false)\r
, deinterlace_(false)\r
, mode_(video_mode::invalid)\r
, is_key_(false)\r
, deinterlace_(false)\r
- , blend_mode_(image_transform::normal)\r
+ , blend_mode_(image_transform::blend_mode::normal)\r
+ , alpha_mode_(image_transform::alpha_mode::normal)\r
{\r
std::fill(fill_translation_.begin(), fill_translation_.end(), 0.0);\r
std::fill(fill_scale_.begin(), fill_scale_.end(), 1.0);\r
{\r
std::fill(fill_translation_.begin(), fill_translation_.end(), 0.0);\r
std::fill(fill_scale_.begin(), fill_scale_.end(), 1.0);\r
return deinterlace_;\r
}\r
\r
return deinterlace_;\r
}\r
\r
-void image_transform::set_blend_mode(image_transform::blend_mode value)\r
+void image_transform::set_blend_mode(image_transform::blend_mode::type value)\r
{\r
blend_mode_ = value;\r
}\r
\r
{\r
blend_mode_ = value;\r
}\r
\r
-image_transform::blend_mode image_transform::get_blend_mode() const\r
+image_transform::blend_mode::type image_transform::get_blend_mode() const\r
{\r
return blend_mode_;\r
}\r
\r
{\r
return blend_mode_;\r
}\r
\r
+void image_transform::set_alpha_mode(image_transform::alpha_mode::type value)\r
+{\r
+ alpha_mode_ = value;\r
+}\r
+\r
+image_transform::alpha_mode::type image_transform::get_alpha_mode() const\r
+{\r
+ return alpha_mode_;\r
+}\r
+\r
image_transform& image_transform::operator*=(const image_transform &other)\r
{\r
opacity_ *= other.opacity_;\r
image_transform& image_transform::operator*=(const image_transform &other)\r
{\r
opacity_ *= other.opacity_;\r
mode_ = other.mode_;\r
\r
blend_mode_ = std::max(blend_mode_, other.blend_mode_);\r
mode_ = other.mode_;\r
\r
blend_mode_ = std::max(blend_mode_, other.blend_mode_);\r
+ alpha_mode_ = std::max(alpha_mode_, other.alpha_mode_);\r
gain_ *= other.gain_;\r
brightness_ *= other.brightness_;\r
contrast_ *= other.contrast_;\r
gain_ *= other.gain_;\r
brightness_ *= other.brightness_;\r
contrast_ *= other.contrast_;\r
image_transform result; \r
result.set_mode (dest.get_mode() != video_mode::invalid ? dest.get_mode() : source.get_mode());\r
result.set_blend_mode (std::max(source.get_blend_mode(), dest.get_blend_mode()));\r
image_transform result; \r
result.set_mode (dest.get_mode() != video_mode::invalid ? dest.get_mode() : source.get_mode());\r
result.set_blend_mode (std::max(source.get_blend_mode(), dest.get_blend_mode()));\r
+ result.set_alpha_mode (std::max(source.get_alpha_mode(), dest.get_alpha_mode()));\r
result.set_is_key (source.get_is_key() | dest.get_is_key());\r
result.set_deinterlace (source.get_deinterlace() | dest.get_deinterlace());\r
result.set_gain (do_tween(time, source.get_gain(), dest.get_gain(), duration, tweener));\r
result.set_is_key (source.get_is_key() | dest.get_is_key());\r
result.set_deinterlace (source.get_deinterlace() | dest.get_deinterlace());\r
result.set_gain (do_tween(time, source.get_gain(), dest.get_gain(), duration, tweener));\r
-image_transform::blend_mode get_blend_mode(const std::wstring& str)\r
+image_transform::blend_mode::type get_blend_mode(const std::wstring& str)\r
{\r
if(boost::iequals(str, L"normal"))\r
{\r
if(boost::iequals(str, L"normal"))\r
- return image_transform::normal;\r
+ return image_transform::blend_mode::normal;\r
else if(boost::iequals(str, L"lighten"))\r
else if(boost::iequals(str, L"lighten"))\r
- return image_transform::lighten;\r
+ return image_transform::blend_mode::lighten;\r
else if(boost::iequals(str, L"darken"))\r
else if(boost::iequals(str, L"darken"))\r
- return image_transform::darken;\r
+ return image_transform::blend_mode::darken;\r
else if(boost::iequals(str, L"multiply"))\r
else if(boost::iequals(str, L"multiply"))\r
- return image_transform::multiply;\r
+ return image_transform::blend_mode::multiply;\r
else if(boost::iequals(str, L"average"))\r
else if(boost::iequals(str, L"average"))\r
- return image_transform::average;\r
+ return image_transform::blend_mode::average;\r
else if(boost::iequals(str, L"add"))\r
else if(boost::iequals(str, L"add"))\r
- return image_transform::add;\r
+ return image_transform::blend_mode::add;\r
else if(boost::iequals(str, L"subtract"))\r
else if(boost::iequals(str, L"subtract"))\r
- return image_transform::subtract;\r
+ return image_transform::blend_mode::subtract;\r
else if(boost::iequals(str, L"difference"))\r
else if(boost::iequals(str, L"difference"))\r
- return image_transform::difference;\r
+ return image_transform::blend_mode::difference;\r
else if(boost::iequals(str, L"negation"))\r
else if(boost::iequals(str, L"negation"))\r
- return image_transform::negation;\r
+ return image_transform::blend_mode::negation;\r
else if(boost::iequals(str, L"exclusion"))\r
else if(boost::iequals(str, L"exclusion"))\r
- return image_transform::exclusion;\r
+ return image_transform::blend_mode::exclusion;\r
else if(boost::iequals(str, L"screen"))\r
else if(boost::iequals(str, L"screen"))\r
- return image_transform::screen;\r
+ return image_transform::blend_mode::screen;\r
else if(boost::iequals(str, L"overlay"))\r
else if(boost::iequals(str, L"overlay"))\r
- return image_transform::overlay;\r
+ return image_transform::blend_mode::overlay;\r
else if(boost::iequals(str, L"soft_light"))\r
else if(boost::iequals(str, L"soft_light"))\r
- return image_transform::soft_light;\r
+ return image_transform::blend_mode::soft_light;\r
else if(boost::iequals(str, L"hard_light"))\r
else if(boost::iequals(str, L"hard_light"))\r
- return image_transform::hard_light;\r
+ return image_transform::blend_mode::hard_light;\r
else if(boost::iequals(str, L"color_dodge"))\r
else if(boost::iequals(str, L"color_dodge"))\r
- return image_transform::color_dodge;\r
+ return image_transform::blend_mode::color_dodge;\r
else if(boost::iequals(str, L"color_burn"))\r
else if(boost::iequals(str, L"color_burn"))\r
- return image_transform::color_burn;\r
+ return image_transform::blend_mode::color_burn;\r
else if(boost::iequals(str, L"linear_dodge"))\r
else if(boost::iequals(str, L"linear_dodge"))\r
- return image_transform::linear_dodge;\r
+ return image_transform::blend_mode::linear_dodge;\r
else if(boost::iequals(str, L"linear_burn"))\r
else if(boost::iequals(str, L"linear_burn"))\r
- return image_transform::linear_burn;\r
+ return image_transform::blend_mode::linear_burn;\r
else if(boost::iequals(str, L"linear_light"))\r
else if(boost::iequals(str, L"linear_light"))\r
- return image_transform::linear_light;\r
+ return image_transform::blend_mode::linear_light;\r
else if(boost::iequals(str, L"vivid_light"))\r
else if(boost::iequals(str, L"vivid_light"))\r
- return image_transform::vivid_light;\r
+ return image_transform::blend_mode::vivid_light;\r
else if(boost::iequals(str, L"pin_light"))\r
else if(boost::iequals(str, L"pin_light"))\r
- return image_transform::pin_light;\r
+ return image_transform::blend_mode::pin_light;\r
else if(boost::iequals(str, L"hard_mix"))\r
else if(boost::iequals(str, L"hard_mix"))\r
- return image_transform::hard_mix;\r
+ return image_transform::blend_mode::hard_mix;\r
else if(boost::iequals(str, L"reflect"))\r
else if(boost::iequals(str, L"reflect"))\r
- return image_transform::reflect;\r
+ return image_transform::blend_mode::reflect;\r
else if(boost::iequals(str, L"glow"))\r
else if(boost::iequals(str, L"glow"))\r
- return image_transform::glow;\r
+ return image_transform::blend_mode::glow;\r
else if(boost::iequals(str, L"phoenix"))\r
else if(boost::iequals(str, L"phoenix"))\r
- return image_transform::phoenix;\r
+ return image_transform::blend_mode::phoenix;\r
else if(boost::iequals(str, L"contrast"))\r
else if(boost::iequals(str, L"contrast"))\r
- return image_transform::contrast;\r
+ return image_transform::blend_mode::contrast;\r
else if(boost::iequals(str, L"saturation"))\r
else if(boost::iequals(str, L"saturation"))\r
- return image_transform::saturation;\r
+ return image_transform::blend_mode::saturation;\r
else if(boost::iequals(str, L"color"))\r
else if(boost::iequals(str, L"color"))\r
- return image_transform::color;\r
+ return image_transform::blend_mode::color;\r
else if(boost::iequals(str, L"luminosity"))\r
else if(boost::iequals(str, L"luminosity"))\r
- return image_transform::luminosity;\r
+ return image_transform::blend_mode::luminosity;\r
+ else if(boost::iequals(str, L"invert"))\r
+ return image_transform::blend_mode::invert;\r
- return image_transform::normal;\r
+ return image_transform::blend_mode::normal;\r
+}\r
+\r
+image_transform::alpha_mode::type get_alpha_mode(const std::wstring& str)\r
+{\r
+ if(boost::iequals(str, L"normal"))\r
+ return image_transform::alpha_mode::normal;\r
+\r
+ return image_transform::alpha_mode::normal;\r
}\r
\r
}}
\ No newline at end of file
}\r
\r
}}
\ No newline at end of file
- normal = 0,\r
- lighten,\r
- darken,\r
- multiply,\r
- average,\r
- add,\r
- subtract,\r
- difference,\r
- negation,\r
- exclusion,\r
- screen,\r
- overlay,\r
- soft_light,\r
- hard_light,\r
- color_dodge,\r
- color_burn,\r
- linear_dodge,\r
- linear_burn,\r
- linear_light,\r
- vivid_light,\r
- pin_light,\r
- hard_mix,\r
- reflect,\r
- glow,\r
- phoenix,\r
- contrast,\r
- saturation,\r
- color,\r
- luminosity,\r
- blend_mode_count \r
+ enum type \r
+ {\r
+ normal = 0,\r
+ lighten,\r
+ darken,\r
+ multiply,\r
+ average,\r
+ add,\r
+ subtract,\r
+ difference,\r
+ negation,\r
+ exclusion,\r
+ screen,\r
+ overlay,\r
+ soft_light,\r
+ hard_light,\r
+ color_dodge,\r
+ color_burn,\r
+ linear_dodge,\r
+ linear_burn,\r
+ linear_light,\r
+ vivid_light,\r
+ pin_light,\r
+ hard_mix,\r
+ reflect,\r
+ glow,\r
+ phoenix,\r
+ contrast,\r
+ saturation,\r
+ color,\r
+ luminosity,\r
+ invert,\r
+ blend_mode_count \r
+ };\r
+ };\r
+\r
+ struct alpha_mode\r
+ {\r
+ enum type \r
+ {\r
+ normal = 0,\r
+ };\r
void set_deinterlace(bool value);\r
bool get_deinterlace() const;\r
\r
void set_deinterlace(bool value);\r
bool get_deinterlace() const;\r
\r
- void set_blend_mode(blend_mode value);\r
- blend_mode get_blend_mode() const;\r
+ void set_blend_mode(blend_mode::type value);\r
+ blend_mode::type get_blend_mode() const;\r
+ \r
+ void set_alpha_mode(alpha_mode::type value);\r
+ alpha_mode::type get_alpha_mode() const;\r
\r
private:\r
double opacity_;\r
\r
private:\r
double opacity_;\r
video_mode::type mode_;\r
bool is_key_;\r
bool deinterlace_;\r
video_mode::type mode_;\r
bool is_key_;\r
bool deinterlace_;\r
- blend_mode blend_mode_;\r
+ blend_mode::type blend_mode_;\r
+ alpha_mode::type alpha_mode_;\r
-image_transform::blend_mode get_blend_mode(const std::wstring& str);\r
+image_transform::blend_mode::type get_blend_mode(const std::wstring& str);\r
+image_transform::alpha_mode::type get_alpha_mode(const std::wstring& str);\r
\r
image_transform tween(double time, const image_transform& source, const image_transform& dest, double duration, const tweener_t& tweener);\r
\r
\r
image_transform tween(double time, const image_transform& source, const image_transform& dest, double duration, const tweener_t& tweener);\r
\r
int layer = GetLayerIndex();\r
GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform); \r
}\r
int layer = GetLayerIndex();\r
GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform); \r
}\r
+ else if(_parameters[1] == L"ALPHA")\r
+ {\r
+ auto blend_str = _parameters.at(2);\r
+\r
+ auto transform = [=](image_transform transform) -> image_transform\r
+ {\r
+ transform.set_alpha_mode(get_alpha_mode(blend_str));\r
+ return transform;\r
+ };\r
+ \r
+ int layer = GetLayerIndex();\r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform); \r
+ }\r
else if(_parameters[1] == L"BRIGHTNESS")\r
{\r
auto value = boost::lexical_cast<double>(_parameters.at(2));\r
else if(_parameters[1] == L"BRIGHTNESS")\r
{\r
auto value = boost::lexical_cast<double>(_parameters.at(2));\r