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