From 5391bc8ee9d44c6622a33db7efdb91f7bf99fa18 Mon Sep 17 00:00:00 2001 From: ronag Date: Fri, 19 Aug 2011 14:12:41 +0000 Subject: [PATCH] 2.0. image_mixer: Fixed layer mixing. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1233 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- core/mixer/gpu/ogl_device.cpp | 12 ++++++++++++ core/mixer/gpu/ogl_device.h | 3 +++ core/mixer/image/image_kernel.cpp | 17 +++++++++++++++++ core/mixer/image/image_mixer.cpp | 13 +++++++++---- core/mixer/image/image_shader.cpp | 6 ++++-- core/producer/frame/image_transform.h | 1 + shell/casparcg.config | 19 ++++++++----------- 7 files changed, 54 insertions(+), 17 deletions(-) diff --git a/core/mixer/gpu/ogl_device.cpp b/core/mixer/gpu/ogl_device.cpp index 7196af356..d74d5fd96 100644 --- a/core/mixer/gpu/ogl_device.cpp +++ b/core/mixer/gpu/ogl_device.cpp @@ -44,6 +44,7 @@ ogl_device::ogl_device() std::fill(binded_textures_.begin(), binded_textures_.end(), 0); std::fill(viewport_.begin(), viewport_.end(), 0); std::fill(scissor_.begin(), scissor_.end(), 0); + std::fill(blend_func_.begin(), blend_func_.end(), 0); invoke([=] { @@ -335,5 +336,16 @@ void ogl_device::use(shader& shader) } } +void ogl_device::blend_func_separate(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); + } +} + }} diff --git a/core/mixer/gpu/ogl_device.h b/core/mixer/gpu/ogl_device.h index 4b709e7ad..ad5908c3b 100644 --- a/core/mixer/gpu/ogl_device.h +++ b/core/mixer/gpu/ogl_device.h @@ -65,6 +65,7 @@ class ogl_device : boost::noncopyable GLint attached_texture_; GLint active_shader_; std::array binded_textures_; + std::array blend_func_; std::unique_ptr context_; @@ -91,6 +92,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 use(shader& shader); diff --git a/core/mixer/image/image_kernel.cpp b/core/mixer/image/image_kernel.cpp index 31e7440ff..b2b03475b 100644 --- a/core/mixer/image/image_kernel.cpp +++ b/core/mixer/image/image_kernel.cpp @@ -121,6 +121,23 @@ struct image_kernel::implementation : boost::noncopyable shader_->set("background", texture_id::background); shader_->set("blend_mode", item.transform.get_is_key() ? core::image_transform::blend_mode::normal : item.transform.get_blend_mode()); } + else + { + switch(item.transform.get_blend_mode()) + { + case image_transform::blend_mode::add: + ogl.blend_func_separate(GL_ONE, GL_ONE, GL_ONE, GL_ONE); + break; + case image_transform::blend_mode::replace: + ogl.blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE); + break; + case image_transform::blend_mode::screen: + ogl.blend_func_separate(GL_ONE, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE); + default: + ogl.blend_func_separate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + break; + } + } // Setup image-adjustements diff --git a/core/mixer/image/image_mixer.cpp b/core/mixer/image/image_mixer.cpp index ff470cc82..f82f60cd4 100644 --- a/core/mixer/image/image_mixer.cpp +++ b/core/mixer/image/image_mixer.cpp @@ -156,10 +156,15 @@ public: { auto local_draw_buffer = create_device_buffer(4); - BOOST_FOREACH(auto& item, layer) + // First item should just be "copied" to empty framebuffer. + auto item = layer.begin(); + item->transform.set_blend_mode(image_transform::blend_mode::replace); + draw_item(std::move(*item++), local_draw_buffer, local_key_buffer, layer_key_buffer); + + for(; item != layer.end(); ++item) { - item.transform.set_blend_mode(image_transform::blend_mode::normal); // Disable blending, it will be used when merging back into render stack. - draw_item(std::move(item), local_draw_buffer, local_key_buffer, layer_key_buffer); + item->transform.set_blend_mode(image_transform::blend_mode::normal); // Disable blending, it will be used when merging back into render stack. + draw_item(std::move(*item), local_draw_buffer, local_key_buffer, layer_key_buffer); } kernel_.draw(channel_.ogl(), create_render_item(local_draw_buffer, layer.front().transform.get_blend_mode()), draw_buffer, nullptr, nullptr); @@ -211,7 +216,7 @@ public: // TODO: Optimize bool has_overlapping_items(const layer& layer, image_transform::blend_mode::type blend_mode) { - if(layer.empty()) + if(layer.size() < 2) return false; implementation::layer fill; diff --git a/core/mixer/image/image_shader.cpp b/core/mixer/image/image_shader.cpp index 781ea9b83..23f7666d2 100644 --- a/core/mixer/image/image_shader.cpp +++ b/core/mixer/image/image_shader.cpp @@ -69,9 +69,11 @@ std::string get_blend_color_func() " \n" "vec4 blend(vec4 fore) \n" "{ \n" - " vec4 back = texture2D(background, gl_TexCoord[1].st); \n" + " if(blend_mode == 29) // replace \n" + " return fore; \n" + " vec4 back = texture2D(background, gl_TexCoord[1].st).bgra; \n" " fore.rgb = get_blend_color(back.rgb, fore.rgb); \n" - " return vec4(mix(back.bgr, fore.rgb, fore.a), back.a + fore.a); \n" + " return vec4(mix(back.rgb, fore.rgb, fore.a), back.a + fore.a); \n" "} \n"; } diff --git a/core/producer/frame/image_transform.h b/core/producer/frame/image_transform.h index 1d1e33c54..df24a689d 100644 --- a/core/producer/frame/image_transform.h +++ b/core/producer/frame/image_transform.h @@ -66,6 +66,7 @@ public: saturation, color, luminosity, + replace, blend_mode_count }; }; diff --git a/shell/casparcg.config b/shell/casparcg.config index dc79cda0c..c39dd970e 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -12,6 +12,9 @@ 3 + + true + 1 true @@ -46,23 +49,17 @@ - 1080i5000 + 720p5000 1 true true - - - - 1080i5000 - - - 2 - true - true - + + 1 + true + -- 2.39.2