]> git.sesse.net Git - casparcg/blobdiff - accelerator/ogl/image/image_shader.cpp
[mixer] Merged fixed from 2.0 where contrast adjustment incorrectly worked on premult...
[casparcg] / accelerator / ogl / image / image_shader.cpp
index f9b49f03e97141936dcc4b6e67cbf644fc3a2588..96753a5a4497ab7ccb6f70f46247fe823bd9a93f 100644 (file)
@@ -37,7 +37,8 @@ namespace caspar { namespace accelerator { namespace ogl {
 
 std::weak_ptr<shader>  g_shader;
 tbb::mutex                             g_shader_mutex;
-bool                                   g_blend_modes = false;
+bool                                   g_blend_modes           = false;
+bool                                   g_post_processing       = false;
 
 std::string get_blend_color_func()
 {
@@ -102,7 +103,7 @@ std::string get_blend_color_func()
                                }
                )shader";
 }
-               
+
 std::string get_simple_blend_color_func()
 {
        return
@@ -124,24 +125,33 @@ std::string get_chroma_func()
        return
 
                get_chroma_glsl()
-               
+
                +
-               
+
                R"shader(
                                vec4 chroma_key(vec4 c)
                                {
-                                       switch (chroma_mode)
-                                       {
-                                       case 0: return c;
-                                       case 1: return ChromaOnGreen(c.bgra).bgra;
-                                       case 2: return ChromaOnBlue(c.bgra).bgra;
-                                       }
-
-                                       return c;
+                                       return ChromaOnCustomColor(c.bgra).bgra;
                                }
                )shader";
 }
 
+std::string get_post_process()
+{
+       return R"shader(
+               if (post_processing)
+               {
+                       gl_FragColor = post_process().bgra;
+               }
+               else
+       )shader";
+}
+
+std::string get_no_post_process()
+{
+       return "";
+}
+
 std::string get_vertex()
 {
        return R"shader(
@@ -158,7 +168,7 @@ std::string get_vertex()
        )shader";
 }
 
-std::string get_fragment(bool blend_modes)
+std::string get_fragment(bool blend_modes, bool post_processing)
 {
        return R"shader(
 
@@ -190,9 +200,18 @@ std::string get_fragment(bool blend_modes)
                        uniform float           sat;
                        uniform float           con;
 
-                       uniform int                     chroma_mode;
-                       uniform vec2            chroma_blend;
-                       uniform float           chroma_spill;
+                       uniform bool            post_processing;
+                       uniform bool            straighten_alpha;
+
+                       uniform bool            chroma;
+                       uniform bool            chroma_show_mask;
+                       uniform float           chroma_target_hue;
+                       uniform float           chroma_hue_width;
+                       uniform float           chroma_min_saturation;
+                       uniform float           chroma_min_brightness;
+                       uniform float           chroma_softness;
+                       uniform float           chroma_spill_suppress;
+                       uniform float           chroma_spill_suppress_saturation;
        )shader"
 
        +
@@ -290,27 +309,53 @@ std::string get_fragment(bool blend_modes)
                                return vec4(0.0, 0.0, 0.0, 0.0);
                        }
 
+                       vec4 post_process()
+                       {
+                               vec4 color = texture2D(background, gl_TexCoord[0].st).bgra;
+
+                               if (straighten_alpha)
+                                       color.rgb /= color.a + 0.0000001;
+
+                               return color;
+                       }
+
                        void main()
                        {
-                               vec4 color = get_rgba_color();
-                               color = chroma_key(color);
-                               if(levels)
-                                       color.rgb = LevelsControl(color.rgb, min_input, gamma, max_input, min_output, max_output);
-                               if(csb)
-                                       color.rgb = ContrastSaturationBrightness(color.rgb, brt, sat, con);
-                               if(has_local_key)
-                                       color *= texture2D(local_key, gl_TexCoord[1].st).r;
-                               if(has_layer_key)
-                                       color *= texture2D(layer_key, gl_TexCoord[1].st).r;
-                               color *= opacity;
-                               color = blend(color);
-                               gl_FragColor = color.bgra;
+       )shader"
+
+       +
+
+       (post_processing ? get_post_process() : get_no_post_process())
+
+       +
+
+       R"shader(
+                               {
+                                       vec4 color = get_rgba_color();
+                                       if (chroma)
+                                               color = chroma_key(color);
+                                       if(levels)
+                                               color.rgb = LevelsControl(color.rgb, min_input, gamma, max_input, min_output, max_output);
+                                       if(csb)
+                                               color.rgb = ContrastSaturationBrightness(color, brt, sat, con);
+                                       if(has_local_key)
+                                               color *= texture2D(local_key, gl_TexCoord[1].st).r;
+                                       if(has_layer_key)
+                                               color *= texture2D(layer_key, gl_TexCoord[1].st).r;
+                                       color *= opacity;
+                                       color = blend(color);
+                                       gl_FragColor = color.bgra;
+                               }
                        }
        )shader";
 }
 
 std::shared_ptr<shader> get_image_shader(
-               const spl::shared_ptr<device>& ogl, bool& blend_modes, bool blend_modes_wanted)
+               const spl::shared_ptr<device>& ogl,
+               bool& blend_modes,
+               bool blend_modes_wanted,
+               bool& post_processing,
+               bool straight_alpha_wanted)
 {
        tbb::mutex::scoped_lock lock(g_shader_mutex);
        auto existing_shader = g_shader.lock();
@@ -318,6 +363,7 @@ std::shared_ptr<shader> get_image_shader(
        if(existing_shader)
        {
                blend_modes = g_blend_modes;
+               post_processing = g_post_processing;
                return existing_shader;
        }
 
@@ -335,21 +381,22 @@ std::shared_ptr<shader> get_image_shader(
                                delete p;
                        });
        };
-               
+
        try
-       {                               
+       {
                g_blend_modes  = glTextureBarrierNV ? blend_modes_wanted : false;
-               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)), deleter);
+               g_post_processing = straight_alpha_wanted;
+               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes, g_post_processing)), deleter);
        }
        catch(...)
        {
                CASPAR_LOG_CURRENT_EXCEPTION();
                CASPAR_LOG(warning) << "Failed to compile shader. Trying to compile without blend-modes.";
-                               
+
                g_blend_modes = false;
-               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)), deleter);
+               existing_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes, g_post_processing)), deleter);
        }
-                                               
+
        //if(!g_blend_modes)
        //{
        //      ogl.blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
@@ -358,6 +405,7 @@ std::shared_ptr<shader> get_image_shader(
 
 
        blend_modes = g_blend_modes;
+       post_processing = g_post_processing;
        g_shader = existing_shader;
        return existing_shader;
 }