1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtOpenGL module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists purely as an
45// implementation detail. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49//
50
51
52#ifndef QOPENGL_ENGINE_SHADER_SOURCE_H
53#define QOPENGL_ENGINE_SHADER_SOURCE_H
54
55#include "qopenglengineshadermanager_p.h"
56
57QT_BEGIN_NAMESPACE
58
59
60static const char* const qopenglslMainVertexShader = "\n\
61 void setPosition(); \n\
62 void main(void) \n\
63 { \n\
64 setPosition(); \n\
65 }\n";
66
67static const char* const qopenglslMainWithTexCoordsVertexShader = "\n\
68 attribute highp vec2 textureCoordArray; \n\
69 varying highp vec2 textureCoords; \n\
70 void setPosition(); \n\
71 void main(void) \n\
72 { \n\
73 setPosition(); \n\
74 textureCoords = textureCoordArray; \n\
75 }\n";
76
77static const char* const qopenglslMainWithTexCoordsAndOpacityVertexShader = "\n\
78 attribute highp vec2 textureCoordArray; \n\
79 attribute lowp float opacityArray; \n\
80 varying highp vec2 textureCoords; \n\
81 varying lowp float opacity; \n\
82 void setPosition(); \n\
83 void main(void) \n\
84 { \n\
85 setPosition(); \n\
86 textureCoords = textureCoordArray; \n\
87 opacity = opacityArray; \n\
88 }\n";
89
90// NOTE: We let GL do the perspective correction so texture lookups in the fragment
91// shader are also perspective corrected.
92static const char* const qopenglslPositionOnlyVertexShader = "\n\
93 attribute highp vec2 vertexCoordsArray; \n\
94 attribute highp vec3 pmvMatrix1; \n\
95 attribute highp vec3 pmvMatrix2; \n\
96 attribute highp vec3 pmvMatrix3; \n\
97 void setPosition(void) \n\
98 { \n\
99 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
100 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
101 gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\
102 }\n";
103
104static const char* const qopenglslComplexGeometryPositionOnlyVertexShader = "\n\
105 uniform highp mat3 matrix; \n\
106 attribute highp vec2 vertexCoordsArray; \n\
107 void setPosition(void) \n\
108 { \n\
109 gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\
110 } \n";
111
112static const char* const qopenglslUntransformedPositionVertexShader = "\n\
113 attribute highp vec4 vertexCoordsArray; \n\
114 void setPosition(void) \n\
115 { \n\
116 gl_Position = vertexCoordsArray; \n\
117 }\n";
118
119// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
120static const char* const qopenglslPositionWithPatternBrushVertexShader = "\n\
121 attribute highp vec2 vertexCoordsArray; \n\
122 attribute highp vec3 pmvMatrix1; \n\
123 attribute highp vec3 pmvMatrix2; \n\
124 attribute highp vec3 pmvMatrix3; \n\
125 uniform mediump vec2 halfViewportSize; \n\
126 uniform highp vec2 invertedTextureSize; \n\
127 uniform highp mat3 brushTransform; \n\
128 varying highp vec2 patternTexCoords; \n\
129 void setPosition(void) \n\
130 { \n\
131 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
132 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
133 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
134 mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
135 mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\
136 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
137 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
138 patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\
139 }\n";
140
141static const char* const qopenglslAffinePositionWithPatternBrushVertexShader
142 = qopenglslPositionWithPatternBrushVertexShader;
143
144static const char* const qopenglslPatternBrushSrcFragmentShader = "\n\
145 uniform sampler2D brushTexture; \n\
146 uniform lowp vec4 patternColor; \n\
147 varying highp vec2 patternTexCoords;\n\
148 lowp vec4 srcPixel() \n\
149 { \n\
150 return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\
151 }\n";
152
153
154// Linear Gradient Brush
155static const char* const qopenglslPositionWithLinearGradientBrushVertexShader = "\n\
156 attribute highp vec2 vertexCoordsArray; \n\
157 attribute highp vec3 pmvMatrix1; \n\
158 attribute highp vec3 pmvMatrix2; \n\
159 attribute highp vec3 pmvMatrix3; \n\
160 uniform mediump vec2 halfViewportSize; \n\
161 uniform highp vec3 linearData; \n\
162 uniform highp mat3 brushTransform; \n\
163 varying mediump float index; \n\
164 void setPosition() \n\
165 { \n\
166 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
167 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
168 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
169 mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
170 mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
171 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
172 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
173 index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\
174 }\n";
175
176static const char* const qopenglslAffinePositionWithLinearGradientBrushVertexShader
177 = qopenglslPositionWithLinearGradientBrushVertexShader;
178
179static const char* const qopenglslLinearGradientBrushSrcFragmentShader = "\n\
180 uniform sampler2D brushTexture; \n\
181 varying mediump float index; \n\
182 lowp vec4 srcPixel() \n\
183 { \n\
184 mediump vec2 val = vec2(index, 0.5); \n\
185 return texture2D(brushTexture, val); \n\
186 }\n";
187
188
189// Conical Gradient Brush
190static const char* const qopenglslPositionWithConicalGradientBrushVertexShader = "\n\
191 attribute highp vec2 vertexCoordsArray; \n\
192 attribute highp vec3 pmvMatrix1; \n\
193 attribute highp vec3 pmvMatrix2; \n\
194 attribute highp vec3 pmvMatrix3; \n\
195 uniform mediump vec2 halfViewportSize; \n\
196 uniform highp mat3 brushTransform; \n\
197 varying highp vec2 A; \n\
198 void setPosition(void) \n\
199 { \n\
200 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
201 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
202 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
203 mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
204 mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
205 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
206 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
207 A = hTexCoords.xy * invertedHTexCoordsZ; \n\
208 }\n";
209
210static const char* const qopenglslAffinePositionWithConicalGradientBrushVertexShader
211 = qopenglslPositionWithConicalGradientBrushVertexShader;
212
213static const char* const qopenglslConicalGradientBrushSrcFragmentShader = "\n\
214 #define INVERSE_2PI 0.1591549430918953358 \n\
215 uniform sampler2D brushTexture; \n\
216 uniform mediump float angle; \n\
217 varying highp vec2 A; \n\
218 lowp vec4 srcPixel() \n\
219 { \n\
220 highp float t; \n\
221 if (abs(A.y) == abs(A.x)) \n\
222 t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\
223 else \n\
224 t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\
225 return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\
226 }\n";
227
228
229// Radial Gradient Brush
230static const char* const qopenglslPositionWithRadialGradientBrushVertexShader = "\n\
231 attribute highp vec2 vertexCoordsArray;\n\
232 attribute highp vec3 pmvMatrix1; \n\
233 attribute highp vec3 pmvMatrix2; \n\
234 attribute highp vec3 pmvMatrix3; \n\
235 uniform mediump vec2 halfViewportSize; \n\
236 uniform highp mat3 brushTransform; \n\
237 uniform highp vec2 fmp; \n\
238 uniform mediump vec3 bradius; \n\
239 varying highp float b; \n\
240 varying highp vec2 A; \n\
241 void setPosition(void) \n\
242 {\n\
243 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
244 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
245 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
246 mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
247 mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
248 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
249 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
250 A = hTexCoords.xy * invertedHTexCoordsZ; \n\
251 b = bradius.x + 2.0 * dot(A, fmp); \n\
252 }\n";
253
254static const char* const qopenglslAffinePositionWithRadialGradientBrushVertexShader
255 = qopenglslPositionWithRadialGradientBrushVertexShader;
256
257static const char* const qopenglslRadialGradientBrushSrcFragmentShader = "\n\
258 uniform sampler2D brushTexture; \n\
259 uniform highp float fmp2_m_radius2; \n\
260 uniform highp float inverse_2_fmp2_m_radius2; \n\
261 uniform highp float sqrfr; \n\
262 varying highp float b; \n\
263 varying highp vec2 A; \n\
264 uniform mediump vec3 bradius; \n\
265 lowp vec4 srcPixel() \n\
266 { \n\
267 highp float c = sqrfr-dot(A, A); \n\
268 highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\
269 lowp vec4 result = vec4(0.0); \n\
270 if (det >= 0.0) { \n\
271 highp float detSqrt = sqrt(det); \n\
272 highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\
273 if (bradius.y + w * bradius.z >= 0.0) \n\
274 result = texture2D(brushTexture, vec2(w, 0.5)); \n\
275 } \n\
276 return result; \n\
277 }\n";
278
279
280// Texture Brush
281static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
282 attribute highp vec2 vertexCoordsArray; \n\
283 attribute highp vec3 pmvMatrix1; \n\
284 attribute highp vec3 pmvMatrix2; \n\
285 attribute highp vec3 pmvMatrix3; \n\
286 uniform mediump vec2 halfViewportSize; \n\
287 uniform highp vec2 invertedTextureSize; \n\
288 uniform highp mat3 brushTransform; \n\
289 varying highp vec2 brushTextureCoords; \n\
290 void setPosition(void) \n\
291 { \n\
292 highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
293 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
294 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
295 mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
296 mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
297 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
298 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
299 brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
300 }\n";
301
302static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
303 = qopenglslPositionWithTextureBrushVertexShader;
304
305static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
306 varying highp vec2 brushTextureCoords; \n\
307 uniform sampler2D brushTexture; \n\
308 lowp vec4 srcPixel() \n\
309 { \n\
310 return texture2D(brushTexture, brushTextureCoords); \n\
311 }\n";
312
313static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
314 varying highp vec2 brushTextureCoords; \n\
315 uniform lowp vec4 patternColor; \n\
316 uniform sampler2D brushTexture; \n\
317 lowp vec4 srcPixel() \n\
318 { \n\
319 return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\
320 }\n";
321
322// Solid Fill Brush
323static const char* const qopenglslSolidBrushSrcFragmentShader = "\n\
324 uniform lowp vec4 fragmentColor; \n\
325 lowp vec4 srcPixel() \n\
326 { \n\
327 return fragmentColor; \n\
328 }\n";
329
330static const char* const qopenglslImageSrcFragmentShader = "\n\
331 varying highp vec2 textureCoords; \n\
332 uniform sampler2D imageTexture; \n\
333 lowp vec4 srcPixel() \n\
334 { \n"
335 "return texture2D(imageTexture, textureCoords); \n"
336 "}\n";
337
338static const char* const qopenglslCustomSrcFragmentShader = "\n\
339 varying highp vec2 textureCoords; \n\
340 uniform sampler2D imageTexture; \n\
341 lowp vec4 srcPixel() \n\
342 { \n\
343 return customShader(imageTexture, textureCoords); \n\
344 }\n";
345
346static const char* const qopenglslImageSrcWithPatternFragmentShader = "\n\
347 varying highp vec2 textureCoords; \n\
348 uniform lowp vec4 patternColor; \n\
349 uniform sampler2D imageTexture; \n\
350 lowp vec4 srcPixel() \n\
351 { \n\
352 return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\
353 }\n";
354
355static const char* const qopenglslNonPremultipliedImageSrcFragmentShader = "\n\
356 varying highp vec2 textureCoords; \n\
357 uniform sampler2D imageTexture; \n\
358 lowp vec4 srcPixel() \n\
359 { \n\
360 lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\
361 sample.rgb = sample.rgb * sample.a; \n\
362 return sample; \n\
363 }\n";
364
365static const char* const qopenglslGrayscaleImageSrcFragmentShader = "\n\
366 varying highp vec2 textureCoords; \n\
367 uniform sampler2D imageTexture; \n\
368 lowp vec4 srcPixel() \n\
369 { \n\
370 return texture2D(imageTexture, textureCoords).rrra; \n\
371 }\n";
372
373static const char* const qopenglslAlphaImageSrcFragmentShader = "\n\
374 varying highp vec2 textureCoords; \n\
375 uniform sampler2D imageTexture; \n\
376 lowp vec4 srcPixel() \n\
377 { \n\
378 return vec4(0, 0, 0, texture2D(imageTexture, textureCoords).r); \n\
379 }\n";
380
381static const char* const qopenglslShockingPinkSrcFragmentShader = "\n\
382 lowp vec4 srcPixel() \n\
383 { \n\
384 return vec4(0.98, 0.06, 0.75, 1.0); \n\
385 }\n";
386
387static const char* const qopenglslMainFragmentShader_ImageArrays = "\n\
388 varying lowp float opacity; \n\
389 lowp vec4 srcPixel(); \n\
390 void main() \n\
391 { \n\
392 gl_FragColor = srcPixel() * opacity; \n\
393 }\n";
394
395static const char* const qopenglslMainFragmentShader_MO = "\n\
396 uniform lowp float globalOpacity; \n\
397 lowp vec4 srcPixel(); \n\
398 lowp vec4 applyMask(lowp vec4); \n\
399 void main() \n\
400 { \n\
401 gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\
402 }\n";
403
404static const char* const qopenglslMainFragmentShader_M = "\n\
405 lowp vec4 srcPixel(); \n\
406 lowp vec4 applyMask(lowp vec4); \n\
407 void main() \n\
408 { \n\
409 gl_FragColor = applyMask(srcPixel()); \n\
410 }\n";
411
412static const char* const qopenglslMainFragmentShader_O = "\n\
413 uniform lowp float globalOpacity; \n\
414 lowp vec4 srcPixel(); \n\
415 void main() \n\
416 { \n\
417 gl_FragColor = srcPixel()*globalOpacity; \n\
418 }\n";
419
420static const char* const qopenglslMainFragmentShader = "\n\
421 lowp vec4 srcPixel(); \n\
422 void main() \n\
423 { \n\
424 gl_FragColor = srcPixel(); \n\
425 }\n";
426
427static const char* const qopenglslMaskFragmentShader = "\n\
428 varying highp vec2 textureCoords;\n\
429 uniform sampler2D maskTexture;\n\
430 lowp vec4 applyMask(lowp vec4 src) \n\
431 {\n\
432 lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
433 return src * mask.a; \n\
434 }\n";
435
436// For source over with subpixel antialiasing, the final color is calculated per component as follows
437// (.a is alpha component, .c is red, green or blue component):
438// alpha = src.a * mask.c * opacity
439// dest.c = dest.c * (1 - alpha) + src.c * alpha
440//
441// In the first pass, calculate: dest.c = dest.c * (1 - alpha) with blend funcs: zero, 1 - source color
442// In the second pass, calculate: dest.c = dest.c + src.c * alpha with blend funcs: one, one
443//
444// If source is a solid color (src is constant), only the first pass is needed, with blend funcs: constant, 1 - source color
445
446// For source composition with subpixel antialiasing, the final color is calculated per component as follows:
447// alpha = src.a * mask.c * opacity
448// dest.c = dest.c * (1 - mask.c) + src.c * alpha
449//
450
451static const char* const qopenglslRgbMaskFragmentShaderPass1 = "\n\
452 varying highp vec2 textureCoords;\n\
453 uniform sampler2D maskTexture;\n\
454 lowp vec4 applyMask(lowp vec4 src) \n\
455 { \n\
456 lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
457 return src.a * mask; \n\
458 }\n";
459
460static const char* const qopenglslRgbMaskFragmentShaderPass2 = "\n\
461 varying highp vec2 textureCoords;\n\
462 uniform sampler2D maskTexture;\n\
463 lowp vec4 applyMask(lowp vec4 src) \n\
464 { \n\
465 lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
466 return src * mask; \n\
467 }\n";
468
469static const char* const qopenglslMultiplyCompositionModeFragmentShader = "\n\
470 #ifdef GL_KHR_blend_equation_advanced\n\
471 layout(blend_support_multiply) out;\n\
472 #endif\n";
473
474static const char* const qopenglslScreenCompositionModeFragmentShader = "\n\
475 #ifdef GL_KHR_blend_equation_advanced\n\
476 layout(blend_support_screen) out;\n\
477 #endif\n";
478
479static const char* const qopenglslOverlayCompositionModeFragmentShader = "\n\
480 #ifdef GL_KHR_blend_equation_advanced\n\
481 layout(blend_support_overlay) out;\n\
482 #endif\n";
483
484static const char* const qopenglslDarkenCompositionModeFragmentShader = "\n\
485 #ifdef GL_KHR_blend_equation_advanced\n\
486 layout(blend_support_darken) out;\n\
487 #endif\n";
488
489static const char* const qopenglslLightenCompositionModeFragmentShader = "\n\
490 #ifdef GL_KHR_blend_equation_advanced\n\
491 layout(blend_support_lighten) out;\n\
492 #endif\n";
493
494static const char* const qopenglslColorDodgeCompositionModeFragmentShader = "\n\
495 #ifdef GL_KHR_blend_equation_advanced\n\
496 layout(blend_support_colordodge) out;\n\
497 #endif\n";
498
499static const char* const qopenglslColorBurnCompositionModeFragmentShader = "\n\
500 #ifdef GL_KHR_blend_equation_advanced\n\
501 layout(blend_support_colorburn) out;\n\
502 #endif\n";
503
504static const char* const qopenglslHardLightCompositionModeFragmentShader = "\n\
505 #ifdef GL_KHR_blend_equation_advanced\n\
506 layout(blend_support_hardlight) out;\n\
507 #endif\n";
508
509static const char* const qopenglslSoftLightCompositionModeFragmentShader = "\n\
510 #ifdef GL_KHR_blend_equation_advanced\n\
511 layout(blend_support_softlight) out;\n\
512 #endif\n";
513
514static const char* const qopenglslDifferenceCompositionModeFragmentShader = "\n\
515 #ifdef GL_KHR_blend_equation_advanced\n\
516 layout(blend_support_difference) out;\n\
517 #endif\n";
518
519static const char* const qopenglslExclusionCompositionModeFragmentShader = "\n\
520 #ifdef GL_KHR_blend_equation_advanced\n\
521 layout(blend_support_exclusion) out;\n\
522 #endif\n";
523
524/*
525 Left to implement:
526 RgbMaskFragmentShader,
527 RgbMaskWithGammaFragmentShader,
528*/
529
530/*
531 OpenGL 3.2+ Core Profile shaders
532 The following shader snippets are copies of the snippets above
533 but use the modern GLSL 1.5 keywords. New shaders should make
534 a snippet for both profiles and add them appropriately in the
535 shader manager.
536*/
537static const char* const qopenglslMainVertexShader_core =
538 "#version 150 core\n\
539 void setPosition(); \n\
540 void main(void) \n\
541 { \n\
542 setPosition(); \n\
543 }\n";
544
545static const char* const qopenglslMainWithTexCoordsVertexShader_core =
546 "#version 150 core\n\
547 in vec2 textureCoordArray; \n\
548 out vec2 textureCoords; \n\
549 void setPosition(); \n\
550 void main(void) \n\
551 { \n\
552 setPosition(); \n\
553 textureCoords = textureCoordArray; \n\
554 }\n";
555
556static const char* const qopenglslMainWithTexCoordsAndOpacityVertexShader_core =
557 "#version 150 core\n\
558 in vec2 textureCoordArray; \n\
559 in float opacityArray; \n\
560 out vec2 textureCoords; \n\
561 out float opacity; \n\
562 void setPosition(); \n\
563 void main(void) \n\
564 { \n\
565 setPosition(); \n\
566 textureCoords = textureCoordArray; \n\
567 opacity = opacityArray; \n\
568 }\n";
569
570// NOTE: We let GL do the perspective correction so texture lookups in the fragment
571// shader are also perspective corrected.
572static const char* const qopenglslPositionOnlyVertexShader_core = "\n\
573 in vec2 vertexCoordsArray; \n\
574 in vec3 pmvMatrix1; \n\
575 in vec3 pmvMatrix2; \n\
576 in vec3 pmvMatrix3; \n\
577 void setPosition(void) \n\
578 { \n\
579 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
580 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
581 gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\
582 }\n";
583
584static const char* const qopenglslComplexGeometryPositionOnlyVertexShader_core = "\n\
585 in vec2 vertexCoordsArray; \n\
586 uniform mat3 matrix; \n\
587 void setPosition(void) \n\
588 { \n\
589 gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\
590 } \n";
591
592static const char* const qopenglslUntransformedPositionVertexShader_core = "\n\
593 in vec4 vertexCoordsArray; \n\
594 void setPosition(void) \n\
595 { \n\
596 gl_Position = vertexCoordsArray; \n\
597 }\n";
598
599// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
600static const char* const qopenglslPositionWithPatternBrushVertexShader_core = "\n\
601 in vec2 vertexCoordsArray; \n\
602 in vec3 pmvMatrix1; \n\
603 in vec3 pmvMatrix2; \n\
604 in vec3 pmvMatrix3; \n\
605 out vec2 patternTexCoords; \n\
606 uniform vec2 halfViewportSize; \n\
607 uniform vec2 invertedTextureSize; \n\
608 uniform mat3 brushTransform; \n\
609 void setPosition(void) \n\
610 { \n\
611 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
612 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
613 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
614 vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
615 vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\
616 float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
617 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
618 patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\
619 }\n";
620
621static const char* const qopenglslAffinePositionWithPatternBrushVertexShader_core
622 = qopenglslPositionWithPatternBrushVertexShader_core;
623
624static const char* const qopenglslPatternBrushSrcFragmentShader_core = "\n\
625 in vec2 patternTexCoords;\n\
626 uniform sampler2D brushTexture; \n\
627 uniform vec4 patternColor; \n\
628 vec4 srcPixel() \n\
629 { \n\
630 return patternColor * (1.0 - texture(brushTexture, patternTexCoords).r); \n\
631 }\n";
632
633
634// Linear Gradient Brush
635static const char* const qopenglslPositionWithLinearGradientBrushVertexShader_core = "\n\
636 in vec2 vertexCoordsArray; \n\
637 in vec3 pmvMatrix1; \n\
638 in vec3 pmvMatrix2; \n\
639 in vec3 pmvMatrix3; \n\
640 out float index; \n\
641 uniform vec2 halfViewportSize; \n\
642 uniform vec3 linearData; \n\
643 uniform mat3 brushTransform; \n\
644 void setPosition() \n\
645 { \n\
646 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
647 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
648 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
649 vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
650 vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
651 float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
652 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
653 index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\
654 }\n";
655
656static const char* const qopenglslAffinePositionWithLinearGradientBrushVertexShader_core
657 = qopenglslPositionWithLinearGradientBrushVertexShader_core;
658
659static const char* const qopenglslLinearGradientBrushSrcFragmentShader_core = "\n\
660 uniform sampler2D brushTexture; \n\
661 in float index; \n\
662 vec4 srcPixel() \n\
663 { \n\
664 vec2 val = vec2(index, 0.5); \n\
665 return texture(brushTexture, val); \n\
666 }\n";
667
668
669// Conical Gradient Brush
670static const char* const qopenglslPositionWithConicalGradientBrushVertexShader_core = "\n\
671 in vec2 vertexCoordsArray; \n\
672 in vec3 pmvMatrix1; \n\
673 in vec3 pmvMatrix2; \n\
674 in vec3 pmvMatrix3; \n\
675 out vec2 A; \n\
676 uniform vec2 halfViewportSize; \n\
677 uniform mat3 brushTransform; \n\
678 void setPosition(void) \n\
679 { \n\
680 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
681 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
682 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
683 vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
684 vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
685 float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
686 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
687 A = hTexCoords.xy * invertedHTexCoordsZ; \n\
688 }\n";
689
690static const char* const qopenglslAffinePositionWithConicalGradientBrushVertexShader_core
691 = qopenglslPositionWithConicalGradientBrushVertexShader_core;
692
693static const char* const qopenglslConicalGradientBrushSrcFragmentShader_core = "\n\
694 #define INVERSE_2PI 0.1591549430918953358 \n\
695 in vec2 A; \n\
696 uniform sampler2D brushTexture; \n\
697 uniform float angle; \n\
698 vec4 srcPixel() \n\
699 { \n\
700 float t; \n\
701 if (abs(A.y) == abs(A.x)) \n\
702 t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\
703 else \n\
704 t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\
705 return texture(brushTexture, vec2(t - floor(t), 0.5)); \n\
706 }\n";
707
708
709// Radial Gradient Brush
710static const char* const qopenglslPositionWithRadialGradientBrushVertexShader_core = "\n\
711 in vec2 vertexCoordsArray;\n\
712 in vec3 pmvMatrix1; \n\
713 in vec3 pmvMatrix2; \n\
714 in vec3 pmvMatrix3; \n\
715 out float b; \n\
716 out vec2 A; \n\
717 uniform vec2 halfViewportSize; \n\
718 uniform mat3 brushTransform; \n\
719 uniform vec2 fmp; \n\
720 uniform vec3 bradius; \n\
721 void setPosition(void) \n\
722 {\n\
723 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
724 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
725 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
726 vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
727 vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
728 float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
729 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
730 A = hTexCoords.xy * invertedHTexCoordsZ; \n\
731 b = bradius.x + 2.0 * dot(A, fmp); \n\
732 }\n";
733
734static const char* const qopenglslAffinePositionWithRadialGradientBrushVertexShader_core
735 = qopenglslPositionWithRadialGradientBrushVertexShader_core;
736
737static const char* const qopenglslRadialGradientBrushSrcFragmentShader_core = "\n\
738 in float b; \n\
739 in vec2 A; \n\
740 uniform sampler2D brushTexture; \n\
741 uniform float fmp2_m_radius2; \n\
742 uniform float inverse_2_fmp2_m_radius2; \n\
743 uniform float sqrfr; \n\
744 uniform vec3 bradius; \n\
745 \n\
746 vec4 srcPixel() \n\
747 { \n\
748 float c = sqrfr-dot(A, A); \n\
749 float det = b*b - 4.0*fmp2_m_radius2*c; \n\
750 vec4 result = vec4(0.0); \n\
751 if (det >= 0.0) { \n\
752 float detSqrt = sqrt(det); \n\
753 float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\
754 if (bradius.y + w * bradius.z >= 0.0) \n\
755 result = texture(brushTexture, vec2(w, 0.5)); \n\
756 } \n\
757 return result; \n\
758 }\n";
759
760
761// Texture Brush
762static const char* const qopenglslPositionWithTextureBrushVertexShader_core = "\n\
763 in vec2 vertexCoordsArray; \n\
764 in vec3 pmvMatrix1; \n\
765 in vec3 pmvMatrix2; \n\
766 in vec3 pmvMatrix3; \n\
767 out vec2 brushTextureCoords; \n\
768 uniform vec2 halfViewportSize; \n\
769 uniform vec2 invertedTextureSize; \n\
770 uniform mat3 brushTransform; \n\
771 \n\
772 void setPosition(void) \n\
773 { \n\
774 mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
775 vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
776 gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
777 vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
778 vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
779 float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
780 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
781 brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
782 }\n";
783
784static const char* const qopenglslAffinePositionWithTextureBrushVertexShader_core
785 = qopenglslPositionWithTextureBrushVertexShader_core;
786
787static const char* const qopenglslTextureBrushSrcFragmentShader_core = "\n\
788 in vec2 brushTextureCoords; \n\
789 uniform sampler2D brushTexture; \n\
790 vec4 srcPixel() \n\
791 { \n\
792 return texture(brushTexture, brushTextureCoords); \n\
793 }\n";
794
795static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader_core = "\n\
796 in vec2 brushTextureCoords; \n\
797 uniform vec4 patternColor; \n\
798 uniform sampler2D brushTexture; \n\
799 vec4 srcPixel() \n\
800 { \n\
801 return patternColor * (1.0 - texture(brushTexture, brushTextureCoords).r); \n\
802 }\n";
803
804// Solid Fill Brush
805static const char* const qopenglslSolidBrushSrcFragmentShader_core = "\n\
806 uniform vec4 fragmentColor; \n\
807 vec4 srcPixel() \n\
808 { \n\
809 return fragmentColor; \n\
810 }\n";
811
812static const char* const qopenglslImageSrcFragmentShader_core = "\n\
813 in vec2 textureCoords; \n\
814 uniform sampler2D imageTexture; \n\
815 vec4 srcPixel() \n\
816 { \n\
817 return texture(imageTexture, textureCoords); \n\
818 }\n";
819
820static const char* const qopenglslCustomSrcFragmentShader_core = "\n\
821 in vec2 textureCoords; \n\
822 uniform sampler2D imageTexture; \n\
823 vec4 srcPixel() \n\
824 { \n\
825 return customShader(imageTexture, textureCoords); \n\
826 }\n";
827
828static const char* const qopenglslImageSrcWithPatternFragmentShader_core = "\n\
829 in vec2 textureCoords; \n\
830 uniform vec4 patternColor; \n\
831 uniform sampler2D imageTexture; \n\
832 vec4 srcPixel() \n\
833 { \n\
834 return patternColor * (1.0 - texture(imageTexture, textureCoords).r); \n\
835 }\n";
836
837static const char* const qopenglslNonPremultipliedImageSrcFragmentShader_core = "\n\
838 in vec2 textureCoords; \n\
839 uniform sampler2D imageTexture; \n\
840 vec4 srcPixel() \n\
841 { \n\
842 vec4 sample = texture(imageTexture, textureCoords); \n\
843 sample.rgb = sample.rgb * sample.a; \n\
844 return sample; \n\
845 }\n";
846
847static const char* const qopenglslGrayscaleImageSrcFragmentShader_core = "\n\
848 in vec2 textureCoords; \n\
849 uniform sampler2D imageTexture; \n\
850 vec4 srcPixel() \n\
851 { \n\
852 return texture(imageTexture, textureCoords).rrra; \n\
853 }\n";
854
855static const char* const qopenglslAlphaImageSrcFragmentShader_core = "\n\
856 in vec2 textureCoords; \n\
857 uniform sampler2D imageTexture; \n\
858 vec4 srcPixel() \n\
859 { \n\
860 return vec4(0, 0, 0, texture(imageTexture, textureCoords).r); \n\
861 }\n";
862
863static const char* const qopenglslShockingPinkSrcFragmentShader_core = "\n\
864 vec4 srcPixel() \n\
865 { \n\
866 return vec4(0.98, 0.06, 0.75, 1.0); \n\
867 }\n";
868
869static const char* const qopenglslMainFragmentShader_ImageArrays_core =
870 "#version 150 core\n\
871 in float opacity; \n\
872 out vec4 fragColor; \n\
873 vec4 srcPixel(); \n\
874 void main() \n\
875 { \n\
876 fragColor = srcPixel() * opacity; \n\
877 }\n";
878
879static const char* const qopenglslMainFragmentShader_MO_core =
880 "#version 150 core\n\
881 out vec4 fragColor; \n\
882 uniform float globalOpacity; \n\
883 vec4 srcPixel(); \n\
884 vec4 applyMask(vec4); \n\
885 void main() \n\
886 { \n\
887 fragColor = applyMask(srcPixel()*globalOpacity); \n\
888 }\n";
889
890static const char* const qopenglslMainFragmentShader_M_core =
891 "#version 150 core\n\
892 out vec4 fragColor; \n\
893 vec4 srcPixel(); \n\
894 vec4 applyMask(vec4); \n\
895 void main() \n\
896 { \n\
897 fragColor = applyMask(srcPixel()); \n\
898 }\n";
899
900static const char* const qopenglslMainFragmentShader_O_core =
901 "#version 150 core\n\
902 out vec4 fragColor; \n\
903 uniform float globalOpacity; \n\
904 vec4 srcPixel(); \n\
905 void main() \n\
906 { \n\
907 fragColor = srcPixel()*globalOpacity; \n\
908 }\n";
909
910static const char* const qopenglslMainFragmentShader_core =
911 "#version 150 core\n\
912 out vec4 fragColor; \n\
913 vec4 srcPixel(); \n\
914 void main() \n\
915 { \n\
916 fragColor = srcPixel(); \n\
917 }\n";
918
919static const char* const qopenglslMaskFragmentShader_core = "\n\
920 in vec2 textureCoords;\n\
921 uniform sampler2D maskTexture;\n\
922 vec4 applyMask(vec4 src) \n\
923 {\n\
924 vec4 mask = texture(maskTexture, textureCoords); \n\
925 return src * mask.r; \n\
926 }\n";
927
928// For source over with subpixel antialiasing, the final color is calculated per component as follows
929// (.a is alpha component, .c is red, green or blue component):
930// alpha = src.a * mask.c * opacity
931// dest.c = dest.c * (1 - alpha) + src.c * alpha
932//
933// In the first pass, calculate: dest.c = dest.c * (1 - alpha) with blend funcs: zero, 1 - source color
934// In the second pass, calculate: dest.c = dest.c + src.c * alpha with blend funcs: one, one
935//
936// If source is a solid color (src is constant), only the first pass is needed, with blend funcs: constant, 1 - source color
937
938// For source composition with subpixel antialiasing, the final color is calculated per component as follows:
939// alpha = src.a * mask.c * opacity
940// dest.c = dest.c * (1 - mask.c) + src.c * alpha
941//
942
943static const char* const qopenglslRgbMaskFragmentShaderPass1_core = "\n\
944 in vec2 textureCoords;\n\
945 uniform sampler2D maskTexture;\n\
946 vec4 applyMask(vec4 src) \n\
947 { \n\
948 vec4 mask = texture(maskTexture, textureCoords); \n\
949 return src.a * mask; \n\
950 }\n";
951
952static const char* const qopenglslRgbMaskFragmentShaderPass2_core = "\n\
953 in vec2 textureCoords;\n\
954 uniform sampler2D maskTexture;\n\
955 vec4 applyMask(vec4 src) \n\
956 { \n\
957 vec4 mask = texture(maskTexture, textureCoords); \n\
958 return src * mask; \n\
959 }\n";
960
961/*
962 Left to implement:
963 RgbMaskFragmentShader_core,
964 RgbMaskWithGammaFragmentShader_core,
965*/
966
967QT_END_NAMESPACE
968
969#endif // GLGC_SHADER_SOURCE_H
970