diff --git a/package/contents/ui/KomplexModel.qml b/package/contents/ui/KomplexModel.qml index 8ac911a..547616f 100644 --- a/package/contents/ui/KomplexModel.qml +++ b/package/contents/ui/KomplexModel.qml @@ -304,20 +304,162 @@ Rectangle console.log('Uknown channel type 3 ' + typeof json.channel3) } - channel.frameBufferChannel = json.frame_buffer_channel !== undefined ? json.frame_buffer_channel : -1 - channel.type = json.type !== undefined ? json.type : typeDefault - channel.visible = false - channel.iMouse = Qt.binding(() => { return mainItem.iMouse; }) - channel.iTime = Qt.binding(() => { return mainItem.iTime; }) - channel.iResolutionScale = json.resolution_scale ? json.resolution_scale : 1.0 + /* + Channel Type + + parse this one first so we can handle defaults, but not ignore overrides + */ + if(typeof json.type === "number") + { + channel.type = json.type + } + else if(typeof json.type === "string") + { + switch(json.type.toLowerCase()) + { + case "image": + channel.type = ShaderChannel.ImageChannel + break; + case "audio": + channel.type = ShaderChannel.AudioChannel + break; + case "video": + channel.type = ShaderChannel.VideoChannel + break; + case "cubemap": + channel.type = ShaderChannel.ImageChannel + break; + case "shader": + channel.type = ShaderChannel.ShaderChannel + break; + case "scene": + channel.type = ShaderChannel.SceneChannel + break; + default: + channel.type = ShaderChannel.ImageChannel + break; + } + } + + channel.frameBufferChannel = typeof json.frame_buffer_channel === "number" ? json.frame_buffer_channel : -1 + channel.iTimeScale = typeof json.time_scale === "number" ? json.time_scale : 1.0 + channel.iResolutionScale = typeof json.resolution_scale === "number" ? json.resolution_scale : 1.0 channel.iResolution = Qt.binding(() => { return json.resolution_x ? Qt.vector3d(json.resolution_x, json.resolution_y, 1.0) : Qt.vector3d(mainItem.iResolution.x,mainItem.iResolution.y,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.width = Qt.binding(() => channel.iResolution.x) channel.height = Qt.binding(() => channel.iResolution.y) - channel.materialTexture = json.materialTexture !== undefined ? getFilePath(json.materialTexture) : "" - channel.materialShader = json.materialShader !== undefined ? getFilePath(json.materialShader) : "" + channel.materialTexture = typeof json.materialTexture === "string" ? getFilePath(json.materialTexture) : "" + channel.materialShader = typeof json.materialShader === "string" ? getFilePath(json.materialShader) : "" + channel.mipmap = typeof json.mipmap === "boolean" ? json.mipmap : true + channel.blending = typeof json.blending === "boolean" ? json.blending : true + channel.samples = typeof json.samples === "number" ? json.samples : 1 + channel.invert = typeof json.invert === "boolean" ? json.invert : false + + if(typeof json.source === "string") + { + channel.source = getFilePath(json.source) + } + else + { + channel.source = "" + } + + /* + Source Format + */ + var format = ShaderEffectSource.RGB8A + + if(typeof json.format === "string") + { + switch(json.format.toLowerCase()) + { + case "rgb8a": + format = ShaderEffectSource.RGB8A + break; + case "rgb16f": + format = ShaderEffectSource.RGB16F + break; + case "rgb32f": + format = ShaderEffectSource.RGB32F + break; + default: + format = ShaderEffectSource.RGB8A + break; + } + + console.log("Set format mode to " + format) + } + + channel.format = format + + /* + Source Wrap Mode + */ + var wrapMode = ShaderEffectSource.Repeat + + if(typeof json.wrap_mode === "string") + { + switch(json.wrap_mode.toLowerCase()) + { + case "clamptoedge": + wrapMode = ShaderEffectSource.ClampToEdge + break; + case "repeathorizontally": + wrapMode = ShaderEffectSource.RepeatHorizontally + break; + case "repeatvertically": + wrapMode = ShaderEffectSource.RepeatVertically + break; + case "repeat": + wrapMode = ShaderEffectSource.Repeat + break; + default: + wrapMode = ShaderEffectSource.Repeat + break; + } + + console.log("Set wrap mode to " + wrapMode) + } + + channel.wrapMode = wrapMode + + /* + Source Mirroring Mode + */ + var mirrorMode = ShaderEffectSource.NoMirroring + + if(typeof json.texture_mirroring === "string") + { + switch(json.texture_mirroring.toLowerCase()) + { + case "nomirroring": + mirrorMode = ShaderEffectSource.NoMirroring + break; + case "mirrorhorizontally": + mirrorMode = ShaderEffectSource.MirrorHorizontally + break; + case "mirrorvertically": + mirrorMode = ShaderEffectSource.MirrorVertically + break; + default: + mirrorMode = ShaderEffectSource.NoMirroring + break; + } + + console.log("Set mirror mode to " + mirrorMode) + } + + channel.textureMirroring = mirrorMode + + /* + Non-configurable bindings + */ + channel.iMouse = Qt.binding(() => { return mainItem.iMouse; }) + channel.iTime = Qt.binding(() => { return mainItem.iTime; }) + channel.iTimeDelta = Qt.binding(() => { return mainItem.iTimeDelta; }) + channel.iFrameRate = Qt.binding(() => { return mainItem.iFrameRate; }) + channel.iFrame = Qt.binding(() => { return mainItem.iFrame; }) + channel.visible = false channel.iChannelTime = Qt.binding(() => { return [ @@ -328,13 +470,6 @@ Rectangle ]; }); - channel.iFrameRate = Qt.binding(() => { return mainItem.iFrameRate; }) - channel.iFrame = mainItem.iFrame - channel.invert = json.invert ? json.invert : false - - var source = getFilePath(json.source) - channel.source = source - if(autodestroy) data.channels.push(channel) } diff --git a/package/contents/ui/ShaderChannel.qml b/package/contents/ui/ShaderChannel.qml index a57d778..80b98cf 100644 --- a/package/contents/ui/ShaderChannel.qml +++ b/package/contents/ui/ShaderChannel.qml @@ -70,37 +70,16 @@ Item 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 blending: false + property bool blending: true property string materialTexture:"" property string materialShader:"" + property bool mipmap: false + property int samples: 1 + property var textureMirroring: ShaderEffectSource.NoMirroring + property var wrapMode: ShaderEffectSource.ClampToEdge + property var format: ShaderEffectSource.RGB8A property var windowModel - - // bind to ShaderEffectSource.live to prevent data being updated causing a refresh between intended frames. I think this may be why - // the shaders are using so many resources. This is likely to cause issues of its own since we have no way of knowing the progress - // of the current capture, but we'll cross that bridge later - property bool active: true - - // this seems to work better than doubling the timer frequency and setting active/inactive states, - // but god damn does it feel hacky. Try to find a better way to actually limit framerate - onIFrameChanged: () => - { - // this method of frame limiting breaks video playback - // even when the video is the source of an item being limited - // in this way - - if(type === ShaderChannel.ShaderChannel) - { - active = true; - active = false; - - return; - } - - if(active === false) - active = true; - } - - property bool invert + property bool invert: false property var iChannelResolution: [Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1)] @@ -282,60 +261,63 @@ Item { if(!videoComponent.loaded) return; - delayedStartTimer.start() + + autoStart() + //delayedStartTimer.start() } - onMediaStatusChanged: - { - switch(mediaStatus) - { - case MediaPlayer.NoMedia: - console.log("No media loaded") - break; - case MediaPlayer.LoadingMedia: - console.log("Video loading") - break; - case MediaPlayer.LoadedMedia: - console.log("Video Loaded") - break; - case MediaPlayer.BufferingMedia: - console.log("Video buffering") - break; - case MediaPlayer.StalledMedia: - console.log("Video stalled") - break; - case MediaPlayer.BufferedMedia: - console.log("Video buffered") - break; - case MediaPlayer.EndOfMedia: - console.log("Video EOF") - break; - case MediaPlayer.InvalidMedia: - console.log("Video invalid") - break; - } - } + // onMediaStatusChanged: + // { + // switch(mediaStatus) + // { + // case MediaPlayer.NoMedia: + // console.log("No media loaded") + // break; + // case MediaPlayer.LoadingMedia: + // console.log("Video loading") + // break; + // case MediaPlayer.LoadedMedia: + // console.log("Video Loaded") + // break; + // case MediaPlayer.BufferingMedia: + // console.log("Video buffering") + // break; + // case MediaPlayer.StalledMedia: + // console.log("Video stalled") + // break; + // case MediaPlayer.BufferedMedia: + // console.log("Video buffered") + // break; + // case MediaPlayer.EndOfMedia: + // console.log("Video EOF") + // break; + // case MediaPlayer.InvalidMedia: + // console.log("Video invalid") + // break; + // } + // } - onPlaybackStateChanged: - { - switch(playbackState) - { - case MediaPlayer.PlayingState: - console.log("Video playback started") - break; - case MediaPlayer.PausedState: - console.log("Video playback paused") - break; - case MediaPlayer.StoppedState: - console.log("Video playback stopped") - break; - } - } + // onPlaybackStateChanged: + // { + // switch(playbackState) + // { + // case MediaPlayer.PlayingState: + // console.log("Video playback started") + // break; + // case MediaPlayer.PausedState: + // console.log("Video playback paused") + // break; + // case MediaPlayer.StoppedState: + // console.log("Video playback stopped") + // break; + // } + // } Component.onCompleted: { videoComponent.loaded = true - delayedStartTimer.start() + + autoStart() } function autoStart() @@ -353,14 +335,6 @@ Item } } - Timer - { - id: delayedStartTimer - interval: 500 - repeat: false - onTriggered: mediaPlayer.autoStart() - } - function start() { mediaPlayer.play() } function stop() { mediaPlayer.stop() } function seek(position) { mediaPlayer.setPosition(position); } @@ -382,134 +356,172 @@ Item ShaderEffectSource { id: channelSource0 - sourceItem: channel.iChannel0 ? channel.iChannel0 : null - live: Qt.binding(() => { return isLive(); }) + live: false smooth: true - sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) - wrapMode: Qt.binding(() => { - if(channel.iChannel0 === undefined || channel.iChannel0.type === ShaderChannel.Audio) - return ShaderEffectSource.ClampToEdge; - else - return ShaderEffectSource.Repeat; - }) - textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) - textureMirroring: ShaderEffectSource.NoMirroring - recursive: true - mipmap: true + recursive: false hideSource: true width: channel.iResolution.x height: channel.iResolution.y visible: false - format: ShaderEffectSource.RGBA8 - samples: 1 - function isLive() + format: channel.iChannel0 ? channel.iChannel0.format : ShaderEffectSource.RGB8A + sourceItem: channel.iChannel0 ? channel.iChannel0 : null + textureMirroring: channel.iChannel0 ? channel.iChannel0.textureMirroring : ShaderEffectSource.NoMirroring + wrapMode: channel.iChannel0 ? channel.iChannel0.wrapMode : ShaderEffectSource.Repeat + mipmap: channel.iChannel0 ? channel.iChannel0.mipmap : true + samples: channel.iChannel0 ? channel.iChannel0.samples : 1 + + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) + + Connections { - if(channel.iChannel0 === undefined) - return false; - - return channel.iChannel0.type != ShaderChannel.VideoChannel && channel.active; + target: channel.iChannel0 + function onTypeChanged() + { + if(channel.iChannel0.type === ShaderChannel.AudioChannel) + { + //channelSource0.wrapMode = ShaderEffectSource.ClampToEdge + channelSource0.live = true + } + else + { + //channelSource0.wrapMode = ShaderEffectSource.Repeat + channelSource0.live = false + } + + // if(!channelSource0.live) + // channelSource0.scheduleUpdate() + } } } ShaderEffectSource { id: channelSource1 - sourceItem: channel.iChannel1 ? channel.iChannel1 : null - live: Qt.binding(() => { return isLive(); }) + live: false smooth: false - sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) - wrapMode: Qt.binding(() => { - if(channel.iChannel1 === undefined || channel.iChannel1.type === ShaderChannel.Audio) - return ShaderEffectSource.ClampToEdge; - else - return ShaderEffectSource.Repeat; - }) - textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) - textureMirroring: ShaderEffectSource.NoMirroring - recursive: true - mipmap: true + recursive: false hideSource: true width: channel.iResolution.x height: channel.iResolution.y visible: false - format: ShaderEffectSource.RGBA8 - samples: 1 - function isLive() + format: channel.iChannel1 ? channel.iChannel1.format : ShaderEffectSource.RGB8A + sourceItem: channel.iChannel1 ? channel.iChannel1 : null + textureMirroring: channel.iChannel1 ? channel.iChannel1.textureMirroring : ShaderEffectSource.NoMirroring + wrapMode: channel.iChannel1 ? channel.iChannel1.wrapMode : ShaderEffectSource.Repeat + mipmap: channel.iChannel1 ? channel.iChannel1.mipmap : true + samples: channel.iChannel1 ? channel.iChannel1.samples : 1 + + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) + + Connections { - return true; + target: channel.iChannel1 + function onTypeChanged() + { + if(channel.iChannel1.type === ShaderChannel.AudioChannel) + { + //channelSource1.wrapMode = ShaderEffectSource.ClampToEdge + channelSource1.live = true + } + else + { + //channelSource1.wrapMode = ShaderEffectSource.Repeat + channelSource1.live = false + } - if(channel.iChannel1 === undefined) - return false; - - return channel.iChannel1.type != ShaderChannel.VideoChannel && channel.active; + // if(!channelSource1.live) + // channelSource1.scheduleUpdate() + } } } ShaderEffectSource { id: channelSource2 - sourceItem: channel.iChannel2 ? channel.iChannel2 : null - live: Qt.binding(() => { return isLive(); }) + live: false smooth: false - sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) - wrapMode: Qt.binding(() => { - if(channel.iChannel2 === undefined || channel.iChannel2.type === ShaderChannel.Audio) - return ShaderEffectSource.ClampToEdge; - else - return ShaderEffectSource.Repeat; - }) - textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) - textureMirroring: ShaderEffectSource.NoMirroring recursive: true - mipmap: true hideSource: true width: channel.iResolution.x height: channel.iResolution.y visible: false - format: ShaderEffectSource.RGBA8 - samples: 1 - function isLive() + format: channel.iChannel2 ? channel.iChannel2.format : ShaderEffectSource.RGB8A + sourceItem: channel.iChannel2 ? channel.iChannel2 : null + textureMirroring: channel.iChannel2 ? channel.iChannel2.textureMirroring : ShaderEffectSource.NoMirroring + wrapMode: channel.iChannel2 ? channel.iChannel2.wrapMode : ShaderEffectSource.Repeat + mipmap: channel.iChannel2 ? channel.iChannel2.mipmap : true + samples: channel.iChannel2 ? channel.iChannel2.samples : 1 + + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) + + Connections { - if(channel.iChannel2 === undefined) - return false; - - return channel.iChannel2.type != ShaderChannel.VideoChannel && channel.active; + target: channel.iChannel2 + function onTypeChanged() + { + if(channel.iChannel2.type === ShaderChannel.AudioChannel) + { + //channelSource2.wrapMode = ShaderEffectSource.ClampToEdge + channelSource2.live = true + } + else + { + //channelSource2.wrapMode = ShaderEffectSource.Repeat + channelSource2.live = false + } + + // if(!channelSource2.live) + // channelSource2.scheduleUpdate() + } } } ShaderEffectSource { id: channelSource3 - sourceItem: channel.iChannel3 ? channel.iChannel3 : null - live: Qt.binding(() => { return isLive(); }) + live: false smooth: false - sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) - wrapMode: Qt.binding(() => { - if(channel.iChannel1 === undefined || channel.iChannel1.type === ShaderChannel.Audio) - return ShaderEffectSource.ClampToEdge; - else - return ShaderEffectSource.Repeat; - }) - textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) - textureMirroring: ShaderEffectSource.NoMirroring recursive: true - mipmap: true hideSource: true width: channel.iResolution.x height: channel.iResolution.y visible: false - format: ShaderEffectSource.RGBA8 - samples: 1 - function isLive() + format: channel.iChannel3 ? channel.iChannel1.format : ShaderEffectSource.RGB8A + sourceItem: channel.iChannel3 ? channel.iChannel3 : null + textureMirroring: channel.iChannel3 ? channel.iChannel3.textureMirroring : ShaderEffectSource.NoMirroring + wrapMode: channel.iChannel3 ? channel.iChannel3.wrapMode : ShaderEffectSource.Repeat + mipmap: channel.iChannel3 ? channel.iChannel3.mipmap : true + samples: channel.iChannel3 ? channel.iChannel3.samples : 1 + + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) + + Connections { - if(channel.iChannel3 === undefined) - return false; - - return channel.iChannel3.type != ShaderChannel.VideoChannel && channel.active; + target: channel.iChannel3 + function onTypeChanged() + { + if(channel.iChannel3.type === ShaderChannel.AudioChannel) + { + //channelSource3.wrapMode = ShaderEffectSource.ClampToEdge + channelSource3.live = true + } + else + { + //channelSource3.wrapMode = ShaderEffectSource.Repeat + channelSource3.live = false + } + + if(!channelSource3.live) + channelSource3.scheduleUpdate() + } } } @@ -517,19 +529,19 @@ Item ShaderEffectSource { id: frameBufferSource - sourceItem: channel.frameBufferChannel === -1 ? null : channelShaderContent - sourceRect: Qt.rect(0,0, channelShaderContent.width, channelShaderContent.height) - wrapMode: ShaderEffectSource.Repeat - live: channel.active + sourceItem: channel.frameBufferChannel === -1 ? null : channelShaderOutput + sourceRect: Qt.rect(0,0, channelShaderOutput.width, channelShaderOutput.height) + wrapMode: ShaderEffectSource.ClampToEdge + live: false mipmap: true recursive: true - textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + textureSize: Qt.size(channelShaderOutput.width, channelShaderOutput.height) visible: false textureMirroring: ShaderEffectSource.NoMirroring width: channel.iResolution.x height: channel.iResolution.y - format: ShaderEffectSource.RGBA8 - samples: 1 + format: ShaderEffectSource.RGB8A + samples: 2 } // The shader effect that will be used to render the shader @@ -560,6 +572,29 @@ Item blending: true } + + Connections + { + target: channel + function onIFrameChanged() + { + // skip first frame. frame 0 is a blank screen + if(channel.frameBufferChannel > -1 )//&& channel.iFrame > 1) + frameBufferSource.scheduleUpdate() + + if(channel.iChannel0 !== undefined && !channelSource0.live) + channelSource0.scheduleUpdate() + + if(channel.iChannel1 !== undefined && !channelSource1.live) + channelSource1.scheduleUpdate() + + if(channel.iChannel2 !== undefined && !channelSource2.live) + channelSource2.scheduleUpdate() + + if(channel.iChannel3 !== undefined && !channelSource3.live) + channelSource3.scheduleUpdate() + } + } } }