From 05f603ed8697ea74182ec999d5fff900cdd59adc Mon Sep 17 00:00:00 2001 From: Andrew Wason Date: Mon, 8 Jan 2024 16:43:17 -0500 Subject: [PATCH] LumaGradientMixer and luma gradient viewer --- src/MediaFX/CMakeLists.txt | 3 +- src/MediaFX/qml/effects/CrossFadeMixer.qml | 2 +- src/MediaFX/qml/effects/LumaGradientMixer.qml | 32 ++++ src/MediaFX/qml/effects/LumaMixer.qml | 6 +- src/MediaFX/qml/effects/luma.frag | 26 +-- src/MediaFX/session.cpp | 2 + tools/qml/LumaMixerViewer.qml | 160 ++++++++++++++++++ tools/viewer/CMakeLists.txt | 2 +- ...aMixerHarness.qml => MediaMixerViewer.qml} | 26 ++- 9 files changed, 223 insertions(+), 36 deletions(-) create mode 100644 src/MediaFX/qml/effects/LumaGradientMixer.qml create mode 100644 tools/qml/LumaMixerViewer.qml rename tools/viewer/qml/{MediaMixerHarness.qml => MediaMixerViewer.qml} (69%) diff --git a/src/MediaFX/CMakeLists.txt b/src/MediaFX/CMakeLists.txt index 8200d4c..39f276c 100644 --- a/src/MediaFX/CMakeLists.txt +++ b/src/MediaFX/CMakeLists.txt @@ -57,10 +57,11 @@ qt_add_qml_module(mediafx qml/effects/MediaMixer.qml qml/effects/CrossFadeMixer.qml qml/effects/LumaMixer.qml + qml/effects/LumaGradientMixer.qml ) qt_add_shaders(mediafx "shaders" PREFIX - "/shaders" + "/" FILES qml/effects/crossfade.frag qml/effects/luma.frag diff --git a/src/MediaFX/qml/effects/CrossFadeMixer.qml b/src/MediaFX/qml/effects/CrossFadeMixer.qml index 395a4e9..d1d7555 100644 --- a/src/MediaFX/qml/effects/CrossFadeMixer.qml +++ b/src/MediaFX/qml/effects/CrossFadeMixer.qml @@ -17,5 +17,5 @@ import MediaFX MediaMixer { //required source //XXX how to make this required for users of us? - fragmentShader: "qrc:/shaders/qml/effects/crossfade.frag.qsb" + fragmentShader: "qrc:/qml/effects/crossfade.frag.qsb" } diff --git a/src/MediaFX/qml/effects/LumaGradientMixer.qml b/src/MediaFX/qml/effects/LumaGradientMixer.qml new file mode 100644 index 0000000..e870a67 --- /dev/null +++ b/src/MediaFX/qml/effects/LumaGradientMixer.qml @@ -0,0 +1,32 @@ +// Copyright (C) 2024 Andrew Wason +// +// This file is part of mediaFX. +// +// mediaFX is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// mediaFX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with mediaFX. +// If not, see . + +import QtQuick +import QtQuick.Shapes +import MediaFX + +LumaMixer { + id: root + property alias fillGradient: path.fillGradient + Shape { + ShapePath { + id: path + scale: Qt.size(root.width, root.height) + PathPolyline { + path: [Qt.point(0, 0), Qt.point(0, 1), Qt.point(1, 1), Qt.point(1, 0), Qt.point(0, 0)] + } + } + } +} diff --git a/src/MediaFX/qml/effects/LumaMixer.qml b/src/MediaFX/qml/effects/LumaMixer.qml index a6f003c..8278fcc 100644 --- a/src/MediaFX/qml/effects/LumaMixer.qml +++ b/src/MediaFX/qml/effects/LumaMixer.qml @@ -20,10 +20,10 @@ MediaMixer { id: root default required property Item luma - property real transitionWidth: root.width - readonly property real premultipliedTransitionWidth: root.time * transitionWidth + 1.0 + property real transitionWidth: 1.0 + readonly property real premultipliedTransitionWidth: root.time * (transitionWidth + 1.0) - fragmentShader: "qrc:/shaders/qml/effects/luma.frag.qsb" + fragmentShader: "qrc:/qml/effects/luma.frag.qsb" state: "default" states: State { diff --git a/src/MediaFX/qml/effects/luma.frag b/src/MediaFX/qml/effects/luma.frag index f104bab..f4d8ca8 100644 --- a/src/MediaFX/qml/effects/luma.frag +++ b/src/MediaFX/qml/effects/luma.frag @@ -18,7 +18,6 @@ layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 qt_Matrix; float qt_Opacity; - float time; float transitionWidth; float premultipliedTransitionWidth; }; @@ -30,27 +29,8 @@ void main() { vec4 dp = texture(dest, qt_TexCoord0); vec4 lp = texture(luma, qt_TexCoord0); - - vec4 m = clamp((lp * vec4(transitionWidth) - vec4(transitionWidth)) + vec4(premultipliedTransitionWidth), vec4(0.0), vec4(1.0)); + // Based on https://github.com/j-b-m/movit/blob/master/luma_mix_effect.frag + // premultipliedTransitionWidth = time * (transitionWidth + 1.0) + float m = clamp((lp.r * transitionWidth - transitionWidth) + premultipliedTransitionWidth, 0.0, 1.0); fragColor = mix(sp, dp, m) * qt_Opacity; - - -/* - float m = clamp((lp.r * transitionWidth - transitionWidth) + (premultipliedTransitionWidth), 0.0, 1.0); - fragColor = mix(sp, dp, m) * qt_Opacity; -*/ - - //fragColor = vec4(lp.rgb, 1.0); - //fragColor = vec4(mix(sp.rgb, dp.rgb, m.rgb), 1.0) * qt_Opacity; - //fragColor = vec4(1.0, 0.0, 0.0, 1.0); - -/*XXX - float w = PREFIX(transition_width); - float luma = INPUT3(tc).x; - if (PREFIX(bool_inverse)) { - luma = 1.0 - luma; - } - float m = clamp((luma * w - w) + PREFIX(progress_mul_w_plus_one), 0.0, 1.0); - return mix(first, second, m); -*/ } \ No newline at end of file diff --git a/src/MediaFX/session.cpp b/src/MediaFX/session.cpp index eab7dfa..f1b34f9 100644 --- a/src/MediaFX/session.cpp +++ b/src/MediaFX/session.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -104,6 +105,7 @@ void Session::quickViewStatusChanged(QQuickView::Status status) if (status == QQuickView::Error) { emit exitApp(1); } else if (status == QQuickView::Ready) { + quickView->rootObject()->setEnabled(false); QCoreApplication::postEvent(this, new QEvent(renderEventType)); } } diff --git a/tools/qml/LumaMixerViewer.qml b/tools/qml/LumaMixerViewer.qml new file mode 100644 index 0000000..5c63a2b --- /dev/null +++ b/tools/qml/LumaMixerViewer.qml @@ -0,0 +1,160 @@ +// Copyright (C) 2024 Andrew Wason +// +// This file is part of mediaFX. +// +// mediaFX is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// mediaFX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with mediaFX. +// If not, see . +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes +import MediaFX +import MediaFX.Viewer + +Rectangle { + SystemPalette { + id: palette + colorGroup: SystemPalette.Active + } + color: palette.window + width: layout.implicitWidth + height: layout.implicitHeight + + ColumnLayout { + id: layout + MediaMixerViewer { + mixer: linearMixer + Layout.fillWidth: true + Layout.fillHeight: true + ColumnLayout { + anchors.fill: parent + LabeledSlider { + id: x1Slider + label: "x1" + to: linearMixer.width + Layout.fillWidth: true + } + LabeledSlider { + id: y1Slider + label: "y1" + to: linearMixer.height + Layout.fillWidth: true + } + LabeledSlider { + id: x2Slider + label: "x2" + to: linearMixer.width + Layout.fillWidth: true + } + LabeledSlider { + id: y2Slider + label: "y2" + to: linearMixer.height + Layout.fillWidth: true + } + LabeledSlider { + id: tw1Slider + label: "transitionWidth" + to: linearMixer.width + Layout.fillWidth: true + } + LumaGradientMixer { + id: linearMixer + transitionWidth: tw1Slider.value + fillGradient: LinearGradient { + x1: x1Slider.value + y1: y1Slider.value + x2: x2Slider.value + y2: y2Slider.value + GradientStop { + position: 0.0 + color: "white" + } + GradientStop { + position: 1.0 + color: "black" + } + } + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + MediaMixerViewer { + mixer: conicalMixer + Layout.fillWidth: true + Layout.fillHeight: true + ColumnLayout { + anchors.fill: parent + LabeledSlider { + id: angleSlider + label: "angle" + to: 360 + Layout.fillWidth: true + } + LabeledSlider { + id: centerXSlider + label: "centerX" + to: conicalMixer.width + Layout.fillWidth: true + } + LabeledSlider { + id: centerYSlider + label: "centerY" + to: conicalMixer.height + Layout.fillWidth: true + } + LabeledSlider { + id: tw2Slider + label: "transitionWidth" + to: conicalMixer.width + Layout.fillWidth: true + } + LumaGradientMixer { + id: conicalMixer + transitionWidth: tw2Slider.value + fillGradient: ConicalGradient { + angle: angleSlider.value + centerX: centerXSlider.value + centerY: centerYSlider.value + GradientStop { + position: 0.0 + color: "white" + } + GradientStop { + position: 1.0 + color: "black" + } + } + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + } + component LabeledSlider: RowLayout { + property alias label: label.text + property alias from: slider.from + property alias to: slider.to + property alias value: slider.value + Label { + id: label + } + Slider { + id: slider + hoverEnabled: true + ToolTip.delay: 1000 + ToolTip.visible: hovered + ToolTip.text: slider.value + Layout.fillWidth: true + } + } +} diff --git a/tools/viewer/CMakeLists.txt b/tools/viewer/CMakeLists.txt index 677aba9..cbac996 100644 --- a/tools/viewer/CMakeLists.txt +++ b/tools/viewer/CMakeLists.txt @@ -22,7 +22,7 @@ target_link_libraries(mediafxviewer PUBLIC mediafx mediafxplugin) qt_add_qml_module(mediafxviewer URI MediaFX.Viewer QML_FILES - qml/MediaMixerHarness.qml + qml/MediaMixerViewer.qml ) install(TARGETS mediafxviewer RUNTIME DESTINATION) diff --git a/tools/viewer/qml/MediaMixerHarness.qml b/tools/viewer/qml/MediaMixerViewer.qml similarity index 69% rename from tools/viewer/qml/MediaMixerHarness.qml rename to tools/viewer/qml/MediaMixerViewer.qml index a590d0c..84fd1a4 100644 --- a/tools/viewer/qml/MediaMixerHarness.qml +++ b/tools/viewer/qml/MediaMixerViewer.qml @@ -1,3 +1,17 @@ +// Copyright (C) 2024 Andrew Wason +// +// This file is part of mediaFX. +// +// mediaFX is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// mediaFX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with mediaFX. +// If not, see . import QtQuick import QtQuick.Shapes import QtQuick.Layouts @@ -7,27 +21,25 @@ import MediaFX Item { id: root - default property alias mixer: mixerContainer.data + default property alias data: mixerContainer.data + required property Item mixer - height: 400 + implicitHeight: 400 + implicitWidth: 400 state: "default" - width: 400 states: State { name: "default" PropertyChanges { - anchors.fill: mixerContainer dest: destItem source: sourceItem - target: root.mixer[0] time: time.value + target: root.mixer } } ColumnLayout { - id: layout - anchors.fill: parent Item {