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