From a47f8063ca9a59872d90b58fe72d465cbae559f6 Mon Sep 17 00:00:00 2001 From: Digital Artifex <7929434+DigitalArtifex@users.noreply.github.com> Date: Fri, 15 Aug 2025 09:33:12 -0400 Subject: [PATCH] Added recursive buffer support --- .gitignore | 6 +++ package/contents/ui/KomplexModel.qml | 51 +++++++++++++++++++------- package/contents/ui/ShaderChannel.qml | 50 ++++++++++++++++++++++--- package/contents/ui/ShaderToyModel.qml | 1 + tools/ShaderToyProcessor.py | 11 ++++-- 5 files changed, 96 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 5d5a771..ee10186 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,12 @@ tools/processed/* tools/build/* tools/processed/ tools/build/ +tools/broken +tools/broken/* +tools/packs_build/ +tools/packs_processed/ +tools/packs_build/* +tools/packs_processed/* PKGBUILD #VSCode Ignores diff --git a/package/contents/ui/KomplexModel.qml b/package/contents/ui/KomplexModel.qml index 29e3136..c45d1d2 100644 --- a/package/contents/ui/KomplexModel.qml +++ b/package/contents/ui/KomplexModel.qml @@ -65,7 +65,7 @@ Item Komplex.ShaderPackModel { id: shaderPackModel - onJsonChanged: + onJsonChanged: () => { // clean up old channels while(data.channels.length > 0) @@ -125,6 +125,7 @@ Item mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) mainItem.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight) + mainItem.iFrame += 1 } } } @@ -145,13 +146,13 @@ Item var currentChannel = null; if (pack.channel0) - channelOutput.iChannel0 = parseChannel(pack.channel0); + channelOutput.iChannel0 = parseChannel(pack.channel0, channelOutput); if (pack.channel1) - channelOutput.iChannel1 = parseChannel(pack.channel1); + channelOutput.iChannel1 = parseChannel(pack.channel1, channelOutput); if (pack.channel2) - channelOutput.iChannel2 = parseChannel(pack.channel2); + channelOutput.iChannel2 = parseChannel(pack.channel2, channelOutput); if (pack.channel3) - channelOutput.iChannel3 = parseChannel(pack.channel3); + channelOutput.iChannel3 = parseChannel(pack.channel3, channelOutput); channelOutput.source = getFilePath(pack.source); // Set the shader source file channelOutput.type = ShaderChannel.Type.ShaderChannel; // Set the shader @@ -164,7 +165,7 @@ Item } // Recursive helper function to parse channels - function parseChannel(channel) + function parseChannel(channel, parent) { if (!channel) return; @@ -181,25 +182,49 @@ Item if (component.status === Component.Ready) { result = component.createObject(mainItem, { x: 100, y: 100 }); } + result.frameBufferChannel = channel.frameBufferChannel !== undefined ? channel.frameBufferChannel : -1 result.type = channel.type result.anchors.fill = mainItem result.visible = false - result.iMouse = Qt.binding(function () { return mainItem.iMouse; }) - result.iTime = Qt.binding(function() { return mainItem.iTime; }) - result.iResolution = Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0) + 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) - result.iChannel0 = parseChannel(channel.channel0); + result.iChannel0 = parseChannel(channel.channel0, result); if (channel.channel1) - result.iChannel1 = parseChannel(channel.channel1); + result.iChannel1 = parseChannel(channel.channel1, result); if (channel.channel2) - result.iChannel2 = parseChannel(channel.channel2); + result.iChannel2 = parseChannel(channel.channel2, result); if (channel.channel3) - result.iChannel3 = parseChannel(channel.channel3); + result.iChannel3 = parseChannel(channel.channel3, result); data.channels.push(result) // save for destroying diff --git a/package/contents/ui/ShaderChannel.qml b/package/contents/ui/ShaderChannel.qml index 78cddac..2f3524b 100644 --- a/package/contents/ui/ShaderChannel.qml +++ b/package/contents/ui/ShaderChannel.qml @@ -68,6 +68,7 @@ Item property real mouseBias: 1 property var iDate property real iTimeScale: 1 // This is used to scale the time for the shader, allowing for slow motion or fast forward effects per channel + property int frameBufferChannel: -1 property bool invert @@ -250,6 +251,10 @@ Item Item { + property var frameBufferData: undefined + id: channelShaderContent + anchors.fill: parent + // Setup the shader effect sources for each channel // These are needed to provide the uniform data to the shader channel buffers ShaderEffectSource @@ -259,6 +264,9 @@ Item live: true smooth: true sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + wrapMode: ShaderEffectSource.Repeat + textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + textureMirroring: ShaderEffectSource.NoMirroring } ShaderEffectSource @@ -268,6 +276,9 @@ Item live: true smooth: true sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + wrapMode: ShaderEffectSource.Repeat + textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + textureMirroring: ShaderEffectSource.NoMirroring } ShaderEffectSource @@ -277,6 +288,9 @@ Item live: true smooth: true sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + wrapMode: ShaderEffectSource.Repeat + textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + textureMirroring: ShaderEffectSource.NoMirroring } ShaderEffectSource @@ -286,15 +300,33 @@ Item live: true smooth: true sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + wrapMode: ShaderEffectSource.Repeat + textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + textureMirroring: ShaderEffectSource.NoMirroring + } + + // recursive frame buffer + ShaderEffectSource + { + id: frameBufferSource + sourceItem: channelShaderContent + live: true + sourceRect: Qt.rect(0,0, channelShaderContent.width, channelShaderContent.height) + wrapMode: ShaderEffectSource.Repeat + recursive: true + textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + anchors.fill: parent + visible: false + textureMirroring: ShaderEffectSource.NoMirroring } // The shader effect that will be used to render the shader ShaderEffect { - property var iChannel0: channelSource0 - property var iChannel1: channelSource1 - property var iChannel2: channelSource2 - property var iChannel3: channelSource3 + property var iChannel0: channel.frameBufferChannel === 0 ? frameBufferSource : channelSource0 + property var iChannel1: channel.frameBufferChannel === 1 ? frameBufferSource : channelSource1 + property var iChannel2: channel.frameBufferChannel === 2 ? frameBufferSource : channelSource2 + property var iChannel3: channel.frameBufferChannel === 3 ? frameBufferSource : channelSource3 property var iResolution: channel.iResolution property var iTime: data.iTime @@ -310,6 +342,8 @@ Item fragmentShader: Qt.resolvedUrl(channel.source) anchors.fill: parent + + id: channelShaderOutput } } } @@ -374,8 +408,7 @@ Item } } - // Supporting this as an mp3 feels kinda silly. Should really figure out how to capture desktop audio with qml - // UPDATE: This is not currently supported in QML, so we will need to implement this in C++ later + // Connect the audio channel to the cpp backend Component { id: channelAudio @@ -414,6 +447,11 @@ Item { Komplex.AudioModel.startCapture() } + + Component.onDestruction: + { + Komplex.AudioModel.stopCapture() + } } } } \ No newline at end of file diff --git a/package/contents/ui/ShaderToyModel.qml b/package/contents/ui/ShaderToyModel.qml index 391882a..d256794 100644 --- a/package/contents/ui/ShaderToyModel.qml +++ b/package/contents/ui/ShaderToyModel.qml @@ -189,6 +189,7 @@ Item mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) mainItem.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight) + mainItem.iFrame += 1 } } } diff --git a/tools/ShaderToyProcessor.py b/tools/ShaderToyProcessor.py index 51b22c8..e4e4c51 100644 --- a/tools/ShaderToyProcessor.py +++ b/tools/ShaderToyProcessor.py @@ -85,6 +85,10 @@ Examples: default='processed', help='Temporary Files Directory') + parser.add_argument('-q', '--qsb', + default='/usr/lib/qt6/bin/qsb', + help='QSB Compiler Location') + return parser.parse_args() def process(): @@ -193,9 +197,8 @@ def compile(): dirname = os.path.basename(source_directory) - if args.output: - output_directory = args.output + '/' + dirname - + qsb = args.qsb + output_directory = args.output + '/' + dirname source_directory = temp_directory + '/' + dirname if args.verbose: @@ -227,7 +230,7 @@ def compile(): # Construct and execute the command cmd = [ - '/usr/lib/qt6/bin/qsb', '--glsl', '330', '--hlsl', '50', '--msl', '12', + qsb, '--glsl', '330', '--hlsl', '50', '--msl', '12', '-o', output_file_path, source_file_path ]