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