]> git.sesse.net Git - casparcg/blob - core/mixer/image/image_kernel.cpp
2.0. image_mixer: Implemeted blending modes. Optimized transition rendering to O...
[casparcg] / core / mixer / image / image_kernel.cpp
1 /*\r
2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 *  This file is part of CasparCG.\r
5 *\r
6 *    CasparCG is free software: you can redistribute it and/or modify\r
7 *    it under the terms of the GNU General Public License as published by\r
8 *    the Free Software Foundation, either version 3 of the License, or\r
9 *    (at your option) any later version.\r
10 *\r
11 *    CasparCG is distributed in the hope that it will be useful,\r
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 *    GNU General Public License for more details.\r
15 \r
16 *    You should have received a copy of the GNU General Public License\r
17 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 */\r
20 #include "../../stdafx.h"\r
21 \r
22 #include "image_kernel.h"\r
23 #include "blending_glsl.h"\r
24 \r
25 #include <common/exception/exceptions.h>\r
26 #include <common/gl/gl_check.h>\r
27 \r
28 #include <core/video_format.h>\r
29 #include <core/producer/frame/pixel_format.h>\r
30 #include <core/producer/frame/image_transform.h>\r
31 \r
32 #include <boost/noncopyable.hpp>\r
33 \r
34 #include <unordered_map>\r
35 \r
36 namespace caspar { namespace core {\r
37 \r
38 class shader_program : boost::noncopyable\r
39 {\r
40         GLuint program_;\r
41 public:\r
42 \r
43         shader_program() : program_(0) {}\r
44         shader_program(shader_program&& other) : program_(other.program_){other.program_ = 0;}\r
45         shader_program(const std::string& vertex_source_str, const std::string& fragment_source_str) : program_(0)\r
46         {\r
47                 GLint success;\r
48         \r
49                 const char* vertex_source = vertex_source_str.c_str();\r
50                                                 \r
51                 auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
52                                         \r
53                 GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
54                 GL(glCompileShaderARB(vertex_shader));\r
55 \r
56                 GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
57                 if (success == GL_FALSE)\r
58                 {\r
59                         char info[2048];\r
60                         GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
61                         GL(glDeleteObjectARB(vertex_shader));\r
62                         std::stringstream str;\r
63                         str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
64                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
65                 }\r
66                         \r
67                 const char* fragment_source = fragment_source_str.c_str();\r
68                                                 \r
69                 auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
70                                         \r
71                 GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
72                 GL(glCompileShaderARB(fragmemt_shader));\r
73 \r
74                 GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
75                 if (success == GL_FALSE)\r
76                 {\r
77                         char info[2048];\r
78                         GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
79                         GL(glDeleteObjectARB(fragmemt_shader));\r
80                         std::stringstream str;\r
81                         str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
82                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
83                 }\r
84                         \r
85                 program_ = glCreateProgramObjectARB();\r
86                         \r
87                 GL(glAttachObjectARB(program_, vertex_shader));\r
88                 GL(glAttachObjectARB(program_, fragmemt_shader));\r
89 \r
90                 GL(glLinkProgramARB(program_));\r
91                         \r
92                 GL(glDeleteObjectARB(vertex_shader));\r
93                 GL(glDeleteObjectARB(fragmemt_shader));\r
94 \r
95                 GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
96                 if (success == GL_FALSE)\r
97                 {\r
98                         char info[2048];\r
99                         GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
100                         GL(glDeleteObjectARB(program_));\r
101                         std::stringstream str;\r
102                         str << "Failed to link shader program:" << std::endl << info << std::endl;\r
103                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
104                 }\r
105                 GL(glUseProgramObjectARB(program_));\r
106                 glUniform1i(glGetUniformLocation(program_, "plane[0]"), 0);\r
107                 glUniform1i(glGetUniformLocation(program_, "plane[1]"), 1);\r
108                 glUniform1i(glGetUniformLocation(program_, "plane[2]"), 2);\r
109                 glUniform1i(glGetUniformLocation(program_, "plane[3]"), 3);\r
110                 glUniform1i(glGetUniformLocation(program_, "plane[4]"), 4);\r
111                 glUniform1i(glGetUniformLocation(program_, "plane[5]"), 5);\r
112         }\r
113 \r
114         GLint get_location(const char* name)\r
115         {\r
116                 GLint loc = glGetUniformLocation(program_, name);\r
117                 return loc;\r
118         }\r
119 \r
120         shader_program& operator=(shader_program&& other) \r
121         {\r
122                 program_ = other.program_; \r
123                 other.program_ = 0; \r
124                 return *this;\r
125         }\r
126 \r
127         ~shader_program()\r
128         {\r
129                 glDeleteProgram(program_);\r
130         }\r
131 \r
132         void use()\r
133         {       \r
134                 GL(glUseProgramObjectARB(program_));            \r
135         }\r
136 };\r
137 \r
138 GLubyte progressive_pattern[] = {\r
139         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
140         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
141         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
142         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
143         \r
144 GLubyte upper_pattern[] = {\r
145         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
146         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
147         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
148         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
149                 \r
150 GLubyte lower_pattern[] = {\r
151         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
152         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
153         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
154         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
155 \r
156 struct image_kernel::implementation : boost::noncopyable\r
157 {       \r
158         std::unordered_map<core::pixel_format::type, shader_program> shaders_;\r
159 \r
160 public:\r
161         std::unordered_map<core::pixel_format::type, shader_program>& shaders()\r
162         {\r
163                 GL(glEnable(GL_POLYGON_STIPPLE));\r
164 \r
165                 if(shaders_.empty())\r
166                 {\r
167                 std::string common_vertex = \r
168                         "void main()                                                                                                                    "\r
169                         "{                                                                                                                                              "\r
170                         "       gl_TexCoord[0] = gl_MultiTexCoord0;                                                                     "\r
171                         "       gl_TexCoord[1] = gl_MultiTexCoord1;                                                                     "\r
172                         "       gl_FrontColor = gl_Color;                                                                                       "\r
173                         "       gl_Position = ftransform();                                                                                     "\r
174                         "}                                                                                                                                              ";\r
175 \r
176                 std::string common_fragment = std::string() +\r
177                         "uniform sampler2D      plane[6];                                                                                       "\r
178                         "uniform float          gain;                                                                                           "\r
179                         "uniform bool           HD;                                                                                                     "\r
180                         "uniform bool           local_key;                                                                                      "\r
181                         "uniform bool           layer_key;                                                                                      "\r
182                         "uniform int            blend_mode;                                                                                     "\r
183 \r
184                         +\r
185 \r
186                         get_blend_glsl()\r
187 \r
188                         +\r
189 \r
190                         "\nvec3 get_blend_color(vec3 back, vec3 fore)                                                             "\r
191                         "\n{                                                                                                                                              "\r
192                         "\n     switch(blend_mode)                                                                                                                "\r
193                         "\n     {                                                                                                                                                 "\r
194                         "\n     case  0: return BlendNormal(back, fore);                                                                  "\r
195                         "\n     case  1: return BlendLighten(back, fore);                                                                 "\r
196                         "\n     case  2: return BlendDarken(back, fore);                                                                  "\r
197                         "\n     case  3: return BlendMultiply(back, fore);                                                                "\r
198                         "\n     case  4: return BlendAverage(back, fore);                                                                 "\r
199                         "\n     case  5: return BlendAdd(back, fore);                                                                     "\r
200                         "\n     case  6: return BlendSubstract(back, fore);                                                               "\r
201                         "\n     case  7: return BlendDifference(back, fore);                                                      "\r
202                         "\n     case  8: return BlendNegation(back, fore);                                                                "\r
203                         "\n     case  9: return BlendExclusion(back, fore);                                                               "\r
204                         "\n     case 10: return BlendScreen(back, fore);                                                                  "\r
205                         "\n     case 11: return BlendOverlay(back, fore);                                                                 "\r
206                         //"\n   case 12: return BlendSoftLight(back, fore);                                                               "\r
207                         //"\n   case 13: return BlendHardLight(back, fore);                                                               "\r
208                         "\n     case 14: return BlendColorDodge(back, fore);                                                      "\r
209                         "\n     case 15: return BlendColorBurn(back, fore);                                                               "\r
210                         "\n     case 16: return BlendLinearDodge(back, fore);                                                     "\r
211                         "\n     case 17: return BlendLinearBurn(back, fore);                                                      "\r
212                         "\n     case 18: return BlendLinearLight(back, fore);                                                     "\r
213                         "\n     case 19: return BlendVividLight(back, fore);                                                      "\r
214                         "\n     case 20: return BlendPinLight(back, fore);                                                                "\r
215                         "\n     case 21: return BlendHardMix(back, fore);                                                                 "\r
216                         "\n     case 22: return BlendReflect(back, fore);                                                                 "\r
217                         "\n     case 23: return BlendGlow(back, fore);                                                                    "\r
218                         "\n     case 24: return BlendPhoenix(back, fore);                                                                 "\r
219                         "\n case 25: return BlendHue(back, fore);                                                                         "\r
220                         "\n case 26: return BlendSaturation(back, fore);                                                          "\r
221                         "\n case 27: return BlendColor(back, fore);                                                               "\r
222                         "\n case 28: return BlendLuminosity(back, fore);                                                          "\r
223                         "\n     }                                                                                                                                                 "\r
224                         "\n                                                                                                                                                       "\r
225                         "\n     return BlendNormal(back, fore);                                                                                   "\r
226                         "\n}                                                                                                                                                      "\r
227                                                                                                                                                                                   \r
228                         "vec4 get_color(vec4 fore)                                                                                                                "\r
229                         "{                                                                                                                                                                "\r
230                         "   vec4 back = texture2D(plane[5], gl_TexCoord[1].st);                                                   "\r
231                         "   fore.rgb = get_blend_color(back.rgb, fore.rgb);"\r
232                         "       return vec4(fore.rgb * fore.a + back.rgb * (1.0-fore.a), back.a + fore.a);"\r
233                         "}                                                                                                                                                                "\r
234                                                                                                                                                                 \r
235                         // NOTE: YCbCr, ITU-R, http://www.intersil.com/data/an/an9717.pdf               \r
236                         // TODO: Support for more yuv formats might be needed.                                  \r
237                         "vec4 ycbcra_to_bgra_sd(float y, float cb, float cr, float a)                   "\r
238                         "{                                                                                                                                              "\r
239                         "       cb -= 0.5;                                                                                                                      "\r
240                         "       cr -= 0.5;                                                                                                                      "\r
241                         "       y = 1.164*(y-0.0625);                                                                                           "\r
242                         "                                                                                                                                               "\r
243                         "       vec4 color;                                                                                                                     "\r
244                         "       color.r = y + 1.596 * cr;                                                                                       "\r
245                         "       color.g = y - 0.813 * cr - 0.391 * cb;                                                          "\r
246                         "       color.b = y + 2.018 * cb;                                                                                       "\r
247                         "       color.a = a;                                                                                                            "\r
248                         "                                                                                                                                               "\r
249                         "       return color;                                                                                                           "\r
250                         "}                                                                                                                                              "                       \r
251                         "                                                                                                                                               "\r
252 \r
253                         "vec4 ycbcra_to_bgra_hd(float y, float cb, float cr, float a)                   "\r
254                         "{                                                                                                                                              "\r
255                         "       cb -= 0.5;                                                                                                                      "\r
256                         "       cr -= 0.5;                                                                                                                      "\r
257                         "       y = 1.164*(y-0.0625);                                                                                           "\r
258                         "                                                                                                                                               "\r
259                         "       vec4 color;                                                                                                                     "\r
260                         "       color.r = y + 1.793 * cr;                                                                                       "\r
261                         "       color.g = y - 0.534 * cr - 0.213 * cb;                                                          "\r
262                         "       color.b = y + 2.115 * cb;                                                                                       "\r
263                         "       color.a = a;                                                                                                            "\r
264                         "                                                                                                                                               "\r
265                         "       return color;                                                                                                           "\r
266                         "}                                                                                                                                              "                       \r
267                         "                                                                                                                                               ";\r
268                         \r
269                 shaders_[core::pixel_format::gray] = shader_program(common_vertex, common_fragment +\r
270 \r
271                         "void main()                                                                                                                    "\r
272                         "{                                                                                                                                              "\r
273                         "       vec4 rgba = vec4(texture2D(plane[0], gl_TexCoord[0].st).rrr, 1.0);      "\r
274                         "       if(local_key)                                                                                                           "\r
275                         "               rgba.a *= texture2D(plane[3], gl_TexCoord[1].st).r;                             "\r
276                         "       if(layer_key)                                                                                                           "\r
277                         "               rgba.a *= texture2D(plane[4], gl_TexCoord[1].st).r;                             "\r
278                         "       gl_FragColor = get_color(rgba * gain);                                                                                  "\r
279                         "}                                                                                                                                              ");\r
280 \r
281                 shaders_[core::pixel_format::abgr] = shader_program(common_vertex, common_fragment +\r
282 \r
283                         "void main()                                                                                                                    "\r
284                         "{                                                                                                                                              "\r
285                         "       vec4 abgr = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
286                         "       if(local_key)                                                                                                           "\r
287                         "               abgr.b *= texture2D(plane[3], gl_TexCoord[1].st).r;                             "\r
288                         "       if(layer_key)                                                                                                           "\r
289                         "               abgr.b *= texture2D(plane[4], gl_TexCoord[1].st).r;                             "\r
290                         "       gl_FragColor = get_color(abgr.argb * gain);                                                                     "\r
291                         "}                                                                                                                                              ");\r
292                 \r
293                 shaders_[core::pixel_format::argb]= shader_program(common_vertex, common_fragment +\r
294 \r
295                         "void main()                                                                                                                    "       \r
296                         "{                                                                                                                                              "\r
297                         "       vec4 argb = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
298                         "       if(local_key)                                                                                                           "\r
299                         "               argb.b *= texture2D(plane[3], gl_TexCoord[1].st).r;                             "\r
300                         "       if(layer_key)                                                                                                           "\r
301                         "               argb.b *= texture2D(plane[4], gl_TexCoord[1].st).r;                             "\r
302                         "       gl_FragColor = get_color(argb.grab * gl_Color * gain);                                                  "\r
303                         "}                                                                                                                                              ");\r
304                 \r
305                 shaders_[core::pixel_format::bgra]= shader_program(common_vertex, common_fragment +\r
306 \r
307                         "void main()                                                                                                                    "\r
308                         "{                                                                                                                                              "\r
309                         "       vec4 bgra = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
310                         "       if(local_key)                                                                                                           "\r
311                         "               bgra.a *= texture2D(plane[3], gl_TexCoord[1].st).r;                             "\r
312                         "       if(layer_key)                                                                                                           "\r
313                         "               bgra.a *= texture2D(plane[4], gl_TexCoord[1].st).r;                             "\r
314                         "       gl_FragColor = get_color(bgra.rgba * gl_Color * gain);                                                  "\r
315                         "}                                                                                                                                              ");\r
316                 \r
317                 shaders_[core::pixel_format::rgba] = shader_program(common_vertex, common_fragment +\r
318 \r
319                         "void main()                                                                                                                    "\r
320                         "{                                                                                                                                              "\r
321                         "       vec4 rgba = texture2D(plane[0], gl_TexCoord[0].st);                                     "\r
322                         "       if(local_key)                                                                                                           "\r
323                         "               rgba.a *= texture2D(plane[3], gl_TexCoord[1].st).r;                             "\r
324                         "       if(layer_key)                                                                                                           "\r
325                         "               rgba.a *= texture2D(plane[4], gl_TexCoord[1].st).r;                             "\r
326                         "       gl_FragColor = get_color(rgba.bgra * gl_Color * gain);                                                  "\r
327                         "}                                                                                                                                              ");\r
328                 \r
329                 shaders_[core::pixel_format::ycbcr] = shader_program(common_vertex, common_fragment +\r
330 \r
331                         "void main()                                                                                                                    "\r
332                         "{                                                                                                                                              "\r
333                         "       float y  = texture2D(plane[0], gl_TexCoord[0].st).r;                            "\r
334                         "       float cb = texture2D(plane[1], gl_TexCoord[0].st).r;                            "\r
335                         "       float cr = texture2D(plane[2], gl_TexCoord[0].st).r;                            "\r
336                         "       float a = 1.0;                                                                                                          "       \r
337                         "       if(local_key)                                                                                                           "\r
338                         "               a *= texture2D(plane[3], gl_TexCoord[1].st).r;                                  "\r
339                         "       if(layer_key)                                                                                                           "\r
340                         "               a *= texture2D(plane[4], gl_TexCoord[1].st).r;                                  "\r
341                         "       if(HD)                                                                                                                          "\r
342                         "               gl_FragColor = get_color(ycbcra_to_bgra_hd(y, cb, cr, a) * gl_Color * gain);"\r
343                         "       else                                                                                                                            "\r
344                         "               gl_FragColor = get_color(ycbcra_to_bgra_sd(y, cb, cr, a) * gl_Color * gain);"\r
345                         "}                                                                                                                                              ");\r
346                 \r
347                 shaders_[core::pixel_format::ycbcra] = shader_program(common_vertex, common_fragment +\r
348 \r
349                         "void main()                                                                                                                    "\r
350                         "{                                                                                                                                              "\r
351                         "       float y  = texture2D(plane[0], gl_TexCoord[0].st).r;                            "\r
352                         "       float cb = texture2D(plane[1], gl_TexCoord[0].st).r;                            "\r
353                         "       float cr = texture2D(plane[2], gl_TexCoord[0].st).r;                            "\r
354                         "       float a  = texture2D(plane[3], gl_TexCoord[0].st).r;                            "\r
355                         "       if(local_key)                                                                                                           "\r
356                         "               a *= texture2D(plane[3], gl_TexCoord[1].st).r;                                  "\r
357                         "       if(layer_key)                                                                                                           "\r
358                         "               a *= texture2D(plane[4], gl_TexCoord[1].st).r;                                  "\r
359                         "       if(HD)                                                                                                                          "\r
360                         "               gl_FragColor = get_color(ycbcra_to_bgra_hd(y, cb, cr, a) * gl_Color * gain);"\r
361                         "       else                                                                                                                            "\r
362                         "               gl_FragColor = get_color(ycbcra_to_bgra_sd(y, cb, cr, a) * gl_Color * gain);"\r
363                         "}                                                                                                                                              ");\r
364                 }\r
365                 return shaders_;\r
366         }\r
367 };\r
368 \r
369 image_kernel::image_kernel() : impl_(new implementation()){}\r
370 \r
371 void image_kernel::draw(size_t width, size_t height, const core::pixel_format_desc& pix_desc, const core::image_transform& transform, bool local_key, bool layer_key)\r
372 {\r
373         GL(glEnable(GL_TEXTURE_2D));\r
374         GL(glDisable(GL_DEPTH_TEST));   \r
375         \r
376         if(transform.get_mode() == core::video_mode::upper)\r
377                 glPolygonStipple(upper_pattern);\r
378         else if(transform.get_mode() == core::video_mode::lower)\r
379                 glPolygonStipple(lower_pattern);\r
380         else\r
381                 glPolygonStipple(progressive_pattern);\r
382 \r
383         impl_->shaders()[pix_desc.pix_fmt].use();\r
384 \r
385         GL(glUniform1f(impl_->shaders()[pix_desc.pix_fmt].get_location("gain"), static_cast<GLfloat>(transform.get_gain())));\r
386         GL(glUniform1i(impl_->shaders()[pix_desc.pix_fmt].get_location("HD"), pix_desc.planes.at(0).height > 700 ? 1 : 0));\r
387         GL(glUniform1i(impl_->shaders()[pix_desc.pix_fmt].get_location("local_key"), local_key ? 1 : 0));\r
388         GL(glUniform1i(impl_->shaders()[pix_desc.pix_fmt].get_location("layer_key"), layer_key ? 1 : 0));\r
389         GL(glUniform1i(impl_->shaders()[pix_desc.pix_fmt].get_location("blend_mode"), transform.get_blend_mode()));\r
390 \r
391         GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity()));\r
392         GL(glViewport(0, 0, width, height));\r
393                                                 \r
394         auto m_p = transform.get_clip_translation();\r
395         auto m_s = transform.get_clip_scale();\r
396         double w = static_cast<double>(width);\r
397         double h = static_cast<double>(height);\r
398 \r
399         GL(glEnable(GL_SCISSOR_TEST));\r
400         GL(glScissor(static_cast<size_t>(m_p[0]*w), static_cast<size_t>(m_p[1]*h), static_cast<size_t>(m_s[0]*w), static_cast<size_t>(m_s[1]*h)));\r
401                         \r
402         auto f_p = transform.get_fill_translation();\r
403         auto f_s = transform.get_fill_scale();\r
404                         \r
405         glBegin(GL_QUADS);\r
406                 glMultiTexCoord2d(GL_TEXTURE0, 0.0, 0.0); glMultiTexCoord2d(GL_TEXTURE1,  f_p[0]        ,  f_p[1]        );             glVertex2d( f_p[0]        *2.0-1.0,  f_p[1]        *2.0-1.0);\r
407                 glMultiTexCoord2d(GL_TEXTURE0, 1.0, 0.0); glMultiTexCoord2d(GL_TEXTURE1, (f_p[0]+f_s[0]),  f_p[1]        );             glVertex2d((f_p[0]+f_s[0])*2.0-1.0,  f_p[1]        *2.0-1.0);\r
408                 glMultiTexCoord2d(GL_TEXTURE0, 1.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1, (f_p[0]+f_s[0]), (f_p[1]+f_s[1]));             glVertex2d((f_p[0]+f_s[0])*2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
409                 glMultiTexCoord2d(GL_TEXTURE0, 0.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1,  f_p[0]        , (f_p[1]+f_s[1]));             glVertex2d( f_p[0]        *2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
410         glEnd();\r
411         GL(glDisable(GL_SCISSOR_TEST)); \r
412 }\r
413 \r
414 }}