]> git.sesse.net Git - casparcg/blob - accelerator/ogl/image/image_shader.cpp
* added geometry to frames for custom rendering
[casparcg] / accelerator / ogl / image / image_shader.cpp
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Robert Nagy, ronag89@gmail.com
20 */
21
22 #include "../../stdafx.h"
23
24 #include "image_shader.h"
25
26 #include "../util/shader.h"
27 #include "../util/device.h"
28
29 #include "blending_glsl.h"
30
31 #include <common/gl/gl_check.h>
32 #include <common/env.h>
33
34 #include <tbb/mutex.h>
35
36 namespace caspar { namespace accelerator { namespace ogl {
37
38 std::shared_ptr<shader> g_shader;
39 tbb::mutex                              g_shader_mutex;
40 bool                                    g_blend_modes = false;
41
42 std::string get_blend_color_func()
43 {
44         return 
45                         
46         get_adjustement_glsl()
47                 
48         +
49
50         get_blend_glsl()
51                 
52         +
53                         
54         "vec3 get_blend_color(vec3 back, vec3 fore)                                                                                     \n"
55         "{                                                                                                                                                                      \n"
56         "       switch(blend_mode)                                                                                                                              \n"
57         "       {                                                                                                                                                               \n"
58         "       case  0: return BlendNormal(back, fore);                                                                                \n"
59         "       case  1: return BlendLighten(back, fore);                                                                               \n"
60         "       case  2: return BlendDarken(back, fore);                                                                                \n"
61         "       case  3: return BlendMultiply(back, fore);                                                                              \n"
62         "       case  4: return BlendAverage(back, fore);                                                                               \n"
63         "       case  5: return BlendAdd(back, fore);                                                                                   \n"
64         "       case  6: return BlendSubstract(back, fore);                                                                             \n"
65         "       case  7: return BlendDifference(back, fore);                                                                    \n"
66         "       case  8: return BlendNegation(back, fore);                                                                              \n"
67         "       case  9: return BlendExclusion(back, fore);                                                                             \n"
68         "       case 10: return BlendScreen(back, fore);                                                                                \n"
69         "       case 11: return BlendOverlay(back, fore);                                                                               \n"
70         //"     case 12: return BlendSoftLight(back, fore);                                                                             \n"
71         "       case 13: return BlendHardLight(back, fore);                                                                             \n"
72         "       case 14: return BlendColorDodge(back, fore);                                                                    \n"
73         "       case 15: return BlendColorBurn(back, fore);                                                                             \n"
74         "       case 16: return BlendLinearDodge(back, fore);                                                                   \n"
75         "       case 17: return BlendLinearBurn(back, fore);                                                                    \n"
76         "       case 18: return BlendLinearLight(back, fore);                                                                   \n"
77         "       case 19: return BlendVividLight(back, fore);                                                                    \n"
78         "       case 20: return BlendPinLight(back, fore);                                                                              \n"
79         "       case 21: return BlendHardMix(back, fore);                                                                               \n"
80         "       case 22: return BlendReflect(back, fore);                                                                               \n"
81         "       case 23: return BlendGlow(back, fore);                                                                                  \n"
82         "       case 24: return BlendPhoenix(back, fore);                                                                               \n"
83         "       case 25: return BlendHue(back, fore);                                                                                   \n"
84         "       case 26: return BlendSaturation(back, fore);                                                                    \n"
85         "       case 27: return BlendColor(back, fore);                                                                                 \n"
86         "       case 28: return BlendLuminosity(back, fore);                                                                    \n"
87         "       }                                                                                                                                                               \n"
88         "       return BlendNormal(back, fore);                                                                                                 \n"
89         "}                                                                                                                                                                      \n"
90         "                                                                                                                                                                       \n"                                                                                                                                                       
91         "vec4 blend(vec4 fore)                                                                                                                          \n"
92         "{                                                                                                                                                                      \n"
93         "   vec4 back = texture2D(background, gl_TexCoord[1].st).bgra;                                          \n"
94         "   if(blend_mode != 0)                                                                                                                         \n"
95         "               fore.rgb = get_blend_color(back.rgb/(back.a+0.0000001), fore.rgb/(fore.a+0.0000001))*fore.a;\n"
96         "       switch(keyer)                                                                                                                                   \n"     
97         "       {                                                                                                                                                               \n"     
98         "               case 1:  return fore + back; // additive                                                                        \n"
99         "               default: return fore + (1.0-fore.a)*back; // linear                                                     \n"
100         "       }                                                                                                                                                               \n"
101         "}                                                                                                                                                                      \n";                    
102 }
103                 
104 std::string get_simple_blend_color_func()
105 {
106         return  
107                 
108         get_adjustement_glsl()
109                         
110         +
111
112         "vec4 blend(vec4 fore)                                                                                                                          \n"
113         "{                                                                                                                                                                      \n"
114         "       return fore;                                                                                                                                    \n"
115         "}                                                                                                                                                                      \n";
116 }
117
118 std::string get_vertex()
119 {
120         return 
121
122         "void main()                                                                                                                                            \n"
123         "{                                                                                                                                                                      \n"
124         "       gl_TexCoord[0] = gl_MultiTexCoord0;                                                                                             \n"
125 //      "       gl_TexCoord[1] = gl_MultiTexCoord1;                                                                                             \n"
126         "       vec4 pos = ftransform();                                                                                                                \n"
127         "       gl_TexCoord[1] = vec4(pos.xy, 0.0, 0.0);                                                                                \n"
128         "       pos.x = pos.x*2.0 - 1.0;                                                                                                                \n"
129         "       pos.y = pos.y*2.0 - 1.0;                                                                                                                \n"
130         "       gl_Position    = pos;                                                                                                                   \n"
131         "}                                                                                                                                                                      \n";
132 }
133
134 std::string get_fragment(bool blend_modes)
135 {
136         return
137
138         "#version 130                                                                                                                                           \n"
139         "uniform sampler2D      background;                                                                                                             \n"
140         "uniform sampler2D      plane[4];                                                                                                               \n"
141         "uniform vec2           plane_size[4];                                                                                                  \n"
142         "uniform sampler2D      local_key;                                                                                                              \n"
143         "uniform sampler2D      layer_key;                                                                                                              \n"
144         "                                                                                                                                                                       \n"
145         "uniform bool           is_hd;                                                                                                                  \n"
146         "uniform bool           has_local_key;                                                                                                  \n"
147         "uniform bool           has_layer_key;                                                                                                  \n"
148         "uniform int            blend_mode;                                                                                                             \n"
149         "uniform int            keyer;                                                                                                                  \n"
150         "uniform int            pixel_format;                                                                                                   \n"
151         "uniform int            deinterlace;                                                                                                    \n"
152         "                                                                                                                                                                       \n"
153         "uniform float          opacity;                                                                                                                \n"
154         "uniform bool           levels;                                                                                                                 \n"
155         "uniform float          min_input;                                                                                                              \n"
156         "uniform float          max_input;                                                                                                              \n"
157         "uniform float          gamma;                                                                                                                  \n"
158         "uniform float          min_output;                                                                                                             \n"
159         "uniform float          max_output;                                                                                                             \n"
160         "                                                                                                                                                                       \n"
161         "uniform bool           csb;                                                                                                                    \n"
162         "uniform float          brt;                                                                                                                    \n"
163         "uniform float          sat;                                                                                                                    \n"
164         "uniform float          con;                                                                                                                    \n"
165         "                                                                                                                                                                       \n"     
166
167         +
168                 
169         (blend_modes ? get_blend_color_func() : get_simple_blend_color_func())
170
171         +
172         
173         "                                                                                                                                                                       \n"
174         "vec4 ycbcra_to_rgba_sd(float Y, float Cb, float Cr, float A)                                           \n"
175         "{                                                                                                                                                                      \n"
176         "   vec4 rgba;                                                                                                                                          \n"
177         "   rgba.b = (1.164*(Y*255 - 16) + 1.596*(Cr*255 - 128))/255;                                           \n"
178         "   rgba.g = (1.164*(Y*255 - 16) - 0.813*(Cr*255 - 128) - 0.391*(Cb*255 - 128))/255;\n"
179         "   rgba.r = (1.164*(Y*255 - 16) + 2.018*(Cb*255 - 128))/255;                                           \n"
180         "   rgba.a = A;                                                                                                                                         \n"
181         "       return rgba;                                                                                                                                    \n"     
182         "}                                                                                                                                                                      \n"                     
183         "                                                                                                                                                                       \n"
184         "vec4 ycbcra_to_rgba_hd(float Y, float Cb, float Cr, float A)                                           \n"
185         "{                                                                                                                                                                      \n"
186         "   vec4 rgba;                                                                                                                                          \n"
187         "   rgba.b = (1.164*(Y*255 - 16) + 1.793*(Cr*255 - 128))/255;                                           \n"
188         "   rgba.g = (1.164*(Y*255 - 16) - 0.534*(Cr*255 - 128) - 0.213*(Cb*255 - 128))/255;\n"
189         "   rgba.r = (1.164*(Y*255 - 16) + 2.115*(Cb*255 - 128))/255;                                           \n"
190         "   rgba.a = A;                                                                                                                                         \n"
191         "       return rgba;                                                                                                                                    \n"
192         "}                                                                                                                                                                      \n"                                     
193         "                                                                                                                                                                       \n"             
194         "vec4 ycbcra_to_rgba(float y, float cb, float cr, float a)                                                      \n"
195         "{                                                                                                                                                                      \n"
196         "       if(is_hd)                                                                                                                                               \n"
197         "               return ycbcra_to_rgba_hd(y, cb, cr, a);                                                                         \n"
198         "       else                                                                                                                                                    \n"
199         "               return ycbcra_to_rgba_sd(y, cb, cr, a);                                                                         \n"
200         "}                                                                                                                                                                      \n"
201         "                                                                                                                                                                       \n"
202         "vec4 get_sample(sampler2D sampler, vec2 coords, vec2 size)                                                     \n"
203         "{                                                                                                                                                                      \n"
204         "       switch(deinterlace)                                                                                                                             \n"
205         "       {                                                                                                                                                               \n"
206         "       case 1: // upper                                                                                                                                \n"
207         "               return texture2D(sampler, coords);                                                                                      \n"
208         "       case 2: // lower                                                                                                                                \n"
209         "               return texture2D(sampler, coords);                                                                                      \n"
210         "       default:                                                                                                                                                \n"
211         "               return texture2D(sampler, coords);                                                                                      \n"
212         "       }                                                                                                                                                               \n"
213         "}                                                                                                                                                                      \n"
214         "                                                                                                                                                                       \n"
215         "vec4 get_rgba_color()                                                                                                                          \n"
216         "{                                                                                                                                                                      \n"
217         "       switch(pixel_format)                                                                                                                    \n"
218         "       {                                                                                                                                                               \n"
219         "       case 0:         //gray                                                                                                                          \n"
220         "               return vec4(get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).rrr, 1.0);\n"
221         "       case 1:         //bgra,                                                                                                                         \n"
222         "               return get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).bgra;                     \n"
223         "       case 2:         //rgba,                                                                                                                         \n"
224         "               return get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).rgba;                     \n"
225         "       case 3:         //argb,                                                                                                                         \n"
226         "               return get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).argb;                     \n"
227         "       case 4:         //abgr,                                                                                                                         \n"
228         "               return get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).gbar;                     \n"
229         "       case 5:         //ycbcr,                                                                                                                        \n"
230         "               {                                                                                                                                                       \n"
231         "                       float y  = get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).r;    \n"
232         "                       float cb = get_sample(plane[1], gl_TexCoord[0].st, plane_size[0]).r;    \n"
233         "                       float cr = get_sample(plane[2], gl_TexCoord[0].st, plane_size[0]).r;    \n"
234         "                       return ycbcra_to_rgba(y, cb, cr, 1.0);                                                                  \n"
235         "               }                                                                                                                                                       \n"
236         "       case 6:         //ycbcra                                                                                                                        \n"
237         "               {                                                                                                                                                       \n"
238         "                       float y  = get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).r;    \n"
239         "                       float cb = get_sample(plane[1], gl_TexCoord[0].st, plane_size[0]).r;    \n"
240         "                       float cr = get_sample(plane[2], gl_TexCoord[0].st, plane_size[0]).r;    \n"
241         "                       float a  = get_sample(plane[3], gl_TexCoord[0].st, plane_size[0]).r;    \n"
242         "                       return ycbcra_to_rgba(y, cb, cr, a);                                                                    \n"
243         "               }                                                                                                                                                       \n"
244         "       case 7:         //luma                                                                                                                          \n"
245         "               {                                                                                                                                                       \n"
246         "                       vec3 y3 = get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).rrr;   \n"
247         "                       return vec4((y3-0.065)/0.859, 1.0);                                                                             \n"
248         "               }                                                                                                                                                       \n"
249         "       case 8:         //bgr,                                                                                                                          \n"
250         "               return vec4(get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).bgr, 1.0);\n"
251         "       case 9:         //rgb,                                                                                                                          \n"
252         "               return vec4(get_sample(plane[0], gl_TexCoord[0].st, plane_size[0]).rgb, 1.0);\n"
253         "       }                                                                                                                                                               \n"
254         "       return vec4(0.0, 0.0, 0.0, 0.0);                                                                                                \n"
255         "}                                                                                                                                                                      \n"
256         "                                                                                                                                                                       \n"
257         "void main()                                                                                                                                            \n"
258         "{                                                                                                                                                                      \n"
259         "       vec4 color = get_rgba_color();                                                                                                  \n"
260         "   if(levels)                                                                                                                                          \n"
261         "               color.rgb = LevelsControl(color.rgb, min_input, max_input, gamma, min_output, max_output); \n"
262         "       if(csb)                                                                                                                                                 \n"
263         "               color.rgb = ContrastSaturationBrightness(color.rgb, brt, sat, con);                     \n"
264         "       if(has_local_key)                                                                                                                               \n"
265         "               color *= texture2D(local_key, gl_TexCoord[1].st).r;                                                     \n"
266         "       if(has_layer_key)                                                                                                                               \n"
267         "               color *= texture2D(layer_key, gl_TexCoord[1].st).r;                                                     \n"
268         "       color *= opacity;                                                                                                                               \n"
269         "       color = blend(color);                                                                                                                   \n"
270         "       gl_FragColor = color.bgra;                                                                                                              \n"
271         "}                                                                                                                                                                      \n";
272 }
273
274 spl::shared_ptr<shader> get_image_shader(bool& blend_modes)
275 {
276         tbb::mutex::scoped_lock lock(g_shader_mutex);
277
278         if(g_shader)
279         {
280                 blend_modes = g_blend_modes;
281                 return spl::make_shared_ptr(g_shader);
282         }
283                 
284         try
285         {                               
286                 g_blend_modes  = glTextureBarrierNV ? env::properties().get(L"configuration.blend-modes", true) : false;
287                 g_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)));
288         }
289         catch(...)
290         {
291                 CASPAR_LOG_CURRENT_EXCEPTION();
292                 CASPAR_LOG(warning) << "Failed to compile shader. Trying to compile without blend-modes.";
293                                 
294                 g_blend_modes = false;
295                 g_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes)));
296         }
297                                                 
298         //if(!g_blend_modes)
299         //{
300         //      ogl.blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
301         //      CASPAR_LOG(info) << L"[shader] Blend-modes are disabled.";
302         //}
303
304         blend_modes = g_blend_modes;
305         return spl::make_shared_ptr(g_shader);
306 }
307
308 }}}