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 QGL_ENGINE_SHADER_SOURCE_H
53 #define QGL_ENGINE_SHADER_SOURCE_H
54 
55 #include "qglengineshadermanager_p.h"
56 
57 QT_BEGIN_NAMESPACE
58 
59 
60 
61 static const char* const qglslMainVertexShader = "\n\
62     void setPosition(); \n\
63     void main(void) \n\
64     { \n\
65         setPosition(); \n\
66     }\n";
67 
68 static const char* const qglslMainWithTexCoordsVertexShader = "\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 
78 static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\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.
93 static const char* const qglslPositionOnlyVertexShader = "\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 
105 static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\
106     uniform highp mat3 matrix; \n\
107     uniform highp float translateZ; \n\
108     attribute highp vec2 vertexCoordsArray; \n\
109     void setPosition(void) \n\
110     { \n\
111       vec3 v = matrix * vec3(vertexCoordsArray, 1.0); \n\
112       vec4 vz = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, translateZ, 1) * vec4(v, 1.0); \n\
113       gl_Position = vec4(vz.xyz, 1.0);\n\
114     } \n";
115 
116 static const char* const qglslUntransformedPositionVertexShader = "\n\
117     attribute highp   vec4      vertexCoordsArray; \n\
118     void setPosition(void) \n\
119     { \n\
120         gl_Position = vertexCoordsArray; \n\
121     }\n";
122 
123 // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
124 static const char* const qglslPositionWithPatternBrushVertexShader = "\n\
125     attribute highp   vec2      vertexCoordsArray; \n\
126     attribute highp   vec3      pmvMatrix1; \n\
127     attribute highp   vec3      pmvMatrix2; \n\
128     attribute highp   vec3      pmvMatrix3; \n\
129     uniform   mediump vec2      halfViewportSize; \n\
130     uniform   highp   vec2      invertedTextureSize; \n\
131     uniform   highp   mat3      brushTransform; \n\
132     varying   highp   vec2      patternTexCoords; \n\
133     void setPosition(void) \n\
134     { \n\
135         highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
136         vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
137         gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
138         mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
139         mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\
140         mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
141         gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
142         patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\
143     }\n";
144 
145 static const char* const qglslAffinePositionWithPatternBrushVertexShader
146                  = qglslPositionWithPatternBrushVertexShader;
147 
148 static const char* const qglslPatternBrushSrcFragmentShader = "\n\
149     uniform           sampler2D brushTexture; \n\
150     uniform   lowp    vec4      patternColor; \n\
151     varying   highp   vec2      patternTexCoords;\n\
152     lowp vec4 srcPixel() \n\
153     { \n\
154         return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\
155     }\n";
156 
157 
158 // Linear Gradient Brush
159 static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\
160     attribute highp   vec2      vertexCoordsArray; \n\
161     attribute highp   vec3      pmvMatrix1; \n\
162     attribute highp   vec3      pmvMatrix2; \n\
163     attribute highp   vec3      pmvMatrix3; \n\
164     uniform   mediump vec2      halfViewportSize; \n\
165     uniform   highp   vec3      linearData; \n\
166     uniform   highp   mat3      brushTransform; \n\
167     varying   mediump float     index; \n\
168     void setPosition() \n\
169     { \n\
170         highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
171         vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
172         gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
173         mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
174         mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
175         mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
176         gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
177         index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\
178     }\n";
179 
180 static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader
181                  = qglslPositionWithLinearGradientBrushVertexShader;
182 
183 static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\
184     uniform           sampler2D brushTexture; \n\
185     varying   mediump float     index; \n\
186     lowp vec4 srcPixel() \n\
187     { \n\
188         mediump vec2 val = vec2(index, 0.5); \n\
189         return texture2D(brushTexture, val); \n\
190     }\n";
191 
192 
193 // Conical Gradient Brush
194 static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\
195     attribute highp   vec2      vertexCoordsArray; \n\
196     attribute highp   vec3      pmvMatrix1; \n\
197     attribute highp   vec3      pmvMatrix2; \n\
198     attribute highp   vec3      pmvMatrix3; \n\
199     uniform   mediump vec2      halfViewportSize; \n\
200     uniform   highp   mat3      brushTransform; \n\
201     varying   highp   vec2      A; \n\
202     void setPosition(void) \n\
203     { \n\
204         highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
205         vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
206         gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
207         mediump vec2  viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
208         mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
209         mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
210         gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
211         A = hTexCoords.xy * invertedHTexCoordsZ; \n\
212     }\n";
213 
214 static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader
215                  = qglslPositionWithConicalGradientBrushVertexShader;
216 
217 static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\
218     #define INVERSE_2PI 0.1591549430918953358 \n\
219     uniform           sampler2D brushTexture; \n\
220     uniform   mediump float     angle; \n\
221     varying   highp   vec2      A; \n\
222     lowp vec4 srcPixel() \n\
223     { \n\
224         highp float t; \n\
225         if (abs(A.y) == abs(A.x)) \n\
226             t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\
227         else \n\
228             t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\
229         return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\
230     }\n";
231 
232 
233 // Radial Gradient Brush
234 static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\
235     attribute highp   vec2      vertexCoordsArray;\n\
236     attribute highp   vec3      pmvMatrix1; \n\
237     attribute highp   vec3      pmvMatrix2; \n\
238     attribute highp   vec3      pmvMatrix3; \n\
239     uniform   mediump vec2      halfViewportSize; \n\
240     uniform   highp   mat3      brushTransform; \n\
241     uniform   highp   vec2      fmp; \n\
242     uniform   mediump vec3      bradius; \n\
243     varying   highp   float     b; \n\
244     varying   highp   vec2      A; \n\
245     void setPosition(void) \n\
246     {\n\
247         highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
248         vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
249         gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
250         mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
251         mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
252         mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
253         gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
254         A = hTexCoords.xy * invertedHTexCoordsZ; \n\
255         b = bradius.x + 2.0 * dot(A, fmp); \n\
256     }\n";
257 
258 static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader
259                  = qglslPositionWithRadialGradientBrushVertexShader;
260 
261 static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\
262     uniform           sampler2D brushTexture; \n\
263     uniform   highp   float     fmp2_m_radius2; \n\
264     uniform   highp   float     inverse_2_fmp2_m_radius2; \n\
265     uniform   highp   float     sqrfr; \n\
266     varying   highp   float     b; \n\
267     varying   highp   vec2      A; \n\
268     uniform   mediump vec3      bradius; \n\
269     lowp vec4 srcPixel() \n\
270     { \n\
271         highp float c = sqrfr-dot(A, A); \n\
272         highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\
273         lowp vec4 result = vec4(0.0); \n\
274         if (det >= 0.0) { \n\
275             highp float detSqrt = sqrt(det); \n\
276             highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\
277             if (bradius.y + w * bradius.z >= 0.0) \n\
278                 result = texture2D(brushTexture, vec2(w, 0.5)); \n\
279         } \n\
280         return result; \n\
281     }\n";
282 
283 
284 // Texture Brush
285 static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
286     attribute highp   vec2      vertexCoordsArray; \n\
287     attribute highp   vec3      pmvMatrix1; \n\
288     attribute highp   vec3      pmvMatrix2; \n\
289     attribute highp   vec3      pmvMatrix3; \n\
290     uniform   mediump vec2      halfViewportSize; \n\
291     uniform   highp   vec2      invertedTextureSize; \n\
292     uniform   highp   mat3      brushTransform; \n\
293     varying   highp   vec2      brushTextureCoords; \n\
294     void setPosition(void) \n\
295     { \n\
296         highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
297         vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
298         gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
299         mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
300         mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
301         mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
302         gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
303         brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
304     }\n";
305 
306 static const char* const qglslAffinePositionWithTextureBrushVertexShader
307                  = qglslPositionWithTextureBrushVertexShader;
308 
309 // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
310 // we emulate GL_REPEAT by only taking the fractional part of the texture coords.
311 // TODO: Special case POT textures which don't need this emulation
312 static const char* const qglslTextureBrushSrcFragmentShader_ES = "\n\
313     varying highp   vec2      brushTextureCoords; \n\
314     uniform         sampler2D brushTexture; \n\
315     lowp vec4 srcPixel() { \n\
316         return texture2D(brushTexture, fract(brushTextureCoords)); \n\
317     }\n";
318 
319 static const char* const qglslTextureBrushSrcFragmentShader_desktop = "\n\
320     varying   highp   vec2      brushTextureCoords; \n\
321     uniform           sampler2D brushTexture; \n\
322     lowp vec4 srcPixel() \n\
323     { \n\
324         return texture2D(brushTexture, brushTextureCoords); \n\
325     }\n";
326 
327 static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
328     varying   highp   vec2      brushTextureCoords; \n\
329     uniform   lowp    vec4      patternColor; \n\
330     uniform           sampler2D brushTexture; \n\
331     lowp vec4 srcPixel() \n\
332     { \n\
333         return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\
334     }\n";
335 
336 // Solid Fill Brush
337 static const char* const qglslSolidBrushSrcFragmentShader = "\n\
338     uniform   lowp    vec4      fragmentColor; \n\
339     lowp vec4 srcPixel() \n\
340     { \n\
341         return fragmentColor; \n\
342     }\n";
343 
344 static const char* const qglslImageSrcFragmentShader = "\n\
345     varying   highp   vec2      textureCoords; \n\
346     uniform           sampler2D imageTexture; \n\
347     lowp vec4 srcPixel() \n\
348     { \n"
349         "return texture2D(imageTexture, textureCoords); \n"
350     "}\n";
351 
352 static const char* const qglslCustomSrcFragmentShader = "\n\
353     varying   highp   vec2      textureCoords; \n\
354     uniform           sampler2D imageTexture; \n\
355     lowp vec4 srcPixel() \n\
356     { \n\
357         return customShader(imageTexture, textureCoords); \n\
358     }\n";
359 
360 static const char* const qglslImageSrcWithPatternFragmentShader = "\n\
361     varying   highp   vec2      textureCoords; \n\
362     uniform   lowp    vec4      patternColor; \n\
363     uniform           sampler2D imageTexture; \n\
364     lowp vec4 srcPixel() \n\
365     { \n\
366         return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\
367     }\n";
368 
369 static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\
370     varying   highp   vec2      textureCoords; \n\
371     uniform          sampler2D imageTexture; \n\
372     lowp vec4 srcPixel() \n\
373     { \n\
374         lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\
375         sample.rgb = sample.rgb * sample.a; \n\
376         return sample; \n\
377     }\n";
378 
379 static const char* const qglslShockingPinkSrcFragmentShader = "\n\
380     lowp vec4 srcPixel() \n\
381     { \n\
382         return vec4(0.98, 0.06, 0.75, 1.0); \n\
383     }\n";
384 
385 static const char* const qglslMainFragmentShader_ImageArrays = "\n\
386     varying   lowp    float     opacity; \n\
387     lowp vec4 srcPixel(); \n\
388     void main() \n\
389     { \n\
390         gl_FragColor = srcPixel() * opacity; \n\
391     }\n";
392 
393 static const char* const qglslMainFragmentShader_CMO = "\n\
394     uniform   lowp    float     globalOpacity; \n\
395     lowp vec4 srcPixel(); \n\
396     lowp vec4 applyMask(lowp vec4); \n\
397     lowp vec4 compose(lowp vec4); \n\
398     void main() \n\
399     { \n\
400         gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
401     }\n";
402 
403 static const char* const qglslMainFragmentShader_CM = "\n\
404     lowp vec4 srcPixel(); \n\
405     lowp vec4 applyMask(lowp vec4); \n\
406     lowp vec4 compose(lowp vec4); \n\
407     void main() \n\
408     { \n\
409         gl_FragColor = applyMask(compose(srcPixel())); \n\
410     }\n";
411 
412 static const char* const qglslMainFragmentShader_MO = "\n\
413     uniform   lowp    float     globalOpacity; \n\
414     lowp vec4 srcPixel(); \n\
415     lowp vec4 applyMask(lowp vec4); \n\
416     void main() \n\
417     { \n\
418         gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\
419     }\n";
420 
421 static const char* const qglslMainFragmentShader_M = "\n\
422     lowp vec4 srcPixel(); \n\
423     lowp vec4 applyMask(lowp vec4); \n\
424     void main() \n\
425     { \n\
426         gl_FragColor = applyMask(srcPixel()); \n\
427     }\n";
428 
429 static const char* const qglslMainFragmentShader_CO = "\n\
430     uniform   lowp    float     globalOpacity; \n\
431     lowp vec4 srcPixel(); \n\
432     lowp vec4 compose(lowp vec4); \n\
433     void main() \n\
434     { \n\
435         gl_FragColor = compose(srcPixel()*globalOpacity); \n\
436     }\n";
437 
438 static const char* const qglslMainFragmentShader_C = "\n\
439     lowp vec4 srcPixel(); \n\
440     lowp vec4 compose(lowp vec4); \n\
441     void main() \n\
442     { \n\
443         gl_FragColor = compose(srcPixel()); \n\
444     }\n";
445 
446 static const char* const qglslMainFragmentShader_O = "\n\
447     uniform   lowp    float     globalOpacity; \n\
448     lowp vec4 srcPixel(); \n\
449     void main() \n\
450     { \n\
451         gl_FragColor = srcPixel()*globalOpacity; \n\
452     }\n";
453 
454 static const char* const qglslMainFragmentShader = "\n\
455     lowp vec4 srcPixel(); \n\
456     void main() \n\
457     { \n\
458         gl_FragColor = srcPixel(); \n\
459     }\n";
460 
461 static const char* const qglslMaskFragmentShader = "\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.a; \n\
468     }\n";
469 
470 // For source over with subpixel antialiasing, the final color is calculated per component as follows
471 // (.a is alpha component, .c is red, green or blue component):
472 // alpha = src.a * mask.c * opacity
473 // dest.c = dest.c * (1 - alpha) + src.c * alpha
474 //
475 // In the first pass, calculate: dest.c = dest.c * (1 - alpha) with blend funcs: zero, 1 - source color
476 // In the second pass, calculate: dest.c = dest.c + src.c * alpha with blend funcs: one, one
477 //
478 // If source is a solid color (src is constant), only the first pass is needed, with blend funcs: constant, 1 - source color
479 
480 // For source composition with subpixel antialiasing, the final color is calculated per component as follows:
481 // alpha = src.a * mask.c * opacity
482 // dest.c = dest.c * (1 - mask.c) + src.c * alpha
483 //
484 
485 static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\
486     varying   highp   vec2      textureCoords;\n\
487     uniform           sampler2D maskTexture;\n\
488     lowp vec4 applyMask(lowp vec4 src) \n\
489     { \n\
490         lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
491         return src.a * mask; \n\
492     }\n";
493 
494 static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\
495     varying   highp   vec2      textureCoords;\n\
496     uniform           sampler2D maskTexture;\n\
497     lowp vec4 applyMask(lowp vec4 src) \n\
498     { \n\
499         lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
500         return src * mask; \n\
501     }\n";
502 
503 /*
504     Left to implement:
505         RgbMaskFragmentShader,
506         RgbMaskWithGammaFragmentShader,
507 
508         MultiplyCompositionModeFragmentShader,
509         ScreenCompositionModeFragmentShader,
510         OverlayCompositionModeFragmentShader,
511         DarkenCompositionModeFragmentShader,
512         LightenCompositionModeFragmentShader,
513         ColorDodgeCompositionModeFragmentShader,
514         ColorBurnCompositionModeFragmentShader,
515         HardLightCompositionModeFragmentShader,
516         SoftLightCompositionModeFragmentShader,
517         DifferenceCompositionModeFragmentShader,
518         ExclusionCompositionModeFragmentShader,
519 */
520 
521 QT_END_NAMESPACE
522 
523 #endif // GLGC_SHADER_SOURCE_H
524