Added recursive buffer support

This commit is contained in:
Digital Artifex
2025-08-15 09:33:12 -04:00
parent 724c017240
commit a47f8063ca
5 changed files with 96 additions and 23 deletions

6
.gitignore vendored
View File

@@ -58,6 +58,12 @@ tools/processed/*
tools/build/* tools/build/*
tools/processed/ tools/processed/
tools/build/ tools/build/
tools/broken
tools/broken/*
tools/packs_build/
tools/packs_processed/
tools/packs_build/*
tools/packs_processed/*
PKGBUILD PKGBUILD
#VSCode Ignores #VSCode Ignores

View File

@@ -65,7 +65,7 @@ Item
Komplex.ShaderPackModel Komplex.ShaderPackModel
{ {
id: shaderPackModel id: shaderPackModel
onJsonChanged: onJsonChanged: () =>
{ {
// clean up old channels // clean up old channels
while(data.channels.length > 0) while(data.channels.length > 0)
@@ -125,6 +125,7 @@ Item
mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) 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.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight)
mainItem.iFrame += 1
} }
} }
} }
@@ -145,13 +146,13 @@ Item
var currentChannel = null; var currentChannel = null;
if (pack.channel0) if (pack.channel0)
channelOutput.iChannel0 = parseChannel(pack.channel0); channelOutput.iChannel0 = parseChannel(pack.channel0, channelOutput);
if (pack.channel1) if (pack.channel1)
channelOutput.iChannel1 = parseChannel(pack.channel1); channelOutput.iChannel1 = parseChannel(pack.channel1, channelOutput);
if (pack.channel2) if (pack.channel2)
channelOutput.iChannel2 = parseChannel(pack.channel2); channelOutput.iChannel2 = parseChannel(pack.channel2, channelOutput);
if (pack.channel3) 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.source = getFilePath(pack.source); // Set the shader source file
channelOutput.type = ShaderChannel.Type.ShaderChannel; // Set the shader channelOutput.type = ShaderChannel.Type.ShaderChannel; // Set the shader
@@ -164,7 +165,7 @@ Item
} }
// Recursive helper function to parse channels // Recursive helper function to parse channels
function parseChannel(channel) function parseChannel(channel, parent)
{ {
if (!channel) return; if (!channel) return;
@@ -181,25 +182,49 @@ Item
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
result = component.createObject(mainItem, { x: 100, y: 100 }); result = component.createObject(mainItem, { x: 100, y: 100 });
} }
result.frameBufferChannel = channel.frameBufferChannel !== undefined ? channel.frameBufferChannel : -1
result.type = channel.type result.type = channel.type
result.anchors.fill = mainItem result.anchors.fill = mainItem
result.visible = false result.visible = false
result.iMouse = Qt.binding(function () { return mainItem.iMouse; }) result.iMouse = Qt.binding(() => { return mainItem.iMouse; })
result.iTime = Qt.binding(function() { return mainItem.iTime; }) result.iTime = Qt.binding(() => { return mainItem.iTime; })
result.iResolution = Qt.vector3d(channel.resolution_x || mainItem.width, channel.resolution_y || mainItem.height, 1.0) 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.mouseBias = channel.mouse_scale ? channel.mouse_scale : 1.0
result.iTimeScale = channel.time_scale ? channel.time_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.invert = channel.invert ? channel.invert : false
result.source = source result.source = source
if (channel.channel0) if (channel.channel0)
result.iChannel0 = parseChannel(channel.channel0); result.iChannel0 = parseChannel(channel.channel0, result);
if (channel.channel1) if (channel.channel1)
result.iChannel1 = parseChannel(channel.channel1); result.iChannel1 = parseChannel(channel.channel1, result);
if (channel.channel2) if (channel.channel2)
result.iChannel2 = parseChannel(channel.channel2); result.iChannel2 = parseChannel(channel.channel2, result);
if (channel.channel3) if (channel.channel3)
result.iChannel3 = parseChannel(channel.channel3); result.iChannel3 = parseChannel(channel.channel3, result);
data.channels.push(result) // save for destroying data.channels.push(result) // save for destroying

View File

@@ -68,6 +68,7 @@ Item
property real mouseBias: 1 property real mouseBias: 1
property var iDate 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 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 property bool invert
@@ -250,6 +251,10 @@ Item
Item Item
{ {
property var frameBufferData: undefined
id: channelShaderContent
anchors.fill: parent
// Setup the shader effect sources for each channel // Setup the shader effect sources for each channel
// These are needed to provide the uniform data to the shader channel buffers // These are needed to provide the uniform data to the shader channel buffers
ShaderEffectSource ShaderEffectSource
@@ -259,6 +264,9 @@ Item
live: true live: true
smooth: true smooth: true
sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) 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 ShaderEffectSource
@@ -268,6 +276,9 @@ Item
live: true live: true
smooth: true smooth: true
sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) 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 ShaderEffectSource
@@ -277,6 +288,9 @@ Item
live: true live: true
smooth: true smooth: true
sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) 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 ShaderEffectSource
@@ -286,15 +300,33 @@ Item
live: true live: true
smooth: true smooth: true
sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) 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 // The shader effect that will be used to render the shader
ShaderEffect ShaderEffect
{ {
property var iChannel0: channelSource0 property var iChannel0: channel.frameBufferChannel === 0 ? frameBufferSource : channelSource0
property var iChannel1: channelSource1 property var iChannel1: channel.frameBufferChannel === 1 ? frameBufferSource : channelSource1
property var iChannel2: channelSource2 property var iChannel2: channel.frameBufferChannel === 2 ? frameBufferSource : channelSource2
property var iChannel3: channelSource3 property var iChannel3: channel.frameBufferChannel === 3 ? frameBufferSource : channelSource3
property var iResolution: channel.iResolution property var iResolution: channel.iResolution
property var iTime: data.iTime property var iTime: data.iTime
@@ -310,6 +342,8 @@ Item
fragmentShader: Qt.resolvedUrl(channel.source) fragmentShader: Qt.resolvedUrl(channel.source)
anchors.fill: parent 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 // Connect the audio channel to the cpp backend
// UPDATE: This is not currently supported in QML, so we will need to implement this in C++ later
Component Component
{ {
id: channelAudio id: channelAudio
@@ -414,6 +447,11 @@ Item
{ {
Komplex.AudioModel.startCapture() Komplex.AudioModel.startCapture()
} }
Component.onDestruction:
{
Komplex.AudioModel.stopCapture()
}
} }
} }
} }

View File

@@ -189,6 +189,7 @@ Item
mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) 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.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight)
mainItem.iFrame += 1
} }
} }
} }

View File

@@ -85,6 +85,10 @@ Examples:
default='processed', default='processed',
help='Temporary Files Directory') help='Temporary Files Directory')
parser.add_argument('-q', '--qsb',
default='/usr/lib/qt6/bin/qsb',
help='QSB Compiler Location')
return parser.parse_args() return parser.parse_args()
def process(): def process():
@@ -193,9 +197,8 @@ def compile():
dirname = os.path.basename(source_directory) dirname = os.path.basename(source_directory)
if args.output: qsb = args.qsb
output_directory = args.output + '/' + dirname output_directory = args.output + '/' + dirname
source_directory = temp_directory + '/' + dirname source_directory = temp_directory + '/' + dirname
if args.verbose: if args.verbose:
@@ -227,7 +230,7 @@ def compile():
# Construct and execute the command # Construct and execute the command
cmd = [ 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 '-o', output_file_path, source_file_path
] ]