diff options
22 files changed, 1383 insertions, 0 deletions
diff --git a/doc/src/images/MaskedBlur_butterfly.png b/doc/src/images/MaskedBlur_butterfly.png Binary files differnew file mode 100644 index 0000000..b0422bf --- /dev/null +++ b/doc/src/images/MaskedBlur_butterfly.png diff --git a/doc/src/images/MaskedBlur_fast1.png b/doc/src/images/MaskedBlur_fast1.png Binary files differnew file mode 100644 index 0000000..03aa6ec --- /dev/null +++ b/doc/src/images/MaskedBlur_fast1.png diff --git a/doc/src/images/MaskedBlur_fast2.png b/doc/src/images/MaskedBlur_fast2.png Binary files differnew file mode 100644 index 0000000..c2067da --- /dev/null +++ b/doc/src/images/MaskedBlur_fast2.png diff --git a/doc/src/images/MaskedBlur_mask.png b/doc/src/images/MaskedBlur_mask.png Binary files differnew file mode 100644 index 0000000..d81d429 --- /dev/null +++ b/doc/src/images/MaskedBlur_mask.png diff --git a/doc/src/images/MaskedBlur_radius1.png b/doc/src/images/MaskedBlur_radius1.png Binary files differnew file mode 100644 index 0000000..b33ff5e --- /dev/null +++ b/doc/src/images/MaskedBlur_radius1.png diff --git a/doc/src/images/MaskedBlur_radius2.png b/doc/src/images/MaskedBlur_radius2.png Binary files differnew file mode 100644 index 0000000..c4332e3 --- /dev/null +++ b/doc/src/images/MaskedBlur_radius2.png diff --git a/doc/src/images/MaskedBlur_radius3.png b/doc/src/images/MaskedBlur_radius3.png Binary files differnew file mode 100644 index 0000000..03aa6ec --- /dev/null +++ b/doc/src/images/MaskedBlur_radius3.png diff --git a/doc/src/images/MaskedBlur_transparentBorder1.png b/doc/src/images/MaskedBlur_transparentBorder1.png Binary files differnew file mode 100644 index 0000000..c4792ba --- /dev/null +++ b/doc/src/images/MaskedBlur_transparentBorder1.png diff --git a/doc/src/images/MaskedBlur_transparentBorder2.png b/doc/src/images/MaskedBlur_transparentBorder2.png Binary files differnew file mode 100644 index 0000000..eeab61e --- /dev/null +++ b/doc/src/images/MaskedBlur_transparentBorder2.png diff --git a/doc/src/qtgraphicaleffects-maskedblur.qdoc b/doc/src/qtgraphicaleffects-maskedblur.qdoc new file mode 100644 index 0000000..0a68a23 --- /dev/null +++ b/doc/src/qtgraphicaleffects-maskedblur.qdoc @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Graphical Effects module. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlclass MaskedBlur + \inqmlmodule QtGraphicalEffects + \brief Applies a blur effect with a varying intesity. + + MaskedBlur effect softens the image by blurring it. The intensity of the blur + can be controlled for each pixel using maskSource so that some parts of the + source are blurred more than others. By default the effect produces a high quality + result, thus the rendering speed may not be the highest possible. + The rendering speed is reduced especially if the maximumRadius is large. + For use cases that require faster rendering speed and the highest possible visual + quality is not necessary, property \l fast can be set to true. + + \table + \header + \o Source + \o MaskSource + \o Effect applied + \row + \o \image Original_butterfly.png + \o \image MaskedBlur_mask.png + \o \image MaskedBlur_butterfly.png + \endtable + + \section1 Example + + The following example shows how to apply the effect. + \snippet snippets/MaskedBlur-example.qml example + + \section1 Memory Consumption + + The internal memory consumption is approximately the same as the memory + consumption of the the source item area in pixels. + If source item is not Image or ShaderEffectSource, then effect internally creates one ShaderEffectSource item per source. + Enabling the effect cache increases the memory consumption. + + \table + \header + \o Estimated memory usage for an effect with a size of 640x480 pixels with 32 bits per pixel (bpp) + \o + \row + \o Effect internal + \o 1.2 MB + \row + \o ShaderEffectSource (if used) + \o 1.2 MB + \row + \o ShaderEffectSource for maskSource (if used) + \o 1.2 MB + \row + \row + \o Effect internal cache (if enabled) + \o 1.2 MB + \row + \o TOTAL (max) + \o 4.8 MB + \endtable + +*/ + +/*! + \qmlproperty variant QtGraphicalEffects::MaskedBlur::source + + This property defines the source item that is going to be blurred. + +*/ + +/*! + \qmlproperty variant QtGraphicalEffects::MaskedBlur::maskSource + + This property defines the item that is controlling the final intensity of the + blur. The pixel alpha channel value from maskSource defines the actual blur + radius that is going to be used for blurring the corresponding source pixel. + Opaque maskSource pixels produce blur with specified \l radius, while transparent + pixels suppress the blur completely. Semitransparent maskSource pixels produce + blur with a radius that is interpolated according to the pixel transparency + level. + +*/ + +/*! + \qmlproperty real QtGraphicalEffects::MaskedBlur::radius + + This property defines the distance of the neighboring pixels which affect + the blurring of an individual pixel. A larger radius increases the blur + effect. + + \bold Note: The radius value should always be lower than maximumRadius, + otherwise the blur quality is not optimal. + + The value ranges from 0.0 (no blur) to maximumRadius (maximum blur). By + default, the property is set to \c 0.0 (no blur). + + \table + \header + \o Output examples with different radius values + \o + \o + \row + \o \image MaskedBlur_radius1.png + \o \image MaskedBlur_radius2.png + \o \image MaskedBlur_radius3.png + \row + \o \bold { radius: 0 } + \o \bold { radius: 8 } + \o \bold { radius: 16 } + \row + \o \l maximumRadius: 16 + \o \l maximumRadius: 16 + \o \l maximumRadius: 16 + \row + \o \l transparentBorder: false + \o \l transparentBorder: false + \o \l transparentBorder: false + \row + \o \l fast: false + \o \l fast: false + \o \l fast: false + \endtable + +*/ + +/*! + \qmlproperty real QtGraphicalEffects::MaskedBlur::maximumRadius + + This property defines the maximum radius value that can be used without + compromising the blur quality. Setting a too large maximumRadius value has a + negative impact on the rendering performance. Changing this property may + cause the underlying OpenGL shaders to be recompiled. + + Ideally, this value should be the same as the highest required radius value, + for example. if the radius is animated between 0.0 and 4.0, maximumRadius + should be set to 4. + + The value ranges from 0 to 16. By default, the property is set to \c 0. + +*/ + +/*! + \qmlproperty bool QtGraphicalEffects::MaskedBlur::transparentBorder + + This property defines the blur near the edges of the item, where the pixel + blurring is affected by the pixels just outside the source. + + Setting this property to \c false, interprets the pixels outside the item + according to the OpenGL clamp-to-edge mode. If the source is Image, the pixels + are interpreted according to the Image::fillMode property. If the source is + ShaderEffectSource, the pixels are interpreted according to the + ShaderEffectSource::wrapMode property. + + Setting this property to \c true, interprets the pixels outside the item to + be transparent. This behavior is similar to the OpenGL clamp-to-border + extension. The blur is expanded slightly outside the effect item area. + + By default, the property is set to \c false. + + \table + \header + \o Output examples with different transparentBorder values + \o + \o + \row + \o \image MaskedBlur_transparentBorder1.png + \o \image MaskedBlur_transparentBorder2.png + \row + \o \bold { transparentBorder: false } + \o \bold { transparentBorder: true } + \row + \o \l radius: 64 + \o \l radius: 64 + \row + \o \l maximumRadius: 16 + \o \l maximumRadius: 16 + \row + \o \l fast: true + \o \l fast: true + \endtable + +*/ + +/*! + \qmlproperty bool QtGraphicalEffects::MaskedBlur::fast + + This property selects the blurring algorithm that is used to produce the + blur. Setting this to true enables fast algorithm, setting value to false + produces higher quality result. + + By default, the property is set to \c false. + + \table + \header + \o Output examples with different fast values + \o + \o + \row + \o \image MaskedBlur_fast1.png + \o \image MaskedBlur_fast2.png + \row + \o \bold { fast: false } + \o \bold { fast: true } + \row + \o \l radius: 16 + \o \l radius: 16 + \row + \o \l maximumRadius: 16 + \o \l maximumRadius: 16 + \row + \o \l transparentBorder: false + \o \l transparentBorder: false + \endtable + +*/ + +/*! + \qmlproperty bool QtGraphicalEffects::MaskedBlur::cached + + This property allows the effect output pixels to be cached in order to + improve the rendering performance. + Every time the source or effect properties are changed, the pixels in the cache + must be updated. Memory consumption is increased, because an extra buffer of + memory is required for storing the effect output. + + It is recommended to disable the cache when the source or the effect + properties are animated. + + By default, the property is set to \c false. + +*/ diff --git a/doc/src/qtgraphicaleffects.qdoc b/doc/src/qtgraphicaleffects.qdoc index 3a1110e..ab425cc 100644 --- a/doc/src/qtgraphicaleffects.qdoc +++ b/doc/src/qtgraphicaleffects.qdoc @@ -79,6 +79,7 @@ Blur \list \o \l {QtGraphicalEffects::FastBlur}{FastBlur} - applies a fast blur effect \o \l {QtGraphicalEffects::GaussianBlur}{GaussianBlur} - applies a higher quality blur effect +\o \l {QtGraphicalEffects::MaskedBlur}{MaskedBlur} - applies a varying intensity blur effect \o \l {QtGraphicalEffects::RecursiveBlur}{RecursiveBlur} - blurs repeatedly, providing a strong blur effect \endlist diff --git a/doc/src/snippets/MaskedBlur-example.qml b/doc/src/snippets/MaskedBlur-example.qml new file mode 100644 index 0000000..9bf8ccf --- /dev/null +++ b/doc/src/snippets/MaskedBlur-example.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +//! [example] +import QtQuick 2.0 +import QtGraphicalEffects 0.1 + +Item { + width: 300 + height: 300 + + Image { + id: butterfly + source: "images/butterfly.png" + sourceSize: Qt.size(parent.width, parent.height) + smooth: true + visible: false + } + + Rectangle { + id: mask + anchors.fill: butterfly + visible: false + gradient: Gradient { + GradientStop { position: 0.3; color: "#ff000000" } + GradientStop { position: 0.7; color: "#00000000" } + } + } + + MaskedBlur { + anchors.fill: butterfly + source: butterfly + maskSource: mask + radius: 16 + maximumRadius: 16 + } +} +//! [example] 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 diff --git a/tests/auto/tst_qtgraphicaleffects.cpp b/tests/auto/tst_qtgraphicaleffects.cpp index 42ed280..c6915a9 100644 --- a/tests/auto/tst_qtgraphicaleffects.cpp +++ b/tests/auto/tst_qtgraphicaleffects.cpp @@ -66,6 +66,7 @@ private slots: void innerShadow(); void levelAdjust(); void linearGradient(); + void maskedBlur(); void opacityMask(); void radialBlur(); void radialGradient(); @@ -697,6 +698,33 @@ void tst_qtgraphicaleffects::levelAdjust() delete obj; } +void tst_qtgraphicaleffects::maskedBlur() +{ + // Creation + QString componentStr = "import QtQuick 2.0\n" + "import effects 0.1\n" + "MaskedBlur {" + "source: ShaderEffectSource {sourceItem: Rectangle {width: 100; height: 100}}" + "maskSource: ShaderEffectSource {sourceItem: Rectangle {width: 100; height: 100}}" + "width: 50; height: 50\n" + "}"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QObject *obj = component.create(); + QTest::qWait(100); + QVERIFY(obj != 0); + + // Default values + QCOMPARE(obj->property("source").toInt(), 0); + QCOMPARE(obj->property("maskSource").toInt(), 0); + QCOMPARE(obj->property("radius").toDouble(), 0.0); + QCOMPARE(obj->property("maximumRadius").toInt(), 0); + QCOMPARE(obj->property("cached").toBool(), false); + QCOMPARE(obj->property("transparentBorder").toBool(), false); + QCOMPARE(obj->property("fast").toBool(), false); + + delete obj; +} QTEST_MAIN(tst_qtgraphicaleffects) diff --git a/tests/manual/testbed/TestBedModel.qml b/tests/manual/testbed/TestBedModel.qml index 58eb38b..7fb27ec 100644 --- a/tests/manual/testbed/TestBedModel.qml +++ b/tests/manual/testbed/TestBedModel.qml @@ -48,6 +48,7 @@ ListModel { ListElement { name: "TestRectangularGlow.qml"; group: "Glow"; last: true } ListElement { name: "TestFastBlur.qml"; group: "Blur" } ListElement { name: "TestGaussianBlur.qml"; group: "Blur" } + ListElement { name: "TestMaskedBlur.qml"; group: "Blur" } ListElement { name: "TestRecursiveBlur.qml"; group: "Blur"; last: true } ListElement { name: "TestDirectionalBlur.qml"; group: "Motion Blur"; } ListElement { name: "TestRadialBlur.qml"; group: "Motion Blur"; } diff --git a/tests/manual/testbed/TestMaskedBlur.qml b/tests/manual/testbed/TestMaskedBlur.qml new file mode 100644 index 0000000..1c5fe35 --- /dev/null +++ b/tests/manual/testbed/TestMaskedBlur.qml @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** 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 "../../../src/effects" + +TestCaseTemplate { + ImageSource { + id: imageSource + source: "images/butterfly.png" + forcedUpdateAnimationRunning: updateCheckBox.selected + } + + Rectangle { + id: maskSource + anchors.fill: imageSource + gradient: Gradient { + GradientStop { position: 0.3; color: Qt.rgba(maskAlphaBeginSlider.value, maskAlphaBeginSlider.value, maskAlphaBeginSlider.value, maskAlphaBeginSlider.value) } + GradientStop { position: 0.7; color: Qt.rgba(maskAlphaEndSlider.value, maskAlphaEndSlider.value, maskAlphaEndSlider.value, maskAlphaEndSlider.value) } + } + } + + ShaderEffectSource { + id: shaderEffectSource + sourceItem: imageSource + live: updateCheckBox.selected + hideSource: enabledCheckBox.selected + smooth: true + onLiveChanged: scheduleUpdate() + visible: false + } + + ShaderEffectSource { + id: shaderEffectMaskSource + sourceItem: maskSource + live: true + hideSource: enabledCheckBox.selected + smooth: true + onLiveChanged: scheduleUpdate() + visible: false + } + + MaskedBlur { + id: effect + anchors.fill: imageSource + radius: radiusSlider.value + maximumRadius: maximumRadiusSlider.value + transparentBorder: transparentBorderCheckBox.selected + visible: enabledCheckBox.selected + cached: cachedCheckBox.selected + fast: fastCheckBox.selected + source: sourceType.value == "shaderEffectSource" ? shaderEffectSource : imageSource + maskSource: sourceType.value == "shaderEffectSource" ? shaderEffectMaskSource : maskSource + } + + bgColor: bgColorPicker.color + controls: [ + Control { + caption: "general" + Slider { + id: radiusSlider + minimum: 0.0 + maximum: 64.0 + value: 16.0 + caption: "radius" + } + Slider { + id: maximumRadiusSlider + minimum: 0 + maximum: 16 + value: 16 + integer: true + caption: "maximumRadius" + } + CheckBox { + id: transparentBorderCheckBox + caption: "transparentBorder" + selected: false + } + CheckBox { + id: fastCheckBox + caption: "fast" + selected: false + } + }, + Control { + caption: "maskSource gradient" + Slider { + id: maskAlphaBeginSlider + minimum: 0.0 + maximum: 1.0 + value: 1.0 + caption: "opacity begin" + } + Slider { + id: maskAlphaEndSlider + minimum: 0.0 + maximum: 1.0 + value: 0.0 + caption: "opacity end" + } + }, + + Control { + caption: "advanced" + last: true + Label { + caption: "Effect size" + text: effect.width + "x" + effect.height + } + Label { + caption: "FPS" + text: fps + } + CheckBox { + id: cachedCheckBox + caption: "cached" + } + CheckBox { + id: enabledCheckBox + caption: "enabled" + } + CheckBox { + id: updateCheckBox + caption: "animated" + selected: false + } + RadioButtonColumn { + id: sourceType + value: "shaderEffectSource" + caption: "source type" + RadioButton { + caption: "shaderEffectSource" + selected: caption == sourceType.value + onPressedChanged: sourceType.value = caption + } + RadioButton { + caption: "image" + selected: caption == sourceType.value + onPressedChanged: { + sourceType.value = caption + updateCheckBox.selected = false + } + } + } + BGColorPicker { + id: bgColorPicker + } + } + ] +} diff --git a/tools/pngdumper/ItemModel.qml b/tools/pngdumper/ItemModel.qml index f6d0cfa..6445208 100644 --- a/tools/pngdumper/ItemModel.qml +++ b/tools/pngdumper/ItemModel.qml @@ -815,6 +815,45 @@ VisualItemModel { property variant __values: ["#FFFFFFFF", "#FFFFFF80", "#FFFFFF30"] } + MaskedBlur { + width: size + height: size + source: butterfly + maskSource: blurMask + maximumRadius: 16 + property string __name: "MaskedBlur" + property variant __properties: ["radius", "maximumRadius", "transparentBorder", "fast"] + property string __varyingProperty: "radius" + property variant __values: [0.0, 8.0, 16.0] + } + MaskedBlur { + width: size + height: size + source: butterfly + maskSource: blurMask + radius: 16 + maximumRadius: 16 + property string __name: "MaskedBlur" + property variant __properties: ["radius", "maximumRadius", "transparentBorder", "fast"] + property string __varyingProperty: "fast" + property variant __values: [false, true] + } + MaskedBlur { + function init() { checkerboard = true } + width: size + height: size + source: bug + maskSource: blurMask + radius: 64 + maximumRadius: 16 + fast: true + property string __name: "MaskedBlur" + property variant __properties: ["radius", "maximumRadius", "transparentBorder", "fast"] + property string __varyingProperty: "transparentBorder" + property variant __values: [false, true] + function uninit() { checkerboard = false } + } + Item { id: theEnd width: size diff --git a/tools/pngdumper/pngdumper.qml b/tools/pngdumper/pngdumper.qml index c3dab22..0d47b7d 100644 --- a/tools/pngdumper/pngdumper.qml +++ b/tools/pngdumper/pngdumper.qml @@ -51,6 +51,17 @@ Rectangle { property bool checkerboard: false color: background + Rectangle { + id: blurMask + anchors.fill: parent + visible: false + gradient: Gradient { + GradientStop { position: 0.3; color: "#ff000000" } + GradientStop { position: 0.7; color: "#00000000" } + } + } + + Gradient { id: firstGradient GradientStop { position: 0.000; color: Qt.rgba(1, 0, 0, 1) } |