qt - Clip QML's ShaderEffect to circular shape -
i'm using shadereffect
in qml have scaled visual copy of item. copy should moveable , dynamic (live
property of shadereffectsource
set true
).
my problem want inside of round rectangle
won't clipped it. shadereffect
overlaps parent , quadratic.
i've coded quick qml example shows problem:
import qtquick 2.4 import qtquick.controls 1.3 applicationwindow { title: qstr("hello shaders") width: 640 height: 480 visible: true color: "green" rectangle { id: examplerect property bool redstate: false anchors.centerin: parent width: parent.width / 3 height: parent.height / 3 color: redstate ? "red" : "cyan" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "white" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "green" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "yellow" } } } timer { interval: 2000 repeat: true running: true ontriggered: { examplerect.redstate = !examplerect.redstate } } } mousearea { anchors.fill: parent hoverenabled: true onpositionchanged: { shadereffectcontainer.x = mouse.x shadereffectcontainer.y = mouse.y } } rectangle { id: shadereffectcontainer width: 100; height: width; radius: width / 2; border.width: 2 shadereffectsource { id: source sourceitem: examplerect visible: false } shadereffect { anchors.fill: parent property variant source: source vertexshader: " uniform highp mat4 qt_matrix; attribute highp vec4 qt_vertex; attribute highp vec2 qt_multitexcoord0; varying highp vec2 qt_texcoord0; void main() { qt_texcoord0 = qt_multitexcoord0 * 1.5 * vec2(0.5, 0.5); gl_position = qt_matrix * qt_vertex; }" fragmentshader: " varying highp vec2 qt_texcoord0; uniform sampler2d source; uniform lowp float qt_opacity; void main() { gl_fragcolor = texture2d(source, qt_texcoord0) * qt_opacity; }" } } }
as can see, examplerect
declared round, it's child overlapping it.
i have tried possible combinations of clip
property , have spent day trying fragment/vertex shaders. no luck, might guess. :)
i've solved problem using layers shown in this answer.
@denimpowell hint.
below updated example code circular shadereffect
.
import qtquick 2.4 import qtquick.controls 1.3 applicationwindow { title: qstr("hello shaders") width: 640 height: 480 visible: true color: "green" rectangle { id: examplerect property bool redstate: false anchors.centerin: parent width: parent.width / 3 height: parent.height / 3 color: redstate ? "red" : "cyan" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "white" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "green" rectangle { anchors.centerin: parent width: parent.width / 2; height: width; color: "yellow" } } } timer { interval: 2000 repeat: true running: true ontriggered: { examplerect.redstate = !examplerect.redstate } } } mousearea { anchors.fill: parent hoverenabled: true onpositionchanged: { shadereffectcontainer.x = mouse.x shadereffectcontainer.y = mouse.y } } rectangle { id: shadereffectcontainer width: 100; height: width; color: "transparent" rectangle { id: rectanglesource anchors.fill: parent shadereffectsource { id: source sourceitem: examplerect visible: false } shadereffect { anchors.fill: parent property variant source: source vertexshader: " uniform highp mat4 qt_matrix; attribute highp vec4 qt_vertex; attribute highp vec2 qt_multitexcoord0; varying highp vec2 qt_texcoord0; void main() { qt_texcoord0 = qt_multitexcoord0 * 1.5 * vec2(0.5, 0.5); gl_position = qt_matrix * qt_vertex; }" fragmentshader: " varying highp vec2 qt_texcoord0; uniform sampler2d source; uniform lowp float qt_opacity; void main() { gl_fragcolor = texture2d(source, qt_texcoord0) * qt_opacity; }" } visible: false layer.enabled: true } rectangle { id: masklayer anchors.fill: parent radius: parent.width / 2 color: "red" border.color: "black" layer.enabled: true layer.samplername: "masksource" layer.effect: shadereffect { property var colorsource: rectanglesource fragmentshader: " uniform lowp sampler2d colorsource; uniform lowp sampler2d masksource; uniform lowp float qt_opacity; varying highp vec2 qt_texcoord0; void main() { gl_fragcolor = texture2d(colorsource, qt_texcoord0) * texture2d(masksource, qt_texcoord0).a * qt_opacity; } " } } // draw border line rectangle { anchors.fill: parent radius: parent.width / 2 border.color: "black" border.width: 1 color: "transparent" } } }
Comments
Post a Comment