I have a shader that I'm running and I want to be able to disable the shader on the press on the button. I want to disable it so it doesn't use any extra resources. How can I achieve this? Here I have an example where a shader slowly fades in and out, and I want to disable the shader when you click the button on the top left. Right now, I get this exception:
ShaderEffect: Property 'source' is not assigned a valid texture provider (std::nullptr_t).
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
width: 1024
height: 600
visible: true
property bool shaderEnabled: true
Rectangle {
id: rect
anchors.fill: parent
color: "gray"
layer.enabled: shaderEnabled
Text {
anchors.centerIn: parent
text: qsTr("Hello")
font.pixelSize: 40
color: "blue"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if (shader.opacity > 0) {
shader.opacity = 0
console.log("Hiding")
} else {
shader.opacity = 1
console.log("Showing")
}
}
}
Button {
id: shaderButton
text: shaderEnabled ? "Disable shader" : "Enable shader"
onClicked: {
shaderEnabled = !shaderEnabled
}
}
ShaderEffect {
id: shader
anchors.fill: parent
property variant source: shaderEnabled ? rect : null
Behavior on opacity { PropertyAnimation {} }
opacity: 0
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
void main() {
gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(1.0, 1.0, 0.0, 1.0) * qt_Opacity;
}"
}
}
Adding a visible: ShaderEnabled
to the ShaderEffect seems to work but I still see the error message which leads me to believe that it's still using the resources. Would using a Loader
help?
I know Loader was mentioned, but, a clean way to avoid Loaders is by using a Repeater and a model. When shaderEnabled is true, it will instantiate a new ShaderEffect instance. When shaderEnabled is false, it will destroy that ShaderEffect instance. To implement this in your example, you will need to rework how you control opacity via a property similar to how you have done shaderEnabled.
Repeater {
model: shaderEnabled ? 1 : 0
ShaderEffect {
}
}