diff options
author | Marko Niemelä <marko.a.niemela@nokia.com> | 2012-01-09 12:54:35 +0200 |
---|---|---|
committer | Marko Niemelä <marko.a.niemela@nokia.com> | 2012-01-09 12:54:35 +0200 |
commit | 8ecab9fe214c404ccc767901220e2adc335f621b (patch) | |
tree | 4d5a316e1d69f628c6a120ef28c362176f77fa7b /src | |
parent | 4279ed2e74523ab678859bd929e1fe7177a4fa75 (diff) | |
download | qtgraphicaleffects-8ecab9fe214c404ccc767901220e2adc335f621b.tar.gz |
Added MaskedBlur effect
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/MaskedBlur.qml | 94 | ||||
-rw-r--r-- | src/effects/internal/DirectionalGaussianMaskedBlur.qml | 271 | ||||
-rw-r--r-- | src/effects/internal/FastMaskedBlur.qml | 309 | ||||
-rw-r--r-- | src/effects/internal/GaussianMaskedBlur.qml | 110 | ||||
-rw-r--r-- | src/effects/qmldir | 1 |
5 files changed, 785 insertions, 0 deletions
diff --git a/src/effects/MaskedBlur.qml b/src/effects/MaskedBlur.qml new file mode 100644 index 0000000..aeadde7 --- /dev/null +++ b/src/effects/MaskedBlur.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Graphical Effects module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "internal" + +Item { + id: rootItem + property variant source + property variant maskSource + property real radius: 0.0 + property int maximumRadius: 0 + property bool cached: false + property bool fast: false + property bool transparentBorder: false + + SourceProxy { + id: sourceProxy + input: rootItem.source + } + + SourceProxy { + id: maskSourceProxy + input: rootItem.maskSource + } + + Loader { + id: loaderItem + anchors.fill: parent + sourceComponent: rootItem.fast ? fastBlur : gaussianBlur + } + + Component { + id: gaussianBlur + GaussianMaskedBlur { + anchors.fill: parent + source: sourceProxy.output + maskSource: maskSourceProxy.output + radius: rootItem.radius + maximumRadius: rootItem.maximumRadius + transparentBorder: rootItem.transparentBorder + cached: rootItem.cached + } + } + + Component { + id: fastBlur + FastMaskedBlur { + anchors.fill: parent + source: sourceProxy.output + maskSource: maskSourceProxy.output + blur: Math.pow(rootItem.radius / 64.0, 0.4) + transparentBorder: rootItem.transparentBorder + cached: rootItem.cached + } + } +} diff --git a/src/effects/internal/DirectionalGaussianMaskedBlur.qml b/src/effects/internal/DirectionalGaussianMaskedBlur.qml new file mode 100644 index 0000000..d224c6f --- /dev/null +++ b/src/effects/internal/DirectionalGaussianMaskedBlur.qml @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Graphical Effects module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: rootItem + property variant source + property variant maskSource + property real deviation: (radius + 1) / 3.3333 + property real radius: 0.0 + property int maximumRadius: 0 + property real horizontalStep: 0.0 + property real verticalStep: 0.0 + property bool transparentBorder: false + property bool cached: false + + SourceProxy { + id: sourceProxy + input: rootItem.source + } + + SourceProxy { + id: maskSourceProxy + input: rootItem.maskSource + } + + ShaderEffectSource { + id: cacheItem + anchors.fill: rootItem + visible: rootItem.cached + smooth: true + sourceItem: shaderItem + live: true + hideSource: visible + } + + ShaderEffect { + id: shaderItem + property variant source: sourceProxy.output + property variant maskSource: maskSourceProxy.output + property real deviation: rootItem.deviation + property real radius: rootItem.radius + property int maxRadius: rootItem.maximumRadius + property bool transparentBorder: rootItem.transparentBorder + property real deltaX: rootItem.horizontalStep + property real deltaY: rootItem.verticalStep + property real gaussianSum: 0.0 + property real startIndex: 0.0 + property real deltaFactor: (2 * radius - 1) / (maxRadius * 2 - 1) + property real expandX: transparentBorder && deltaX > 0 ? maxRadius / width : 0.0 + property real expandY: transparentBorder && deltaY > 0 ? maxRadius / height : 0.0 + property real pixelX: 1.0 / (width / (1.0 - 2 * expandX)) + property real pixelY: 1.0 / (height / (1.0 - 2 * expandY)) + property variant gwts: [] + property variant delta: Qt.vector3d(deltaX * deltaFactor, deltaY * deltaFactor, startIndex); + property variant factor_0_2: Qt.vector3d(gwts[0], gwts[1], gwts[2]); + property variant factor_3_5: Qt.vector3d(gwts[3], gwts[4], gwts[5]); + property variant factor_6_8: Qt.vector3d(gwts[6], gwts[7], gwts[8]); + property variant factor_9_11: Qt.vector3d(gwts[9], gwts[10], gwts[11]); + property variant factor_12_14: Qt.vector3d(gwts[12], gwts[13], gwts[14]); + property variant factor_15_17: Qt.vector3d(gwts[15], gwts[16], gwts[17]); + property variant factor_18_20: Qt.vector3d(gwts[18], gwts[19], gwts[20]); + property variant factor_21_23: Qt.vector3d(gwts[21], gwts[22], gwts[23]); + property variant factor_24_26: Qt.vector3d(gwts[24], gwts[25], gwts[26]); + property variant factor_27_29: Qt.vector3d(gwts[27], gwts[28], gwts[29]); + property variant factor_30_32: Qt.vector3d(gwts[30], gwts[31], gwts[32]); + + anchors.fill: rootItem + + function gausFunc(x){ + //Gaussian function = h(x):=(1/sqrt(2*3.14159*(D^2))) * %e^(-(x^2)/(2*(D^2))); + return (1.0 / Math.sqrt(2 * Math.PI * (Math.pow(shaderItem.deviation, 2)))) * Math.pow(Math.E, -((Math.pow(x, 2)) / (2 * (Math.pow(shaderItem.deviation, 2))))); + } + + function updateGaussianWeights() { + gaussianSum = 0.0; + startIndex = -maxRadius + 0.5 + + var n = new Array(32); + for (var j = 0; j < 32; j++) + n[j] = 0; + + var max = maxRadius * 2 + var delta = (2 * radius - 1) / (max - 1); + for (var i = 0; i < max; i++) { + n[i] = gausFunc(-radius + 0.5 + i * delta); + gaussianSum += n[i]; + } + + gwts = n; + } + + function buildFragmentShader() { + var linearSteps = "" + + if (transparentBorder) + linearSteps = "* linearstep(0.0, pixelX, texCoord.s) * linearstep(1.0, stepX, texCoord.s) * linearstep(0.0, pixelY, texCoord.t) * linearstep(1.0, stepY, texCoord.t)" + + var shaderSteps = [ + "gl_FragColor += texture2D(source, texCoord) * factor_0_2.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_0_2.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_0_2.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_3_5.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_3_5.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_3_5.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_6_8.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_6_8.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_6_8.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_9_11.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_9_11.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_9_11.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_12_14.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_12_14.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_12_14.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_15_17.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_15_17.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_15_17.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_18_20.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_18_20.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_18_20.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_21_23.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_21_23.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_21_23.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_24_26.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_24_26.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_24_26.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_27_29.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_27_29.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_27_29.z" + linearSteps + "; texCoord += shift;", + + "gl_FragColor += texture2D(source, texCoord) * factor_30_32.x" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_30_32.y" + linearSteps + "; texCoord += shift;", + "gl_FragColor += texture2D(source, texCoord) * factor_30_32.z" + linearSteps + "; texCoord += shift;" + ] + + var shader = fragmentShaderBegin + var samples = maxRadius * 2 + if (samples > 32) { + console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!") + samples = 32 + } + + for (var i = 0; i < samples; i++) { + shader += shaderSteps[i] + } + + shader += fragmentShaderEnd + fragmentShader = shader + } + + onDeviationChanged: updateGaussianWeights() + + onRadiusChanged: updateGaussianWeights() + + onTransparentBorderChanged: { + buildFragmentShader() + updateGaussianWeights() + } + + onMaxRadiusChanged: { + buildFragmentShader() + updateGaussianWeights() + } + + Component.onCompleted: { + buildFragmentShader() + updateGaussianWeights() + } + + property string fragmentShaderBegin: " + varying mediump vec2 qt_TexCoord0; + uniform highp float qt_Opacity; + uniform sampler2D source; + uniform sampler2D maskSource; + uniform highp vec3 delta; + uniform highp vec3 factor_0_2; + uniform highp vec3 factor_3_5; + uniform highp vec3 factor_6_8; + uniform highp vec3 factor_9_11; + uniform highp vec3 factor_12_14; + uniform highp vec3 factor_15_17; + uniform highp vec3 factor_18_20; + uniform highp vec3 factor_21_23; + uniform highp vec3 factor_24_26; + uniform highp vec3 factor_27_29; + uniform highp vec3 factor_30_32; + uniform highp float gaussianSum; + uniform highp float expandX; + uniform highp float expandY; + uniform highp float pixelX; + uniform highp float pixelY; + + highp float linearstep(highp float e0, highp float e1, highp float x) { + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); + } + + highp float dlinearstep(highp float e0, highp float d, highp float x) { + return clamp((x - e0) * d, 0.0, 1.0); + } + + void main() { + highp vec2 shift = vec2(delta.x, delta.y) * texture2D(maskSource, qt_TexCoord0).a; + highp float index = delta.z; + mediump vec2 texCoord = qt_TexCoord0; + highp float stepX = 1.0 - pixelX; + highp float stepY = 1.0 - pixelY; + texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX); + texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY); + texCoord += (shift * index); + + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); + " + + property string fragmentShaderEnd: " + if (gaussianSum > 0.0) + gl_FragColor /= gaussianSum; + else + gl_FragColor = texture2D(source, qt_TexCoord0); + + gl_FragColor *= qt_Opacity; + } + " + } +} diff --git a/src/effects/internal/FastMaskedBlur.qml b/src/effects/internal/FastMaskedBlur.qml new file mode 100644 index 0000000..f822601 --- /dev/null +++ b/src/effects/internal/FastMaskedBlur.qml @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Graphical Effects module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: rootItem + property variant source + property variant maskSource + property real blur: 0.0 + property bool transparentBorder: false + property bool cached: false + + SourceProxy { + id: sourceProxy + input: rootItem.source + } + + SourceProxy { + id: maskSourceProxy + input: rootItem.maskSource + } + + ShaderEffectSource { + id: cacheItem + anchors.fill: shaderItem + visible: rootItem.cached + sourceItem: shaderItem + live: true + hideSource: visible + smooth: rootItem.blur > 0 + } + + property string __internalBlurFragmentShader: " + uniform lowp sampler2D source; + uniform lowp float qt_Opacity; + uniform highp float yStep; + uniform highp float xStep; + varying mediump vec2 qt_TexCoord0; + + void main() { + highp vec2 shift = vec2(xStep, yStep); + + lowp vec4 sourceColor = texture2D(source, vec2(qt_TexCoord0.x + shift.x, qt_TexCoord0.y + shift.y * 0.36)) * 0.25 + + texture2D(source, vec2(qt_TexCoord0.x + shift.x * 0.36, qt_TexCoord0.y - shift.y)) * 0.25 + + texture2D(source, vec2(qt_TexCoord0.x - shift.x * 0.36, qt_TexCoord0.y + shift.y)) * 0.25 + + texture2D(source, vec2(qt_TexCoord0.x - shift.x, qt_TexCoord0.y - shift.y * 0.36)) * 0.25; + + gl_FragColor = sourceColor * qt_Opacity; + } + " + + ShaderEffect { + id: mask0 + property variant source: maskSourceProxy.output + anchors.fill: parent + visible: false + smooth: true + } + + ShaderEffectSource { + id: masklevel1 + width: Math.ceil(shaderItem.width / 32) * 32 + height: Math.ceil(shaderItem.height / 32) * 32 + sourceItem: mask0 + hideSource: rootItem.visible + sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0) + visible: false + smooth: rootItem.blur > 0 + } + + ShaderEffect { + id: level0 + property variant source: sourceProxy.output + anchors.fill: parent + visible: false + smooth: true + } + + ShaderEffectSource { + id: level1 + width: Math.ceil(shaderItem.width / 32) * 32 + height: Math.ceil(shaderItem.height / 32) * 32 + sourceItem: level0 + hideSource: rootItem.visible + sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0) + visible: false + smooth: rootItem.blur > 0 + } + + ShaderEffect { + id: effect1 + property variant source: level1 + property real yStep: 1/height + property real xStep: 1/width + anchors.fill: level2 + visible: false + smooth: true + fragmentShader: __internalBlurFragmentShader + } + + ShaderEffectSource { + id: level2 + width: level1.width / 2 + height: level1.height / 2 + sourceItem: effect1 + hideSource: rootItem.visible + visible: false + smooth: true + } + + ShaderEffect { + id: effect2 + property variant source: level2 + property real yStep: 1/height + property real xStep: 1/width + anchors.fill: level3 + visible: false + smooth: true + fragmentShader: __internalBlurFragmentShader + } + + ShaderEffectSource { + id: level3 + width: level2.width / 2 + height: level2.height / 2 + sourceItem: effect2 + hideSource: rootItem.visible + visible: false + smooth: true + } + + ShaderEffect { + id: effect3 + property variant source: level3 + property real yStep: 1/height + property real xStep: 1/width + anchors.fill: level4 + visible: false + smooth: true + fragmentShader: __internalBlurFragmentShader + } + + ShaderEffectSource { + id: level4 + width: level3.width / 2 + height: level3.height / 2 + sourceItem: effect3 + hideSource: rootItem.visible + visible: false + smooth: true + } + + ShaderEffect { + id: effect4 + property variant source: level4 + property real yStep: 1/height + property real xStep: 1/width + anchors.fill: level5 + visible: false + smooth: true + fragmentShader: __internalBlurFragmentShader + } + + ShaderEffectSource { + id: level5 + width: level4.width / 2 + height: level4.height / 2 + sourceItem: effect4 + hideSource: rootItem.visible + visible: false + smooth: true + } + + ShaderEffect { + id: effect5 + property variant source: level5 + property real yStep: 1/height + property real xStep: 1/width + anchors.fill: level6 + visible: false + smooth: true + fragmentShader: __internalBlurFragmentShader + } + + ShaderEffectSource { + id: level6 + width: level5.width / 2 + height: level5.height / 2 + sourceItem: effect5 + hideSource: rootItem.visible + visible: false + smooth: true + } + + ShaderEffect { + id: shaderItem + property variant mask: masklevel1 + property variant source1: level1 + property variant source2: level2 + property variant source3: level3 + property variant source4: level4 + property variant source5: level5 + property variant source6: level6 + property real lod: Math.sqrt(rootItem.blur) * 1.2 - 0.2 + property real weight1 + property real weight2 + property real weight3 + property real weight4 + property real weight5 + property real weight6 + + x: transparentBorder ? -64 : 0 + y: transparentBorder ? -64 : 0 + width: transparentBorder ? parent.width + 128 : parent.width + height: transparentBorder ? parent.height + 128 : parent.height + + fragmentShader: " + uniform lowp sampler2D mask; + uniform lowp sampler2D source1; + uniform lowp sampler2D source2; + uniform lowp sampler2D source3; + uniform lowp sampler2D source4; + uniform lowp sampler2D source5; + uniform lowp sampler2D source6; + uniform lowp float lod; + uniform lowp float qt_Opacity; + varying mediump vec2 qt_TexCoord0; + + mediump float weight(mediump float v) { + if (v <= 0.0) + return 1.0; + + if (v >= 0.5) + return 0.0; + + return 1.0 - v * 2.0; + } + + void main() { + + lowp vec4 maskColor = texture2D(mask, qt_TexCoord0); + mediump float l = lod * maskColor.a; + + mediump float w1 = weight(abs(l - 0.100)); + mediump float w2 = weight(abs(l - 0.300)); + mediump float w3 = weight(abs(l - 0.500)); + mediump float w4 = weight(abs(l - 0.700)); + mediump float w5 = weight(abs(l - 0.900)); + mediump float w6 = weight(abs(l - 1.100)); + + mediump float sum = w1 + w2 + w3 + w4 + w5 + w6; + mediump float weight1 = w1 / sum; + mediump float weight2 = w2 / sum; + mediump float weight3 = w3 / sum; + mediump float weight4 = w4 / sum; + mediump float weight5 = w5 / sum; + mediump float weight6 = w6 / sum; + + lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1; + sourceColor += texture2D(source2, qt_TexCoord0) * weight2; + sourceColor += texture2D(source3, qt_TexCoord0) * weight3; + sourceColor += texture2D(source4, qt_TexCoord0) * weight4; + sourceColor += texture2D(source5, qt_TexCoord0) * weight5; + sourceColor += texture2D(source6, qt_TexCoord0) * weight6; + + gl_FragColor = sourceColor * qt_Opacity; + + } + " + } +} diff --git a/src/effects/internal/GaussianMaskedBlur.qml b/src/effects/internal/GaussianMaskedBlur.qml new file mode 100644 index 0000000..ae013ca --- /dev/null +++ b/src/effects/internal/GaussianMaskedBlur.qml @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Graphical Effects module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: rootItem + property variant source + property variant maskSource + property real radius: 0.0 + property int maximumRadius: 0 + property bool cached: false + property bool transparentBorder: false + + SourceProxy { + id: sourceProxy + input: rootItem.source + } + + SourceProxy { + id: maskSourceProxy + input: rootItem.maskSource + } + + ShaderEffectSource { + id: cacheItem + anchors.fill: blur + visible: rootItem.cached + smooth: true + sourceItem: blur + live: true + hideSource: visible + } + + DirectionalGaussianMaskedBlur { + id: blur + x: transparentBorder ? -maximumRadius : 0 + y: transparentBorder ? -maximumRadius : 0 + width: horizontalBlur.width + height: transparentBorder ? horizontalBlur.height + 2 * maximumRadius : horizontalBlur.height + + horizontalStep: 0.0 + verticalStep: 1.0 / parent.height + + source: ShaderEffectSource { + sourceItem: horizontalBlur + hideSource: true + visible: false + smooth: true + } + maskSource: maskSourceProxy.output + + radius: rootItem.radius + maximumRadius: rootItem.maximumRadius + transparentBorder: rootItem.transparentBorder + } + + DirectionalGaussianMaskedBlur { + id: horizontalBlur + width: transparentBorder ? parent.width + 2 * maximumRadius : parent.width + height: parent.height + + horizontalStep: 1.0 / parent.width + verticalStep: 0.0 + + source: sourceProxy.output + maskSource: maskSourceProxy.output + radius: rootItem.radius + maximumRadius: rootItem.maximumRadius + transparentBorder: rootItem.transparentBorder + visible: false + } +} diff --git a/src/effects/qmldir b/src/effects/qmldir index 635ee01..b9317b6 100644 --- a/src/effects/qmldir +++ b/src/effects/qmldir @@ -15,6 +15,7 @@ HueSaturation 0.1 HueSaturation.qml InnerShadow 0.1 InnerShadow.qml LevelAdjust 0.1 LevelAdjust.qml LinearGradient 0.1 LinearGradient.qml +MaskedBlur 0.1 MaskedBlur.qml OpacityMask 0.1 OpacityMask.qml RadialBlur 0.1 RadialBlur.qml RadialGradient 0.1 RadialGradient.qml |