diff --git a/package/contents/ui/KomplexModel.qml b/package/contents/ui/KomplexModel.qml index 06c5a31..8f2585e 100644 --- a/package/contents/ui/KomplexModel.qml +++ b/package/contents/ui/KomplexModel.qml @@ -54,10 +54,10 @@ Item property string iChannel2: "" property string iChannel3: "" - property var bufferA: null - property var bufferB: null - property var bufferC: null - property var bufferD: null + property var bufferA: ShaderChannel { visible: true; width: mainItem.width; height: mainItem.height } + property var bufferB: ShaderChannel { visible: true; width: mainItem.width; height: mainItem.height } + property var bufferC: ShaderChannel { visible: true; width: mainItem.width; height: mainItem.height } + property var bufferD: ShaderChannel { visible: true; width: mainItem.width; height: mainItem.height } id: mainItem @@ -65,6 +65,7 @@ Item { id: data property var channels: [] + property var buffers: new Map() } Komplex.ShaderPackModel @@ -138,12 +139,155 @@ Item // Load the default shader pack configuration on component completion Component.onCompleted: { + data.buffers.set("{bufferA}", mainItem.bufferA) + data.buffers.set("{bufferB}", mainItem.bufferB) + data.buffers.set("{bufferC}", mainItem.bufferC) + data.buffers.set("{bufferD}", mainItem.bufferD) + + console.log(data.buffers.has("{bufferA}")) + if(wallpaper.configuration.shader_package) shaderPackModel.loadJson(wallpaper.configuration.shader_package); else shaderPackModel.loadJson("/home/parametheus/kde/src/komplex/pack.json"); // Load a default shader pack if none is specified } + // Recursive helper function to parse channels + function parseChannel(channel, json, typeDefault = 2) + { + var source = getFilePath(json.source) + + channel.frameBufferChannel = json.frame_buffer_channel !== undefined ? json.frame_buffer_channel : -1 + channel.type = json.type ? json.type : typeDefault + channel.anchors.fill = mainItem + channel.visible = false + channel.iMouse = Qt.binding(() => { return mainItem.iMouse; }) + channel.iTime = Qt.binding(() => { return mainItem.iTime; }) + channel.iResolution = Qt.binding(() => { return Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0); }) + channel.mouseBias = json.mouse_scale ? json.mouse_scale : 1.0 + channel.iTimeScale = json.time_scale ? json.time_scale : 1.0 + channel.iTimeDelta = Qt.binding(() => { return mainItem.iTimeDelta; }) + + channel.iChannelResolution = Qt.binding(() => { + return [ + Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0) + ]; + }); + + channel.iChannelTime = Qt.binding(() => { + return [ + mainItem.iTime * channel.iTimeScale, + mainItem.iTime * channel.iTimeScale, + mainItem.iTime * channel.iTimeScale, + mainItem.iTime * channel.iTimeScale + ]; + }); + + channel.iFrameRate = Qt.binding(() => { return mainItem.iFrameRate; }) + channel.iFrame = Qt.binding(() => { return mainItem.iFrame; }) + channel.invert = json.invert ? json.invert : false + + channel.source = source + + if (json.channel0) + { + if(typeof json.channel0 === "string") + { + if(data.buffers.has(json.channel0)) + channel.iChannel0 = createBufferAssociation(json.channel0) + else + console.log('Uknown channel buffer 0 ' + json.channel0) + } + else if(typeof json.channel0 === "object") + { + var component = Qt.createComponent("./ShaderChannel.qml") + + if (component.status === Component.Ready) { + channel.iChannel0 = component.createObject(mainItem, { }) + parseChannel(channel.iChannel0, json.channel0) + data.channels.push(channel.iChannel0) // save for destroying + } + } + else + console.log('Uknown channel type 0 ' + typeof json.channel0) + } + + if (json.channel1) + { + if(typeof json.channel1 === "string") + { + if(data.buffers.has(json.channel1)) + channel.iChannel1 = createBufferAssociation(json.channel1) + else + console.log('Uknown channel buffer 1 ' + json.channel1) + } + else if(typeof json.channel1 === "object") + { + var component = Qt.createComponent("./ShaderChannel.qml") + + if (component.status === Component.Ready) { + channel.iChannel1 = component.createObject(mainItem, { }) + parseChannel(channel.iChannel1, json.channel1) + + data.channels.push(channel.iChannel1) // save for destroying + } + } + else + console.log('Uknown channel type 1 ' + typeof json.channel1) + } + + if (json.channel2) + { + if(typeof json.channel2 === "string") + { + if(data.buffers.has(json.channel2)) + channel.iChannel2 = createBufferAssociation(json.channel2) + else + console.log('Uknown channel buffer 2 ' + json.channel2) + } + else if(typeof json.channel2 === "object") + { + var component = Qt.createComponent("./ShaderChannel.qml") + + if (component.status === Component.Ready) { + channel.iChannel2 = component.createObject(mainItem, { }) + parseChannel(channel.iChannel2, json.channel2) + + data.channels.push(channel.iChannel2) // save for destroying + } + } + else + console.log('Uknown channel type 2 ' + typeof json.channel2) + } + + if (json.channel3) + { + if(typeof json.channel3 === "string") + { + if(data.buffers.has(json.channel3)) + channel.iChannel3 = createBufferAssociation(json.channel3) + else + console.log('Uknown channel buffer 3 ' + json.channel3) + } + else if(typeof json.channel3 === "object") + { + var component = Qt.createComponent("./ShaderChannel.qml") + + if (component.status === Component.Ready) { + channel.iChannel3 = component.createObject(mainItem, { }) + parseChannel(channel.iChannel3, json.channel3) + + data.channels.push(channel.iChannel3) // save for destroying + } + } + else + console.log('Uknown channel type 3 ' + typeof json.channel3) + } + } + // Function to parse the pack.json file and set the properties of the ShaderChannel function parsePack(json) { @@ -151,125 +295,19 @@ Item var currentChannel = null; if (pack.bufferA) - mainItem.bufferA = parseChannel(pack.bufferA, 2); + parseChannel(mainItem.bufferA, pack.bufferA, 2); if (pack.bufferB) - mainItem.bufferB = parseChannel(pack.bufferB, 2); + parseChannel(mainItem.bufferB, pack.bufferB, 2); if (pack.bufferC) - mainItem.bufferC = parseChannel(pack.bufferC, 2); + parseChannel(mainItem.bufferC, pack.bufferC, 2); if (pack.bufferD) - mainItem.bufferD = parseChannel(pack.bufferD, 2); + parseChannel(mainItem.bufferD, pack.bufferD, 2); - if (pack.channel0) - { - if(typeof pack.channel0 === "string") - { - switch(pack.channel0) - { - case "{bufferA}": - channelOutput.iChannel0 = mainItem.bufferA - break; - case "{bufferB}": - channelOutput.iChannel0 = mainItem.bufferB - break; - case "{bufferC}": - channelOutput.iChannel0 = mainItem.bufferC - break; - case "{bufferD}": - channelOutput.iChannel0 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + pack.channel0) - break; - } - - } - else if(typeof pack.channel0 === "object") - channelOutput.iChannel0 = parseChannel(pack.channel0); - } - if (pack.channel1) - { - if(typeof pack.channel1 === "string") - { - switch(pack.channel1) - { - case "{bufferA}": - channelOutput.iChannel1 = mainItem.bufferA - break; - case "{bufferB}": - channelOutput.iChannel1 = mainItem.bufferB - break; - case "{bufferC}": - channelOutput.iChannel1 = mainItem.bufferC - break; - case "{bufferD}": - channelOutput.iChannel1 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + pack.channel1) - break; - } - - } - else if(typeof pack.channel1 === "object") - channelOutput.iChannel1 = parseChannel(pack.channel1); - } - if (pack.channel2) - { - if(typeof pack.channel2 === "string") - { - switch(pack.channel2) - { - case "{bufferA}": - channelOutput.iChannel2 = mainItem.bufferA - break; - case "{bufferB}": - channelOutput.iChannel2 = mainItem.bufferB - break; - case "{bufferC}": - channelOutput.iChannel2 = mainItem.bufferC - break; - case "{bufferD}": - channelOutput.iChannel2 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + pack.channel2) - break; - } - - } - else if(typeof pack.channel2 === "object") - channelOutput.iChannel2 = parseChannel(pack.channel2); - } - if (pack.channel3) - { - if(typeof pack.channel3 === "string") - { - switch(pack.channel3) - { - case "{bufferA}": - channelOutput.iChannel3 = mainItem.bufferA - break; - case "{bufferB}": - channelOutput.iChannel3 = mainItem.bufferB - break; - case "{bufferC}": - channelOutput.iChannel3 = mainItem.bufferC - break; - case "{bufferD}": - channelOutput.iChannel3 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + pack.channel3) - break; - } - - } - else if(typeof pack.channel3 === "object") - channelOutput.iChannel3 = parseChannel(pack.channel3); - } + parseChannel(channelOutput, pack, 2) channelOutput.source = getFilePath(pack.source); // Set the shader source file channelOutput.type = ShaderChannel.Type.ShaderChannel; // Set the shader + channelOutput.visible = true if(pack.mouse_scale) channelOutput.mouseBias = pack.mouse_scale @@ -278,169 +316,29 @@ Item channelOutput.iTimeScale = pack.speed } - // Recursive helper function to parse channels - function parseChannel(channel, typeDefault = 0) + // Generate a new ShaderEffectSource for the requested buffer + function createBufferAssociation(buffer) { - if (!channel) return; - var source = getFilePath(channel.source) - - // Qt.createQmlObject() method was not working the same inside plasma - // as it was inside a QMLEngine instance. This resulted in the Loader - // object being undefined and thus breaking the Komplex wallpaper mode. (oops) - - // Instead, use Qt.createComponent() then manually setup bindings - var component = Qt.createComponent("./ShaderChannel.qml") + var component = Qt.createComponent('./ShaderBuffer.qml') var result if (component.status === Component.Ready) { - result = component.createObject(mainItem, { x: 100, y: 100 }); + result = component.createObject(mainItem, { + x:0, + y:0, + sourceItem: data.buffers.get(buffer), + live: true, + sourceRect: Qt.binding(() => { return Qt.rect(0,0,data.buffers.get(buffer).width || 0,data.buffers.get(buffer).height || 0); }), + visible: false, + z:0, + wrapMode: ShaderEffectSource.Repeat, + textureMirroring: ShaderEffectSource.NoMirroring, + textureSize: Qt.size(Qt.binding(() => { return data.buffers.get(buffer).width || 0; } ), Qt.binding(() => { return data.buffers.get(buffer).height || 0; } )), + recursive: false, + mipmap: false + }); } - result.frameBufferChannel = channel.frame_buffer_channel !== undefined ? channel.frame_buffer_channel : -1 - result.type = channel.type ? channel.type : typeDefault - result.anchors.fill = mainItem - result.visible = false - result.iMouse = Qt.binding(() => { return mainItem.iMouse; }) - result.iTime = Qt.binding(() => { return mainItem.iTime; }) - result.iResolution = Qt.binding(() => { return Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0); }) - result.mouseBias = channel.mouse_scale ? channel.mouse_scale : 1.0 - result.iTimeScale = channel.time_scale ? channel.time_scale : 1.0 - result.iTimeDelta = Qt.binding(() => { return mainItem.iTimeDelta; }) - - result.iChannelResolution = Qt.binding(() => { - return [ - Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0), - Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0), - Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0), - Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0) - ]; - }); - - result.iChannelTime = Qt.binding(() => { - return [ - mainItem.iTime * result.iTimeScale, - mainItem.iTime * result.iTimeScale, - mainItem.iTime * result.iTimeScale, - mainItem.iTime * result.iTimeScale - ]; - }); - - result.iFrameRate = Qt.binding(() => { return mainItem.iFrameRate; }) - result.iFrame = Qt.binding(() => { return mainItem.iFrame; }) - result.invert = channel.invert ? channel.invert : false - - result.source = source - - if (channel.channel0) - { - if(typeof channel.channel0 === "string") - { - switch(channel.channel0) - { - case "{bufferA}": - result.iChannel0 = mainItem.bufferA - break; - case "{bufferB}": - result.iChannel0 = mainItem.bufferB - break; - case "{bufferC}": - result.iChannel0 = mainItem.bufferC - break; - case "{bufferD}": - result.iChannel0 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + channel.channel0) - break; - } - - } - else if(typeof channel.channel0 === "object") - result.iChannel0 = parseChannel(channel.channel0); - } - if (channel.channel1) - { - if(typeof channel.channel1 === "string") - { - switch(channel.channel1) - { - case "{bufferA}": - result.iChannel1 = mainItem.bufferA - break; - case "{bufferB}": - result.iChannel1 = mainItem.bufferB - break; - case "{bufferC}": - result.iChannel1 = mainItem.bufferC - break; - case "{bufferD}": - result.iChannel1 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + channel.channel1) - break; - } - - } - else if(typeof channel.channel1 === "object") - result.iChannel1 = parseChannel(channel.channel1); - } - if (channel.channel2) - { - if(typeof channel.channel2 === "string") - { - switch(channel.channel2) - { - case "{bufferA}": - result.iChannel2 = mainItem.bufferA - break; - case "{bufferB}": - result.iChannel2 = mainItem.bufferB - break; - case "{bufferC}": - result.iChannel2 = mainItem.bufferC - break; - case "{bufferD}": - result.iChannel2 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + channel.channel2) - break; - } - - } - else if(typeof channel.channel2 === "object") - result.iChannel2 = parseChannel(channel.channel2); - } - if (channel.channel3) - { - if(typeof channel.channel3 === "string") - { - switch(channel.channel3) - { - case "{bufferA}": - result.iChannel3 = mainItem.bufferA - break; - case "{bufferB}": - result.iChannel3 = mainItem.bufferB - break; - case "{bufferC}": - result.iChannel3 = mainItem.bufferC - break; - case "{bufferD}": - result.iChannel3 = mainItem.bufferD - break; - default: - console.log('Uknown channel type ' + channel.channel3) - break; - } - - } - else if(typeof channel.channel3 === "object") - result.iChannel3 = parseChannel(channel.channel3); - } - - data.channels.push(result) // save for destroying return result; } diff --git a/package/contents/ui/ShaderBuffer.qml b/package/contents/ui/ShaderBuffer.qml new file mode 100644 index 0000000..b37a4d4 --- /dev/null +++ b/package/contents/ui/ShaderBuffer.qml @@ -0,0 +1,24 @@ +import QtQuick + +Item +{ + property alias sourceItem: source.sourceItem + property alias format: source.format + property alias hideSource: source.hideSource + property alias live: source.live + property alias mipmap: source.mipmap + property alias recursive: source.recursive + property alias samples: source.samples + property alias sourceRect: source.sourceRect + property alias textureMirroring: source.textureMirroring + property alias textureSize: source.textureSize + property alias wrapMode: source.wrapMode + + anchors.fill: parent + + ShaderEffectSource + { + anchors.fill: parent + id: source + } +} \ No newline at end of file