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 58 QT_BEGIN_NAMESPACE 59 60 61 static const char* const qopenglslMainVertexShader = "\n\ 62 void setPosition(); \n\ 63 void main(void) \n\ 64 { \n\ 65 setPosition(); \n\ 66 }\n"; 67 68 static 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 78 static 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. 93 static 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 105 static 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 113 static 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 121 static 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 142 static const char* const qopenglslAffinePositionWithPatternBrushVertexShader 143 = qopenglslPositionWithPatternBrushVertexShader; 144 145 static 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 156 static 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 177 static const char* const qopenglslAffinePositionWithLinearGradientBrushVertexShader 178 = qopenglslPositionWithLinearGradientBrushVertexShader; 179 180 static 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 191 static 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 211 static const char* const qopenglslAffinePositionWithConicalGradientBrushVertexShader 212 = qopenglslPositionWithConicalGradientBrushVertexShader; 213 214 static 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 231 static 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 255 static const char* const qopenglslAffinePositionWithRadialGradientBrushVertexShader 256 = qopenglslPositionWithRadialGradientBrushVertexShader; 257 258 static 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 282 static 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 303 static const char* const qopenglslAffinePositionWithTextureBrushVertexShader 304 = qopenglslPositionWithTextureBrushVertexShader; 305 306 static 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 314 static 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 324 static 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 331 static 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 339 static 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 347 static 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 356 static 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 366 static 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 374 static 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 382 static 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 388 static 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 396 static 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 405 static 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 413 static 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 421 static const char* const qopenglslMainFragmentShader = "\n\ 422 lowp vec4 srcPixel(); \n\ 423 void main() \n\ 424 { \n\ 425 gl_FragColor = srcPixel(); \n\ 426 }\n"; 427 428 static 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 452 static 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 461 static 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 470 static const char* const qopenglslMultiplyCompositionModeFragmentShader = "\n\ 471 #ifdef GL_KHR_blend_equation_advanced\n\ 472 layout(blend_support_multiply) out;\n\ 473 #endif\n"; 474 475 static const char* const qopenglslScreenCompositionModeFragmentShader = "\n\ 476 #ifdef GL_KHR_blend_equation_advanced\n\ 477 layout(blend_support_screen) out;\n\ 478 #endif\n"; 479 480 static const char* const qopenglslOverlayCompositionModeFragmentShader = "\n\ 481 #ifdef GL_KHR_blend_equation_advanced\n\ 482 layout(blend_support_overlay) out;\n\ 483 #endif\n"; 484 485 static const char* const qopenglslDarkenCompositionModeFragmentShader = "\n\ 486 #ifdef GL_KHR_blend_equation_advanced\n\ 487 layout(blend_support_darken) out;\n\ 488 #endif\n"; 489 490 static const char* const qopenglslLightenCompositionModeFragmentShader = "\n\ 491 #ifdef GL_KHR_blend_equation_advanced\n\ 492 layout(blend_support_lighten) out;\n\ 493 #endif\n"; 494 495 static const char* const qopenglslColorDodgeCompositionModeFragmentShader = "\n\ 496 #ifdef GL_KHR_blend_equation_advanced\n\ 497 layout(blend_support_colordodge) out;\n\ 498 #endif\n"; 499 500 static const char* const qopenglslColorBurnCompositionModeFragmentShader = "\n\ 501 #ifdef GL_KHR_blend_equation_advanced\n\ 502 layout(blend_support_colorburn) out;\n\ 503 #endif\n"; 504 505 static const char* const qopenglslHardLightCompositionModeFragmentShader = "\n\ 506 #ifdef GL_KHR_blend_equation_advanced\n\ 507 layout(blend_support_hardlight) out;\n\ 508 #endif\n"; 509 510 static const char* const qopenglslSoftLightCompositionModeFragmentShader = "\n\ 511 #ifdef GL_KHR_blend_equation_advanced\n\ 512 layout(blend_support_softlight) out;\n\ 513 #endif\n"; 514 515 static const char* const qopenglslDifferenceCompositionModeFragmentShader = "\n\ 516 #ifdef GL_KHR_blend_equation_advanced\n\ 517 layout(blend_support_difference) out;\n\ 518 #endif\n"; 519 520 static 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 */ 538 static 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 546 static 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 557 static 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. 573 static 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 585 static 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 593 static 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 601 static 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 622 static const char* const qopenglslAffinePositionWithPatternBrushVertexShader_core 623 = qopenglslPositionWithPatternBrushVertexShader_core; 624 625 static 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 636 static 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 657 static const char* const qopenglslAffinePositionWithLinearGradientBrushVertexShader_core 658 = qopenglslPositionWithLinearGradientBrushVertexShader_core; 659 660 static 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 671 static 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 691 static const char* const qopenglslAffinePositionWithConicalGradientBrushVertexShader_core 692 = qopenglslPositionWithConicalGradientBrushVertexShader_core; 693 694 static 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 711 static 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 735 static const char* const qopenglslAffinePositionWithRadialGradientBrushVertexShader_core 736 = qopenglslPositionWithRadialGradientBrushVertexShader_core; 737 738 static 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 763 static 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 785 static const char* const qopenglslAffinePositionWithTextureBrushVertexShader_core 786 = qopenglslPositionWithTextureBrushVertexShader_core; 787 788 static 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 796 static 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 806 static const char* const qopenglslSolidBrushSrcFragmentShader_core = "\n\ 807 uniform vec4 fragmentColor; \n\ 808 vec4 srcPixel() \n\ 809 { \n\ 810 return fragmentColor; \n\ 811 }\n"; 812 813 static 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 821 static 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 829 static 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 838 static 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 848 static 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 856 static 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 864 static 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 870 static 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 880 static 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 891 static 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 901 static 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 911 static 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 920 static 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 944 static 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 953 static 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 968 QT_END_NAMESPACE 969 970 #endif // GLGC_SHADER_SOURCE_H 971