From: ronag Date: Thu, 25 Aug 2011 14:06:14 +0000 (+0000) Subject: 2.0. Fixed mix transition. X-Git-Tag: 2.0.1~60 X-Git-Url: https://git.sesse.net/?p=casparcg;a=commitdiff_plain;h=116e09a218cf056e4de868454b0fe26dc4db1413 2.0. Fixed mix transition. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1284 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- diff --git a/core/mixer/gpu/ogl_device.cpp b/core/mixer/gpu/ogl_device.cpp index d74d5fd96..ba7db7ea0 100644 --- a/core/mixer/gpu/ogl_device.cpp +++ b/core/mixer/gpu/ogl_device.cpp @@ -336,16 +336,21 @@ void ogl_device::use(shader& shader) } } -void ogl_device::blend_func_separate(int c1, int c2, int a1, int a2) +void ogl_device::blend_func(int c1, int c2, int a1, int a2) { std::array func = {c1, c2, a1, a2}; if(blend_func_ != func) { blend_func_ = func; - glBlendFuncSeparate(c1, c2, a1, a2); + GL(glBlendFuncSeparate(c1, c2, a1, a2)); } } +void ogl_device::blend_func(int c1, int c2) +{ + blend_func(c1, c2, c1, c2); +} + }} diff --git a/core/mixer/gpu/ogl_device.h b/core/mixer/gpu/ogl_device.h index ad5908c3b..d1fb65b2d 100644 --- a/core/mixer/gpu/ogl_device.h +++ b/core/mixer/gpu/ogl_device.h @@ -93,7 +93,8 @@ public: void begin_read(host_buffer& dest, device_buffer& source); void begin_read(device_buffer& dest, host_buffer& source); - void blend_func_separate(int c1, int c2, int a1, int a2); + void blend_func(int c1, int c2, int a1, int a2); + void blend_func(int c1, int c2); void use(shader& shader); diff --git a/core/mixer/image/blend_modes.h b/core/mixer/image/blend_modes.h index b008a9983..cd6500e1f 100644 --- a/core/mixer/image/blend_modes.h +++ b/core/mixer/image/blend_modes.h @@ -35,6 +35,7 @@ struct blend_mode saturation, color, luminosity, + mix, blend_mode_count }; }; diff --git a/core/mixer/image/image_kernel.cpp b/core/mixer/image/image_kernel.cpp index e659c618b..1fd83d91d 100644 --- a/core/mixer/image/image_kernel.cpp +++ b/core/mixer/image/image_kernel.cpp @@ -123,7 +123,14 @@ struct image_kernel::implementation : boost::noncopyable } else { - ogl.blend_func_separate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + switch(params.blend_mode) + { + case blend_mode::mix: + ogl.blend_func(GL_ONE, GL_ONE); + break; + default: + ogl.blend_func(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } } // Setup image-adjustements diff --git a/core/mixer/image/image_kernel.h b/core/mixer/image/image_kernel.h index 13827e734..31e9098e4 100644 --- a/core/mixer/image/image_kernel.h +++ b/core/mixer/image/image_kernel.h @@ -43,7 +43,10 @@ struct draw_params std::shared_ptr local_key; std::shared_ptr layer_key; - draw_params() : blend_mode(blend_mode::normal){} + draw_params() + : blend_mode(blend_mode::normal) + { + } }; class image_kernel : boost::noncopyable diff --git a/core/mixer/image/image_mixer.cpp b/core/mixer/image/image_mixer.cpp index 302d7af5e..393c8a714 100644 --- a/core/mixer/image/image_mixer.cpp +++ b/core/mixer/image/image_mixer.cpp @@ -145,37 +145,34 @@ private: return; std::shared_ptr local_key_buffer; + std::shared_ptr local_mix_buffer; if(layer.blend_mode != blend_mode::normal && layer.items.size() > 1) { auto layer_draw_buffer = create_device_buffer(4); BOOST_FOREACH(auto& item, layer.items) - draw_item(std::move(item), layer_draw_buffer, local_key_buffer, layer_key_buffer); - - draw_params draw_params; - draw_params.pix_desc.pix_fmt = pixel_format::bgra; - draw_params.pix_desc.planes = list_of(pixel_format_desc::plane(channel_.get_format_desc().width, channel_.get_format_desc().height, 4)); - draw_params.textures = list_of(layer_draw_buffer); - draw_params.transform = frame_transform(); - draw_params.blend_mode = layer.blend_mode; - draw_params.background = draw_buffer; - - kernel_.draw(channel_.ogl(), std::move(draw_params)); + draw_item(std::move(item), layer_draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer); + + draw_device_buffer(layer_draw_buffer, std::move(local_mix_buffer), blend_mode::normal); + draw_device_buffer(draw_buffer, std::move(layer_draw_buffer), layer.blend_mode); } else // fast path { BOOST_FOREACH(auto& item, layer.items) - draw_item(std::move(item), draw_buffer, local_key_buffer, layer_key_buffer); + draw_item(std::move(item), draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer); + + draw_device_buffer(draw_buffer, std::move(local_mix_buffer), blend_mode::normal); } - + std::swap(local_key_buffer, layer_key_buffer); } void draw_item(item&& item, safe_ptr& draw_buffer, + std::shared_ptr& layer_key_buffer, std::shared_ptr& local_key_buffer, - std::shared_ptr& layer_key_buffer) + std::shared_ptr& local_mix_buffer) { draw_params draw_params; draw_params.pix_desc = std::move(item.pix_desc); @@ -193,8 +190,22 @@ private: kernel_.draw(channel_.ogl(), std::move(draw_params)); } + else if(item.transform.is_mix) + { + local_mix_buffer = local_mix_buffer ? local_mix_buffer : create_device_buffer(4); + + draw_params.background = local_mix_buffer; + draw_params.local_key = std::move(local_key_buffer); + draw_params.layer_key = layer_key_buffer; + + draw_params.blend_mode = blend_mode::mix; + + kernel_.draw(channel_.ogl(), std::move(draw_params)); + } else { + draw_device_buffer(draw_buffer, std::move(local_mix_buffer), blend_mode::normal); + draw_params.background = draw_buffer; draw_params.local_key = std::move(local_key_buffer); draw_params.layer_key = layer_key_buffer; @@ -202,6 +213,22 @@ private: kernel_.draw(channel_.ogl(), std::move(draw_params)); } } + + void draw_device_buffer(safe_ptr& draw_buffer, std::shared_ptr&& source_buffer, blend_mode::type blend_mode = blend_mode::normal) + { + if(!source_buffer) + return; + + draw_params draw_params; + draw_params.pix_desc.pix_fmt = pixel_format::bgra; + draw_params.pix_desc.planes = list_of(pixel_format_desc::plane(source_buffer->width(), source_buffer->height(), 4)); + draw_params.textures = list_of(source_buffer); + draw_params.transform = frame_transform(); + draw_params.blend_mode = blend_mode; + draw_params.background = draw_buffer; + + kernel_.draw(channel_.ogl(), std::move(draw_params)); + } safe_ptr create_device_buffer(size_t stride) { diff --git a/core/mixer/image/image_shader.cpp b/core/mixer/image/image_shader.cpp index d9b83877f..85ceb4cca 100644 --- a/core/mixer/image/image_shader.cpp +++ b/core/mixer/image/image_shader.cpp @@ -69,7 +69,11 @@ std::string get_blend_color_func() " \n" "vec4 blend(vec4 fore) \n" "{ \n" - " vec4 back = texture2D(background, gl_TexCoord[1].st).bgra; \n" + " vec4 back = texture2D(background, gl_TexCoord[1].st).bgra; \n" + " \n" + " if(blend_mode == 29) // mix \n" + " return fore + back; \n" + " \n" " fore.rgb = get_blend_color(back.rgb, fore.rgb); \n" " return fore + (1.0-fore.a)*back; \n" "} \n"; @@ -115,6 +119,7 @@ std::string get_fragment(bool blend_modes) "uniform bool has_local_key; \n" "uniform bool has_layer_key; \n" "uniform int blend_mode; \n" + "uniform int alpha_mode; \n" "uniform int pixel_format; \n" " \n" "uniform float opacity; \n" diff --git a/core/producer/frame/frame_transform.cpp b/core/producer/frame/frame_transform.cpp index 60d93a1aa..a608973ab 100644 --- a/core/producer/frame/frame_transform.cpp +++ b/core/producer/frame/frame_transform.cpp @@ -34,6 +34,7 @@ frame_transform::frame_transform() , saturation(1.0) , field_mode(field_mode::progressive) , is_key(false) + , is_mix(false) { std::fill(fill_translation.begin(), fill_translation.end(), 0.0); std::fill(fill_scale.begin(), fill_scale.end(), 1.0); @@ -63,6 +64,7 @@ frame_transform& frame_transform::operator*=(const frame_transform &other) levels.gamma *= other.levels.gamma; field_mode = static_cast(field_mode & other.field_mode); is_key |= other.is_key; + is_mix |= other.is_mix; return *this; } @@ -99,6 +101,7 @@ frame_transform tween(double time, const frame_transform& source, const frame_tr result.levels.gamma = do_tween(time, source.levels.gamma, dest.levels.gamma, duration, tweener); result.field_mode = static_cast(source.field_mode & dest.field_mode); result.is_key = source.is_key | dest.is_key; + result.is_mix = source.is_mix | dest.is_mix; return result; } diff --git a/core/producer/frame/frame_transform.h b/core/producer/frame/frame_transform.h index 0fde0ec44..d20f774ff 100644 --- a/core/producer/frame/frame_transform.h +++ b/core/producer/frame/frame_transform.h @@ -65,6 +65,7 @@ public: field_mode::type field_mode; bool is_key; + bool is_mix; frame_transform& frame_transform::operator*=(const frame_transform &other); frame_transform frame_transform::operator*(const frame_transform &other) const; diff --git a/core/producer/transition/transition_producer.cpp b/core/producer/transition/transition_producer.cpp index ccbfa757c..24cf92875 100644 --- a/core/producer/transition/transition_producer.cpp +++ b/core/producer/transition/transition_producer.cpp @@ -132,14 +132,18 @@ struct transition_producer : public frame_producer d_frame1->get_frame_transform().volume = 0.0; d_frame2->get_frame_transform().volume = delta2; - //if(info_.type == transition::mix) - //{ - // d_frame1->get_frame_transform().set_opacity(delta1); - // d_frame2->get_frame_transform().set_opacity(delta2); - - // s_frame1->get_frame_transform().set_opacity(1.0-delta1); - // s_frame2->get_frame_transform().set_opacity(1.0-delta2); - //} + if(info_.type == transition::mix) + { + d_frame1->get_frame_transform().opacity = delta1; + d_frame1->get_frame_transform().is_mix = true; + d_frame2->get_frame_transform().opacity = delta2; + d_frame2->get_frame_transform().is_mix = true; + + s_frame1->get_frame_transform().opacity = 1.0-delta1; + s_frame1->get_frame_transform().is_mix = true; + s_frame2->get_frame_transform().opacity = 1.0-delta2; + s_frame2->get_frame_transform().is_mix = true; + } if(info_.type == transition::slide) { d_frame1->get_frame_transform().fill_translation[0] = (-1.0+delta1)*dir; diff --git a/shell/casparcg.config b/shell/casparcg.config index 36a38ca7a..a24afe745 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -41,6 +41,7 @@ true + true 1