diff options
Diffstat (limited to 'examples/quick')
41 files changed, 1784 insertions, 166 deletions
diff --git a/examples/quick/demos/samegame/samegame.pro b/examples/quick/demos/samegame/samegame.pro index e041dd61dd..0f01654d46 100644 --- a/examples/quick/demos/samegame/samegame.pro +++ b/examples/quick/demos/samegame/samegame.pro @@ -7,4 +7,4 @@ RESOURCES += samegame.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/demos/samegame INSTALLS += target -!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite +!qtConfig(sql-sqlite): QTPLUGIN += qsqlite diff --git a/examples/quick/positioners/positioners-attachedproperties.qml b/examples/quick/positioners/positioners-attachedproperties.qml index ac2c76db47..e7fa59bb9a 100644 --- a/examples/quick/positioners/positioners-attachedproperties.qml +++ b/examples/quick/positioners/positioners-attachedproperties.qml @@ -66,14 +66,14 @@ Rectangle { anchors.left: parent.left anchors.leftMargin: page.width / 32 anchors.topMargin: page.height / 48 - spacing: elementSpacing + spacing: page.elementSpacing //! [0] Rectangle { id: green color: "#80c342" - width: 100 * ratio - height: 100 * ratio + width: 100 * page.ratio + height: 100 * page.ratio Text { anchors.left: parent.right @@ -95,8 +95,8 @@ Rectangle { Rectangle { id: blue color: "#14aaff" - width: 100 * ratio - height: 100 * ratio + width: 100 * page.ratio + height: 100 * page.ratio Text { anchors.left: parent.right @@ -117,8 +117,8 @@ Rectangle { Rectangle { id: purple color: "#6400aa" - width: 100 * ratio - height: 100 * ratio + width: 100 * page.ratio + height: 100 * page.ratio Text { anchors.left: parent.right @@ -140,8 +140,8 @@ Rectangle { Rectangle { id: hidingRect color: "#006325" - width: 100 * ratio - height: 100 * ratio + width: 100 * page.ratio + height: 100 * page.ratio visible: false Text { diff --git a/examples/quick/positioners/positioners-transitions.qml b/examples/quick/positioners/positioners-transitions.qml index 0d283f7301..17fe41a7e2 100644 --- a/examples/quick/positioners/positioners-transitions.qml +++ b/examples/quick/positioners/positioners-transitions.qml @@ -55,7 +55,7 @@ Item { interval: 2000 running: true repeat: true - onTriggered: effectiveOpacity = (effectiveOpacity == 1.0 ? 0.0 : 1.0); + onTriggered: page.effectiveOpacity = (page.effectiveOpacity == 1.0 ? 0.0 : 1.0); } Column { @@ -65,7 +65,7 @@ Item { top: parent.top topMargin: page.height / 48 } - spacing: elementSpacing + spacing: page.elementSpacing populate: Transition { NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } @@ -77,32 +77,32 @@ Item { NumberAnimation { properties: "y"; easing.type: Easing.OutBounce } } - Rectangle { color: "#80c342"; width: bigSize; height: smallSize } + Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize } Rectangle { id: greenV1 visible: opacity != 0 - width: bigSize; height: smallSize + width: page.bigSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#14aaff"; width: bigSize; height: smallSize } + Rectangle { color: "#14aaff"; width: page.bigSize; height: page.smallSize } Rectangle { id: greenV2 visible: opacity != 0 - width: bigSize; height: smallSize + width: page.bigSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#6400aa"; width: bigSize; height: smallSize } - Rectangle { color: "#80c342"; width: bigSize; height: smallSize } + Rectangle { color: "#6400aa"; width: page.bigSize; height: page.smallSize } + Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize } } Row { @@ -112,7 +112,7 @@ Item { bottom: page.bottom bottomMargin: page.height / 48 } - spacing: elementSpacing + spacing: page.elementSpacing populate: Transition { NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } @@ -124,40 +124,40 @@ Item { NumberAnimation { properties: "x"; easing.type: Easing.OutBounce } } - Rectangle { color: "#80c342"; width: smallSize; height: bigSize } + Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize } Rectangle { id: blueH1 visible: opacity != 0 - width: smallSize; height: bigSize + width: page.smallSize; height: page.bigSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#14aaff"; width: smallSize; height: bigSize } + Rectangle { color: "#14aaff"; width: page.smallSize; height: page.bigSize } Rectangle { id: greenH2 visible: opacity != 0 - width: smallSize; height: bigSize + width: page.smallSize; height: page.bigSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#6400aa"; width: smallSize; height: bigSize } - Rectangle { color: "#80c342"; width: smallSize; height: bigSize } + Rectangle { color: "#6400aa"; width: page.smallSize; height: page.bigSize } + Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize } } Grid { anchors.top: parent.top anchors.topMargin: page.height / 48 - anchors.left: flow.left + anchors.left: flowItem.left columns: 3 - spacing: elementSpacing + spacing: page.elementSpacing populate: Transition { NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } @@ -169,55 +169,55 @@ Item { NumberAnimation { properties: "x,y"; easing.type: Easing.OutBounce } } - Rectangle { color: "#80c342"; width: smallSize; height: smallSize } + Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize } Rectangle { id: greenG1 visible: opacity != 0 - width: smallSize; height: smallSize + width: page.smallSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#14aaff"; width: smallSize; height: smallSize } + Rectangle { color: "#14aaff"; width: page.smallSize; height: page.smallSize } Rectangle { id: greenG2 visible: opacity != 0 - width: smallSize; height: smallSize + width: page.smallSize; height:page. smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } + Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize } Rectangle { id: greenG3 visible: opacity != 0 - width: smallSize; height: smallSize + width: page.smallSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#80c342"; width: smallSize; height: smallSize } - Rectangle { color: "#14aaff"; width: smallSize; height: smallSize } - Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } + Rectangle { color: "#80c342"; width:page. smallSize; height: page.smallSize } + Rectangle { color: "#14aaff"; width: smallSize; height: page.smallSize } + Rectangle { color: "#6400aa"; width: page.page.smallSize; height: page.smallSize } } Flow { - id: flow + id: flowItem anchors.right: page.right anchors.rightMargin: page.width / 32 - y: 2 * bigSize - width: 1.8 * bigSize - spacing: elementSpacing + y: 2 * page.bigSize + width: 1.8 * page.bigSize + spacing: page.elementSpacing //! [move] move: Transition { @@ -237,42 +237,42 @@ Item { } //! [populate] - Rectangle { color: "#80c342"; width: smallSize; height: smallSize } + Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize } Rectangle { id: greenF1 visible: opacity != 0 - width: 0.6 * bigSize; height: smallSize + width: 0.6 * page.bigSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#14aaff"; width: 0.3 * bigSize; height: smallSize } + Rectangle { color: "#14aaff"; width: 0.3 * page.bigSize; height: page.smallSize } Rectangle { id: greenF2 visible: opacity != 0 - width: 0.6 * bigSize; height: smallSize + width: 0.6 * page.bigSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } + Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize } Rectangle { id: greenF3 visible: opacity != 0 - width: 0.4 * bigSize; height: smallSize + width: 0.4 * page.bigSize; height: page.smallSize color: "#006325" border.color: "transparent" Behavior on opacity { NumberAnimation {} } - opacity: effectiveOpacity + opacity: page.effectiveOpacity } - Rectangle { color: "#80c342"; width: 0.8 * bigSize; height: smallSize } + Rectangle { color: "#80c342"; width: 0.8 * page.bigSize; height: page.smallSize } } } diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro index 63730e53da..445dfb0fab 100644 --- a/examples/quick/quick.pro +++ b/examples/quick/quick.pro @@ -16,7 +16,6 @@ SUBDIRS = quick-accessibility \ scenegraph \ shadereffects \ text \ - textureprovider \ threading \ touchinteraction \ tutorials \ @@ -25,8 +24,14 @@ SUBDIRS = quick-accessibility \ imageresponseprovider \ window \ particles \ - demos \ - rendercontrol + demos + +#OpenGL Support Required +qtConfig(opengl(es1|es2)?) { + SUBDIRS += \ + textureprovider \ + rendercontrol +} # Widget dependent examples qtHaveModule(widgets) { diff --git a/examples/quick/quickwidgets/quickwidget/customgl.qml b/examples/quick/quickwidgets/quickwidget/customgl.qml new file mode 100644 index 0000000000..81e33e1ac9 --- /dev/null +++ b/examples/quick/quickwidgets/quickwidget/customgl.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QuickWidgetExample 1.0 + +Rectangle { + color: "lightGray" + + FbItem { + anchors.fill: parent + anchors.margins: 10 + } + + Text { + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 15 + text: "QQuickFramebufferObject with animated clear color" + color: "white" + } +} diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.cpp b/examples/quick/quickwidgets/quickwidget/fbitem.cpp new file mode 100644 index 0000000000..fc2a4ea7ad --- /dev/null +++ b/examples/quick/quickwidgets/quickwidget/fbitem.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "fbitem.h" +#include <QtGui/QOpenGLFramebufferObject> +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> +#include <QtCore/QDebug> + +#ifndef QT_NO_OPENGL +class FbRenderer : public QQuickFramebufferObject::Renderer +{ +public: + FbRenderer() : c(0), dir(1) { } + + // The lifetime of the FBO and this class depends on how QQuickWidget + // manages the scenegraph and context when it comes to showing and hiding + // the widget. The actual behavior is proven by the debug prints. + ~FbRenderer() { + qDebug("FbRenderer destroyed"); + } + + void render() { + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glClearColor(c, 0, 0, 1); + f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + c += 0.01f * dir; + if (c >= 1.0f || c <= 0.0f) + dir *= -1; + update(); + } + + QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { + qDebug() << "Creating FBO" << size; + QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + return new QOpenGLFramebufferObject(size, format); + } + +private: + float c; + int dir; +}; +#endif + +QQuickFramebufferObject::Renderer *FbItem::createRenderer() const +{ +#ifndef QT_NO_OPENGL + return new FbRenderer; +#else + return nullptr; +#endif +} diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.h b/examples/quick/quickwidgets/quickwidget/fbitem.h new file mode 100644 index 0000000000..59280eb3b8 --- /dev/null +++ b/examples/quick/quickwidgets/quickwidget/fbitem.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FBITEM_H +#define FBITEM_H + +#include <QtQuick/QQuickFramebufferObject> + +class FbItem : public QQuickFramebufferObject +{ + Q_OBJECT +public: + Renderer *createRenderer() const; +}; + +#endif diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp index 3f3638a43f..6bb6722e02 100644 --- a/examples/quick/quickwidgets/quickwidget/main.cpp +++ b/examples/quick/quickwidgets/quickwidget/main.cpp @@ -42,6 +42,7 @@ #include <QQuickItem> #include <QQmlError> #include <QtWidgets> +#include "fbitem.h" class MainWindow : public QMainWindow { Q_OBJECT @@ -54,6 +55,7 @@ private slots: void grabFramebuffer(); void renderToPixmap(); void grabToImage(); + void createQuickWidgetsInTabs(QMdiArea *mdiArea); private: QQuickWidget *m_quickWidget; @@ -76,7 +78,7 @@ MainWindow::MainWindow() QLCDNumber *lcd = new QLCDNumber; lcd->display(1337); lcd->setMinimumSize(250,100); - centralWidget ->addSubWindow(lcd); + centralWidget->addSubWindow(lcd); QUrl source("qrc:quickwidget/rotatingsquare.qml"); @@ -88,7 +90,7 @@ MainWindow::MainWindow() m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView ); m_quickWidget->setSource(source); - centralWidget ->addSubWindow(m_quickWidget); + centralWidget->addSubWindow(m_quickWidget); setCentralWidget(centralWidget); @@ -97,6 +99,34 @@ MainWindow::MainWindow() fileMenu->addAction(tr("Render to pixmap"), this, &MainWindow::renderToPixmap); fileMenu->addAction(tr("Grab via grabToImage"), this, &MainWindow::grabToImage); fileMenu->addAction(tr("Quit"), qApp, &QCoreApplication::quit); + + QMenu *windowMenu = menuBar()->addMenu(tr("&Window")); + windowMenu->addAction(tr("Add tab widget"), this, + [this, centralWidget] { createQuickWidgetsInTabs(centralWidget); }); +} + +void MainWindow::createQuickWidgetsInTabs(QMdiArea *mdiArea) +{ + QTabWidget *tabWidget = new QTabWidget; + + const QSize size(400, 400); + + QQuickWidget *w = new QQuickWidget; + w->resize(size); + w->setResizeMode(QQuickWidget::SizeRootObjectToView); + w->setSource(QUrl("qrc:quickwidget/rotatingsquaretab.qml")); + + tabWidget->addTab(w, tr("Plain Quick content")); + + w = new QQuickWidget; + w->resize(size); + w->setResizeMode(QQuickWidget::SizeRootObjectToView); + w->setSource(QUrl("qrc:quickwidget/customgl.qml")); + + tabWidget->addTab(w, tr("Custom OpenGL drawing")); + + mdiArea->addSubWindow(tabWidget); + tabWidget->show(); } void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status) @@ -153,6 +183,8 @@ int main(int argc, char **argv) { QApplication app(argc, argv); + qmlRegisterType<FbItem>("QuickWidgetExample", 1, 0, "FbItem"); + MainWindow mainWindow; mainWindow.show(); diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.pro b/examples/quick/quickwidgets/quickwidget/quickwidget.pro index 04fb5541a7..5be006f7fa 100644 --- a/examples/quick/quickwidgets/quickwidget/quickwidget.pro +++ b/examples/quick/quickwidgets/quickwidget/quickwidget.pro @@ -3,7 +3,8 @@ QT += core gui quick widgets quickwidgets TARGET = quickwidget TEMPLATE = app -SOURCES += main.cpp +SOURCES += main.cpp fbitem.cpp +HEADERS += fbitem.h RESOURCES += quickwidget.qrc diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc index c073b7b80d..85a49b75ca 100644 --- a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc +++ b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc @@ -1,5 +1,7 @@ <RCC> <qresource prefix="/quickwidget"> <file>rotatingsquare.qml</file> + <file>rotatingsquaretab.qml</file> + <file>customgl.qml</file> </qresource> </RCC> diff --git a/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml new file mode 100644 index 0000000000..51c17b9ffb --- /dev/null +++ b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + gradient: Gradient { + GradientStop { position: 0; color: "steelblue" } + GradientStop { position: 1; color: "black" } + } + + Rectangle { + property int d: 100 + id: square + width: d + height: d + anchors.centerIn: parent + color: "green" + NumberAnimation on rotation { from: 360; to: 0; duration: 4000; loops: Animation.Infinite; } + } + + Text { + anchors.centerIn: parent + text: "Qt Quick running in a tab widget" + color: "purple" + font.bold: true + font.pointSize: 14 + } +} diff --git a/examples/quick/scenegraph/customgeometry/beziercurve.cpp b/examples/quick/scenegraph/customgeometry/beziercurve.cpp index 14e78f8d21..ca3c6f524b 100644 --- a/examples/quick/scenegraph/customgeometry/beziercurve.cpp +++ b/examples/quick/scenegraph/customgeometry/beziercurve.cpp @@ -135,7 +135,7 @@ QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) //! [4] //! [5] geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount); geometry->setLineWidth(2); - geometry->setDrawingMode(GL_LINE_STRIP); + geometry->setDrawingMode(QSGGeometry::DrawLineStrip); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); //! [5] //! [6] diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.cpp b/examples/quick/scenegraph/rendernode/customrenderitem.cpp new file mode 100644 index 0000000000..a92a400922 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/customrenderitem.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "customrenderitem.h" +#include <QQuickWindow> +#include <QSGRendererInterface> + +#include "openglrenderer.h" +#include "d3d12renderer.h" +#include "softwarerenderer.h" + +CustomRenderItem::CustomRenderItem(QQuickItem *parent) + : QQuickItem(parent) +{ + // Our item shows something so set the flag. + setFlag(ItemHasContents); +} + +QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) +{ + QSGRenderNode *n = static_cast<QSGRenderNode *>(node); + if (!n) { + QSGRendererInterface *ri = window()->rendererInterface(); + if (!ri) + return nullptr; + switch (ri->graphicsApi()) { + case QSGRendererInterface::OpenGL: +#ifndef QT_NO_OPENGL + n = new OpenGLRenderNode(this); + break; +#endif + case QSGRendererInterface::Direct3D12: +#if QT_CONFIG(d3d12) + n = new D3D12RenderNode(this); + break; +#endif + case QSGRendererInterface::Software: + n = new SoftwareRenderNode(this); + break; + + default: + return nullptr; + } + } + + return n; +} diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.h b/examples/quick/scenegraph/rendernode/customrenderitem.h new file mode 100644 index 0000000000..43b0b00ed5 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/customrenderitem.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMRENDERITEM_H +#define CUSTOMRENDERITEM_H + +#include <QQuickItem> + +class CustomRenderItem : public QQuickItem +{ + Q_OBJECT + +public: + CustomRenderItem(QQuickItem *parent = nullptr); + QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) override; +}; + +#endif diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp new file mode 100644 index 0000000000..3b377f1cb1 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp @@ -0,0 +1,283 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "d3d12renderer.h" +#include <QQuickItem> +#include <QQuickWindow> +#include <QSGRendererInterface> + +#if QT_CONFIG(d3d12) + +#include "vs_shader.hlslh" +#include "ps_shader.hlslh" + +D3D12RenderNode::D3D12RenderNode(QQuickItem *item) + : m_item(item) +{ +} + +D3D12RenderNode::~D3D12RenderNode() +{ + releaseResources(); +} + +void D3D12RenderNode::releaseResources() +{ + if (vbPtr) { + vertexBuffer->Unmap(0, nullptr); + vbPtr = nullptr; + } + if (cbPtr) { + constantBuffer->Unmap(0, nullptr); + cbPtr = nullptr; + } + constantBuffer = nullptr; + vertexBuffer = nullptr; + rootSignature = nullptr; + pipelineState = nullptr; + m_device = nullptr; +} + +void D3D12RenderNode::init() +{ + QSGRendererInterface *rif = m_item->window()->rendererInterface(); + m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::Device)); + Q_ASSERT(m_device); + + D3D12_ROOT_PARAMETER rootParameter; + rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootParameter.Descriptor.ShaderRegister = 0; // b0 + rootParameter.Descriptor.RegisterSpace = 0; + + D3D12_ROOT_SIGNATURE_DESC desc; + desc.NumParameters = 1; + desc.pParameters = &rootParameter; + desc.NumStaticSamplers = 0; + desc.pStaticSamplers = nullptr; + desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + ComPtr<ID3DBlob> signature; + ComPtr<ID3DBlob> error; + if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { + qWarning("Failed to serialize root signature"); + return; + } + if (FAILED(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), + IID_PPV_ARGS(&rootSignature)))) { + qWarning("Failed to create root signature"); + return; + } + + D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + }; + + D3D12_SHADER_BYTECODE vshader; + vshader.pShaderBytecode = g_VS_Simple; + vshader.BytecodeLength = sizeof(g_VS_Simple); + D3D12_SHADER_BYTECODE pshader; + pshader.pShaderBytecode = g_PS_Simple; + pshader.BytecodeLength = sizeof(g_PS_Simple); + + D3D12_RASTERIZER_DESC rastDesc = {}; + rastDesc.FillMode = D3D12_FILL_MODE_SOLID; + rastDesc.CullMode = D3D12_CULL_MODE_BACK; + rastDesc.FrontCounterClockwise = TRUE; // Vertices are given CCW + + // Enable color write and blending (premultiplied alpha). The latter is + // needed because the example changes the item's opacity and we pass + // inheritedOpacity() into the pixel shader. If that wasn't the case, + // blending could have stayed disabled. + const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = { + TRUE, FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL + }; + D3D12_BLEND_DESC blendDesc = {}; + blendDesc.RenderTarget[0] = premulBlendDesc; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; + psoDesc.pRootSignature = rootSignature.Get(); + psoDesc.VS = vshader; + psoDesc.PS = pshader; + psoDesc.RasterizerState = rastDesc; + psoDesc.BlendState = blendDesc; + // No depth. The correct stacking of the item is ensured by the projection matrix. + // Do not bother with stencil since we do not apply clipping in the + // example. If clipping is desired, render() needs to set a different PSO + // with stencil enabled whenever the RenderState indicates so. + psoDesc.SampleMask = UINT_MAX; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; // not in use due to !DepthEnable, but this would be the correct format otherwise + // We are rendering on the default render target so if the QuickWindow/View + // has requested samples > 0 then we have to follow suit. + const uint samples = qMax(1, m_item->window()->format().samples()); + psoDesc.SampleDesc.Count = samples; + if (samples > 1) { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {}; + msaaInfo.Format = psoDesc.RTVFormats[0]; + msaaInfo.SampleCount = samples; + if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) { + if (msaaInfo.NumQualityLevels > 0) + psoDesc.SampleDesc.Quality = msaaInfo.NumQualityLevels - 1; + } + } + + if (FAILED(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) { + qWarning("Failed to create graphics pipeline state"); + return; + } + + const UINT vertexBufferSize = (2 + 3) * 3 * sizeof(float); + + D3D12_HEAP_PROPERTIES heapProp = {}; + heapProp.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC bufDesc; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + bufDesc.Alignment = 0; + bufDesc.Width = vertexBufferSize; + bufDesc.Height = 1; + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_UNKNOWN; + bufDesc.SampleDesc.Count = 1; + bufDesc.SampleDesc.Quality = 0; + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + bufDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + if (FAILED(m_device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, + IID_PPV_ARGS(&vertexBuffer)))) { + qWarning("Failed to create committed resource (vertex buffer)"); + return; + } + + vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); + vertexBufferView.StrideInBytes = vertexBufferSize / 3; + vertexBufferView.SizeInBytes = vertexBufferSize; + + bufDesc.Width = 256; + if (FAILED(m_device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, + IID_PPV_ARGS(&constantBuffer)))) { + qWarning("Failed to create committed resource (constant buffer)"); + return; + } + + const D3D12_RANGE readRange = { 0, 0 }; + if (FAILED(vertexBuffer->Map(0, &readRange, reinterpret_cast<void **>(&vbPtr)))) { + qWarning("Map failed"); + return; + } + + if (FAILED(constantBuffer->Map(0, &readRange, reinterpret_cast<void **>(&cbPtr)))) { + qWarning("Map failed (constant buffer)"); + return; + } + + float *vp = reinterpret_cast<float *>(vbPtr); + vp += 2; + *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f; + vp += 2; + *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f; + vp += 2; + *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f; +} + +void D3D12RenderNode::render(const RenderState *state) +{ + if (!m_device) + init(); + + QSGRendererInterface *rif = m_item->window()->rendererInterface(); + ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(rif->getResource(m_item->window(), QSGRendererInterface::CommandList)); + Q_ASSERT(commandList); + + const int msize = 16 * sizeof(float); + memcpy(cbPtr, matrix()->constData(), msize); + memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize); + const float opacity = inheritedOpacity(); + memcpy(cbPtr + 2 * msize, &opacity, sizeof(float)); + + const QPointF p0(m_item->width() - 1, m_item->height() - 1); + const QPointF p1(0, 0); + const QPointF p2(0, m_item->height() - 1); + + float *vp = reinterpret_cast<float *>(vbPtr); + *vp++ = p0.x(); + *vp++ = p0.y(); + vp += 3; + *vp++ = p1.x(); + *vp++ = p1.y(); + vp += 3; + *vp++ = p2.x(); + *vp++ = p2.y(); + + commandList->SetPipelineState(pipelineState.Get()); + commandList->SetGraphicsRootSignature(rootSignature.Get()); + commandList->SetGraphicsRootConstantBufferView(0, constantBuffer->GetGPUVirtualAddress()); + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 1, &vertexBufferView); + + commandList->DrawInstanced(3, 1, 0, 0); +} + +// No need to reimplement changedStates() because no relevant commands are +// added to the command list in render(). + +QSGRenderNode::RenderingFlags D3D12RenderNode::flags() const +{ + return BoundedRectRendering | DepthAwareRendering; +} + +QRectF D3D12RenderNode::rect() const +{ + return QRect(0, 0, m_item->width(), m_item->height()); +} + +#endif // d3d12 diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.h b/examples/quick/scenegraph/rendernode/d3d12renderer.h new file mode 100644 index 0000000000..1d2726819f --- /dev/null +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef D3D12RENDERER_H +#define D3D12RENDERER_H + +#include <qsgrendernode.h> + +#if QT_CONFIG(d3d12) + +class QQuickItem; + +#include <d3d12.h> +#include <wrl/client.h> + +using namespace Microsoft::WRL; + +class D3D12RenderNode : public QSGRenderNode +{ +public: + D3D12RenderNode(QQuickItem *item); + ~D3D12RenderNode(); + + void render(const RenderState *state) override; + void releaseResources() override; + RenderingFlags flags() const override; + QRectF rect() const override; + +private: + void init(); + + QQuickItem *m_item; + ID3D12Device *m_device = nullptr; + ComPtr<ID3D12PipelineState> pipelineState; + ComPtr<ID3D12RootSignature> rootSignature; + ComPtr<ID3D12Resource> vertexBuffer; + ComPtr<ID3D12Resource> constantBuffer; + D3D12_VERTEX_BUFFER_VIEW vertexBufferView; + quint8 *vbPtr = nullptr; + quint8 *cbPtr = nullptr; +}; + +#endif // d3d12 + +#endif diff --git a/examples/quick/scenegraph/rendernode/main.cpp b/examples/quick/scenegraph/rendernode/main.cpp new file mode 100644 index 0000000000..3e1714313e --- /dev/null +++ b/examples/quick/scenegraph/rendernode/main.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQuickView> +#include "customrenderitem.h" + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<CustomRenderItem>("SceneGraphRendering", 2, 0, "CustomRenderItem"); + + QQuickView view; + + if (QCoreApplication::arguments().contains(QStringLiteral("--multisample"))) { + QSurfaceFormat fmt; + fmt.setSamples(4); + view.setFormat(fmt); + } + + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///scenegraph/rendernode/main.qml")); + view.resize(1024, 768); + view.show(); + + return app.exec(); +} diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml new file mode 100644 index 0000000000..7c8d82181f --- /dev/null +++ b/examples/quick/scenegraph/rendernode/main.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.8 +import SceneGraphRendering 2.0 + +Item { + Rectangle { + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0; color: "steelblue" } + GradientStop { position: 1; color: "black" } + } + + CustomRenderItem { + id: renderer + anchors.fill: parent + anchors.margins: 10 + + transform: [ + Rotation { id: rotation; axis.x: 0; axis.z: 0; axis.y: 1; angle: 0; origin.x: renderer.width / 2; origin.y: renderer.height / 2; }, + Translate { id: txOut; x: -renderer.width / 2; y: -renderer.height / 2 }, + Scale { id: scale; }, + Translate { id: txIn; x: renderer.width / 2; y: renderer.height / 2 } + ] + } + + SequentialAnimation { + PauseAnimation { duration: 3000 } + ParallelAnimation { + NumberAnimation { target: scale; property: "xScale"; to: 0.6; duration: 1000; easing.type: Easing.InOutBack } + NumberAnimation { target: scale; property: "yScale"; to: 0.6; duration: 1000; easing.type: Easing.InOutBack } + } + NumberAnimation { target: rotation; property: "angle"; to: 80; duration: 1000; easing.type: Easing.InOutCubic } + NumberAnimation { target: rotation; property: "angle"; to: -80; duration: 1000; easing.type: Easing.InOutCubic } + NumberAnimation { target: rotation; property: "angle"; to: 0; duration: 1000; easing.type: Easing.InOutCubic } + NumberAnimation { target: renderer; property: "opacity"; to: 0.1; duration: 1000; easing.type: Easing.InOutCubic } + PauseAnimation { duration: 1000 } + NumberAnimation { target: renderer; property: "opacity"; to: 1.0; duration: 1000; easing.type: Easing.InOutCubic } + ParallelAnimation { + NumberAnimation { target: scale; property: "xScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack } + NumberAnimation { target: scale; property: "yScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack } + } + running: true + loops: Animation.Infinite + } + + Text { + id: label + anchors.bottom: renderer.bottom + anchors.left: renderer.left + anchors.right: renderer.right + anchors.margins: 20 + wrapMode: Text.WordWrap + property int api: GraphicsInfo.api + text: "Custom rendering via the graphics API " + + (api === GraphicsInfo.OpenGL ? "OpenGL" + : api === GraphicsInfo.Direct3D12 ? "Direct3D 12" + : api === GraphicsInfo.Software ? "Software" : "") + color: "yellow" + } + } +} diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp new file mode 100644 index 0000000000..3de864b7b9 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "openglrenderer.h" +#include <QQuickItem> + +#ifndef QT_NO_OPENGL + +#include <QOpenGLShaderProgram> +#include <QOpenGLBuffer> +#include <QOpenGLFunctions> + +OpenGLRenderNode::OpenGLRenderNode(QQuickItem *item) + : m_item(item) +{ +} + +OpenGLRenderNode::~OpenGLRenderNode() +{ + releaseResources(); +} + +void OpenGLRenderNode::releaseResources() +{ + delete m_program; + m_program = nullptr; + delete m_vbo; + m_vbo = nullptr; +} + +void OpenGLRenderNode::init() +{ + m_program = new QOpenGLShaderProgram; + + static const char *vertexShaderSource = + "attribute highp vec4 posAttr;\n" + "attribute lowp vec4 colAttr;\n" + "varying lowp vec4 col;\n" + "uniform highp mat4 matrix;\n" + "void main() {\n" + " col = colAttr;\n" + " gl_Position = matrix * posAttr;\n" + "}\n"; + + static const char *fragmentShaderSource = + "varying lowp vec4 col;\n" + "uniform lowp float opacity;\n" + "void main() {\n" + " gl_FragColor = col * opacity;\n" + "}\n"; + + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource); + m_program->bindAttributeLocation("posAttr", 0); + m_program->bindAttributeLocation("colAttr", 1); + m_program->link(); + + m_matrixUniform = m_program->uniformLocation("matrix"); + m_opacityUniform = m_program->uniformLocation("opacity"); + + const int VERTEX_SIZE = 6 * sizeof(GLfloat); + + static GLfloat colors[] = { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f + }; + + m_vbo = new QOpenGLBuffer; + m_vbo->create(); + m_vbo->bind(); + m_vbo->allocate(VERTEX_SIZE + sizeof(colors)); + m_vbo->write(VERTEX_SIZE, colors, sizeof(colors)); + m_vbo->release(); +} + +void OpenGLRenderNode::render(const RenderState *state) +{ + if (!m_program) + init(); + + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + + m_program->bind(); + m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix()); + m_program->setUniformValue(m_opacityUniform, float(inheritedOpacity())); + + m_vbo->bind(); + + QPointF p0(m_item->width() - 1, m_item->height() - 1); + QPointF p1(0, 0); + QPointF p2(0, m_item->height() - 1); + + GLfloat vertices[6] = { GLfloat(p0.x()), GLfloat(p0.y()), + GLfloat(p1.x()), GLfloat(p1.y()), + GLfloat(p2.x()), GLfloat(p2.y()) }; + m_vbo->write(0, vertices, sizeof(vertices)); + + m_program->setAttributeBuffer(0, GL_FLOAT, 0, 2); + m_program->setAttributeBuffer(1, GL_FLOAT, sizeof(vertices), 3); + m_program->enableAttributeArray(0); + m_program->enableAttributeArray(1); + + // Note that clipping (scissor or stencil) is ignored in this example. + + f->glEnable(GL_BLEND); + f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + f->glDrawArrays(GL_TRIANGLES, 0, 3); +} + +QSGRenderNode::StateFlags OpenGLRenderNode::changedStates() const +{ + return BlendState; +} + +QSGRenderNode::RenderingFlags OpenGLRenderNode::flags() const +{ + return BoundedRectRendering | DepthAwareRendering; +} + +QRectF OpenGLRenderNode::rect() const +{ + return QRect(0, 0, m_item->width(), m_item->height()); +} + +#endif // QT_NO_OPENGL diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h new file mode 100644 index 0000000000..92cc2bc72b --- /dev/null +++ b/examples/quick/scenegraph/rendernode/openglrenderer.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef OPENGLRENDERER_H +#define OPENGLRENDERER_H + +#include <qsgrendernode.h> + +#ifndef QT_NO_OPENGL + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QOpenGLShaderProgram; +class QOpenGLBuffer; + +class OpenGLRenderNode : public QSGRenderNode +{ +public: + OpenGLRenderNode(QQuickItem *item); + ~OpenGLRenderNode(); + + void render(const RenderState *state) override; + void releaseResources() override; + StateFlags changedStates() const override; + RenderingFlags flags() const override; + QRectF rect() const override; + +private: + void init(); + + QQuickItem *m_item; + QOpenGLShaderProgram *m_program = nullptr; + int m_matrixUniform; + int m_opacityUniform; + QOpenGLBuffer *m_vbo = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_OPENGL + +#endif diff --git a/examples/quick/scenegraph/rendernode/rendernode.pro b/examples/quick/scenegraph/rendernode/rendernode.pro new file mode 100644 index 0000000000..968902a5be --- /dev/null +++ b/examples/quick/scenegraph/rendernode/rendernode.pro @@ -0,0 +1,38 @@ +QT += qml quick + +HEADERS += customrenderitem.h \ + openglrenderer.h \ + softwarerenderer.h + +SOURCES += customrenderitem.cpp \ + openglrenderer.cpp \ + softwarerenderer.cpp \ + main.cpp + +RESOURCES += rendernode.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/scenegraph/rendernode +INSTALLS += target + +OTHER_FILES += \ + main.qml \ + shader.hlsl + +qtConfig(d3d12) { + HEADERS += d3d12renderer.h + SOURCES += d3d12renderer.cpp + LIBS += -ld3d12 + + VSPS = shader.hlsl + vshader.input = VSPS + vshader.header = vs_shader.hlslh + vshader.entry = VS_Simple + vshader.type = vs_5_0 + pshader.input = VSPS + pshader.header = ps_shader.hlslh + pshader.entry = PS_Simple + pshader.type = ps_5_0 + + HLSL_SHADERS = vshader pshader + load(hlsl_bytecode_header) +} diff --git a/examples/quick/scenegraph/rendernode/rendernode.qrc b/examples/quick/scenegraph/rendernode/rendernode.qrc new file mode 100644 index 0000000000..3674baccd8 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/rendernode.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/scenegraph/rendernode"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/examples/quick/scenegraph/rendernode/shader.hlsl b/examples/quick/scenegraph/rendernode/shader.hlsl new file mode 100644 index 0000000000..f300fe7aa5 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/shader.hlsl @@ -0,0 +1,28 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 modelview; + float4x4 projection; + float opacity; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float3 color : COLOR; +}; + +PSInput VS_Simple(float4 position : POSITION, float3 color : COLOR) +{ + PSInput result; + + float4x4 mvp = mul(projection, modelview); + result.position = mul(mvp, position); + result.color = color; + + return result; +} + +float4 PS_Simple(PSInput input) : SV_TARGET +{ + return float4(input.color, 1.0) * opacity; +} diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.cpp b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp new file mode 100644 index 0000000000..06e406874a --- /dev/null +++ b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "softwarerenderer.h" +#include <QQuickItem> +#include <QQuickWindow> +#include <QSGRendererInterface> +#include <QPainter> + +SoftwareRenderNode::SoftwareRenderNode(QQuickItem *item) + : m_item(item) +{ +} + +SoftwareRenderNode::~SoftwareRenderNode() +{ + releaseResources(); +} + +void SoftwareRenderNode::releaseResources() +{ +} + +void SoftwareRenderNode::render(const RenderState *renderState) +{ + QSGRendererInterface *rif = m_item->window()->rendererInterface(); + QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::Painter)); + Q_ASSERT(p); + + p->setTransform(matrix()->toTransform()); + p->setOpacity(inheritedOpacity()); + const QRegion *clipRegion = renderState->clipRegion(); + if (clipRegion && !clipRegion->isEmpty()) + p->setClipRegion(*clipRegion, Qt::IntersectClip); + + const QPointF p0(m_item->width() - 1, m_item->height() - 1); + const QPointF p1(0, 0); + const QPointF p2(0, m_item->height() - 1); + QPainterPath path(p0); + path.lineTo(p1); + path.lineTo(p2); + path.closeSubpath(); + + QLinearGradient gradient(QPointF(0, 0), QPointF(m_item->width(), m_item->height())); + gradient.setColorAt(0, Qt::green); + gradient.setColorAt(1, Qt::red); + + p->fillPath(path, gradient); +} + +QSGRenderNode::StateFlags SoftwareRenderNode::changedStates() const +{ + return 0; +} + +QSGRenderNode::RenderingFlags SoftwareRenderNode::flags() const +{ + return BoundedRectRendering; +} + +QRectF SoftwareRenderNode::rect() const +{ + return QRect(0, 0, m_item->width(), m_item->height()); +} diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.h b/examples/quick/scenegraph/rendernode/softwarerenderer.h new file mode 100644 index 0000000000..e91ca92d88 --- /dev/null +++ b/examples/quick/scenegraph/rendernode/softwarerenderer.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SOFTWARERENDERER_H +#define SOFTWARERENDERER_H + +#include <qsgrendernode.h> +#include <QQuickItem> + +class SoftwareRenderNode : public QSGRenderNode +{ +public: + SoftwareRenderNode(QQuickItem *item); + ~SoftwareRenderNode(); + + void render(const RenderState *state) override; + void releaseResources() override; + StateFlags changedStates() const override; + RenderingFlags flags() const override; + QRectF rect() const override; + +private: + QQuickItem *m_item; +}; + +#endif diff --git a/examples/quick/scenegraph/scenegraph.pro b/examples/quick/scenegraph/scenegraph.pro index cf50cdb903..e13e8198b0 100644 --- a/examples/quick/scenegraph/scenegraph.pro +++ b/examples/quick/scenegraph/scenegraph.pro @@ -1,14 +1,21 @@ TEMPLATE = subdirs + +qtConfig(opengl(es1|es2)?) { + SUBDIRS += \ + graph \ + simplematerial \ + sgengine \ + textureinsgnode \ + openglunderqml \ + textureinsgnode \ + textureinthread \ + twotextureproviders +} + SUBDIRS += \ customgeometry \ - graph \ - openglunderqml \ - sgengine \ - simplematerial \ - textureinsgnode \ - textureinthread \ - threadedanimation \ - twotextureproviders + rendernode \ + threadedanimation EXAMPLE_FILES += \ shared diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag b/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag new file mode 100644 index 0000000000..481a238d2a --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag @@ -0,0 +1,18 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 delta; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta) + + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta) + + 0.2466 * source.Sample(sourceSampler, coord) + + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta) + + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag b/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag new file mode 100644 index 0000000000..d6e65b6b10 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag @@ -0,0 +1,17 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float4 tint; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 c = source.Sample(sourceSampler, coord); + float lo = min(min(c.x, c.y), c.z); + float hi = max(max(c.x, c.y), c.z); + return float4(lerp(float3(lo, lo, lo), float3(hi, hi, hi), tint.xyz), c.w) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert b/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert new file mode 100644 index 0000000000..40876e7996 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert @@ -0,0 +1,31 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float bend; + float minimize; + float side; + float width; + float height; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; +}; + +PSInput main(float4 position : POSITION, float2 coord : TEXCOORD0) +{ + PSInput result; + result.coord = coord; + + float4 pos = position; + pos.y = lerp(position.y, height, minimize); + float t = pos.y / height; + t = (3.0 - 2.0 * t) * t * t; + pos.x = lerp(position.x, side * width, t * bend); + result.position = mul(qt_Matrix, pos); + + return result; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag b/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag new file mode 100644 index 0000000000..b6e7e51f35 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag @@ -0,0 +1,21 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 delta; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 tl = source.Sample(sourceSampler, coord - delta); + float4 tr = source.Sample(sourceSampler, coord + float2(delta.x, -delta.y)); + float4 bl = source.Sample(sourceSampler, coord - float2(delta.x, -delta.y)); + float4 br = source.Sample(sourceSampler, coord + delta); + float4 gx = (tl + bl) - (tr + br); + float4 gy = (tl + tr) - (bl + br); + return float4(0.0, 0.0, 0.0, + clamp(dot(sqrt(gx * gx + gy * gy), float4(1.0, 1.0, 1.0, 1.0)), 0.0, 1.0) * qt_Opacity); +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag b/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag new file mode 100644 index 0000000000..a86a25e007 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag @@ -0,0 +1,20 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 offset; + float2 delta; + float darkness; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); +Texture2D shadow : register(t1); +SamplerState shadowSampler : register(s1); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 fg = source.Sample(sourceSampler, coord); + float4 bg = shadow.Sample(shadowSampler, coord + delta); + return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag b/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag new file mode 100644 index 0000000000..c28612a2fd --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag @@ -0,0 +1,17 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float amplitude; + float frequency; + float time; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float2 p = sin(time + frequency * coord); + return source.Sample(sourceSampler, coord + amplitude * float2(p.y, -p.x)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/blur.frag b/examples/quick/shadereffects/content/shaders/blur.frag new file mode 100644 index 0000000000..9173945eed --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/blur.frag @@ -0,0 +1,14 @@ +uniform lowp float qt_Opacity; +uniform sampler2D source; +uniform highp vec2 delta; + +varying highp vec2 qt_TexCoord0; + +void main() +{ + gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/colorize.frag b/examples/quick/shadereffects/content/shaders/colorize.frag new file mode 100644 index 0000000000..1219ef2460 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/colorize.frag @@ -0,0 +1,12 @@ +uniform sampler2D source; +uniform lowp vec4 tint; +uniform lowp float qt_Opacity; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 c = texture2D(source, qt_TexCoord0); + lowp float lo = min(min(c.x, c.y), c.z); + lowp float hi = max(max(c.x, c.y), c.z); + gl_FragColor = qt_Opacity * vec4(mix(vec3(lo), vec3(hi), tint.xyz), c.w); +} diff --git a/examples/quick/shadereffects/content/shaders/genie.vert b/examples/quick/shadereffects/content/shaders/genie.vert new file mode 100644 index 0000000000..3ce371819f --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/genie.vert @@ -0,0 +1,21 @@ +attribute highp vec4 qt_Vertex; +attribute highp vec2 qt_MultiTexCoord0; + +uniform highp mat4 qt_Matrix; +uniform highp float bend; +uniform highp float minimize; +uniform highp float side; +uniform highp float width; +uniform highp float height; + +varying highp vec2 qt_TexCoord0; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + highp vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, height, minimize); + highp float t = pos.y / height; + t = (3. - 2. * t) * t * t; + pos.x = mix(qt_Vertex.x, side * width, t * bend); + gl_Position = qt_Matrix * pos; +} diff --git a/examples/quick/shadereffects/content/shaders/outline.frag b/examples/quick/shadereffects/content/shaders/outline.frag new file mode 100644 index 0000000000..9b46719873 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/outline.frag @@ -0,0 +1,16 @@ +uniform sampler2D source; +uniform highp vec2 delta; +uniform highp float qt_Opacity; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 tl = texture2D(source, qt_TexCoord0 - delta); + lowp vec4 tr = texture2D(source, qt_TexCoord0 + vec2(delta.x, -delta.y)); + lowp vec4 bl = texture2D(source, qt_TexCoord0 - vec2(delta.x, -delta.y)); + lowp vec4 br = texture2D(source, qt_TexCoord0 + delta); + mediump vec4 gx = (tl + bl) - (tr + br); + mediump vec4 gy = (tl + tr) - (bl + br); + gl_FragColor.xyz = vec3(0.); + gl_FragColor.w = clamp(dot(sqrt(gx * gx + gy * gy), vec4(1.)), 0., 1.) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/shadow.frag b/examples/quick/shadereffects/content/shaders/shadow.frag new file mode 100644 index 0000000000..8650ee4f4c --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/shadow.frag @@ -0,0 +1,14 @@ +uniform lowp float qt_Opacity; +uniform highp vec2 offset; +uniform sampler2D source; +uniform sampler2D shadow; +uniform highp float darkness; +uniform highp vec2 delta; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 fg = texture2D(source, qt_TexCoord0); + lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); + gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/wobble.frag b/examples/quick/shadereffects/content/shaders/wobble.frag new file mode 100644 index 0000000000..fedbb68254 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/wobble.frag @@ -0,0 +1,13 @@ +uniform lowp float qt_Opacity; +uniform highp float amplitude; +uniform highp float frequency; +uniform highp float time; +uniform sampler2D source; + +varying highp vec2 qt_TexCoord0; + +void main() +{ + highp vec2 p = sin(time + frequency * qt_TexCoord0); + gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/doc/src/shadereffects.qdoc b/examples/quick/shadereffects/doc/src/shadereffects.qdoc index dc2a2681f5..7b1d68ebb5 100644 --- a/examples/quick/shadereffects/doc/src/shadereffects.qdoc +++ b/examples/quick/shadereffects/doc/src/shadereffects.qdoc @@ -51,6 +51,21 @@ shader: \snippet shadereffects/shadereffects.qml fragment + In order to support multiple graphics APIs, not just OpenGL, the shader + source is not embedded into QML. Instead, file selectors are used to select + the correct variant at runtime. Based on the Qt Quick backend in use, Qt + will automatically select either \c{shaders/wobble.frag} with the GLSL + source code or \c{shaders/+hlsl/wobble.frag} with the HLSL source code. + + \note For simplicity shader source code is used in all variants of the + files. However, with the Direct3D backend of Qt Quick pre-compiled shaders + are also supported. For example, try the following commands in the + \c{content/shaders/+hlsl} directory: \c{move wobble.frag wobble.frag.src} + followed by \c{fxc /E main /T ps_5_0 /Fo wobble.frag wobble.frag.src}. Now + \c wobble.frag contains Direct3D bytecode and that is what gets shipped + with the application instead of the shader source. Further changes are not + necessary, the application will function like before. + You can use any custom property on the ShaderEffect in your shader. This makes animated shader code very easy: \snippet shadereffects/shadereffects.qml properties diff --git a/examples/quick/shadereffects/shadereffects.qml b/examples/quick/shadereffects/shadereffects.qml index 926394ed0f..0c24a7bbf2 100644 --- a/examples/quick/shadereffects/shadereffects.qml +++ b/examples/quick/shadereffects/shadereffects.qml @@ -101,7 +101,7 @@ Rectangle { height: 140 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - font.pixelSize: 120 + font.pixelSize: 118 font.family: "Times" color: "blue" text: "Qt" @@ -128,17 +128,7 @@ Rectangle { property real time: 0 NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 } //! [fragment] - fragmentShader: - "uniform lowp float qt_Opacity;" + - "uniform highp float amplitude;" + - "uniform highp float frequency;" + - "uniform highp float time;" + - "uniform sampler2D source;" + - "varying highp vec2 qt_TexCoord0;" + - "void main() {" + - " highp vec2 p = sin(time + frequency * qt_TexCoord0);" + - " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" + - "}" + fragmentShader: "qrc:shadereffects/content/shaders/wobble.frag" //! [fragment] Slider { id: wobbleSlider @@ -163,32 +153,10 @@ Rectangle { height: theItem.height property variant delta: Qt.size(1.0 / width, 0.0) property variant source: theSource - fragmentShader: " - uniform lowp float qt_Opacity; - uniform sampler2D source; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) - + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) - + 0.2466 * texture2D(source, qt_TexCoord0) - + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) - + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/blur.frag" } } - fragmentShader: " - uniform lowp float qt_Opacity; - uniform sampler2D source; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) - + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) - + 0.2466 * texture2D(source, qt_TexCoord0) - + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) - + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/blur.frag" } } property real angle: 0 @@ -196,19 +164,7 @@ Rectangle { NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 } property variant delta: Qt.size(offset.x / width, offset.y / height) property real darkness: shadowSlider.value - fragmentShader: " - uniform lowp float qt_Opacity; - uniform highp vec2 offset; - uniform sampler2D source; - uniform sampler2D shadow; - uniform highp float darkness; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 fg = texture2D(source, qt_TexCoord0); - lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); - gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/shadow.frag" Slider { id: shadowSlider anchors.left: parent.left @@ -222,38 +178,14 @@ Rectangle { height: 160 property variant source: theSource property variant delta: Qt.size(0.5 / width, 0.5 / height) - fragmentShader: " - uniform sampler2D source; - uniform highp vec2 delta; - uniform highp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 tl = texture2D(source, qt_TexCoord0 - delta); - lowp vec4 tr = texture2D(source, qt_TexCoord0 + vec2(delta.x, -delta.y)); - lowp vec4 bl = texture2D(source, qt_TexCoord0 - vec2(delta.x, -delta.y)); - lowp vec4 br = texture2D(source, qt_TexCoord0 + delta); - mediump vec4 gx = (tl + bl) - (tr + br); - mediump vec4 gy = (tl + tr) - (bl + br); - gl_FragColor.xyz = vec3(0.); - gl_FragColor.w = clamp(dot(sqrt(gx * gx + gy * gy), vec4(1.)), 0., 1.) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/outline.frag" } ShaderEffect { width: 160 height: 160 property variant source: theSource property color tint: root.sliderToColor(colorizeSlider.value) - fragmentShader: " - uniform sampler2D source; - uniform lowp vec4 tint; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 c = texture2D(source, qt_TexCoord0); - lowp float lo = min(min(c.x, c.y), c.z); - lowp float hi = max(max(c.x, c.y), c.z); - gl_FragColor = qt_Opacity * vec4(mix(vec3(lo), vec3(hi), tint.xyz), c.w); - }" + fragmentShader: "qrc:shadereffects/content/shaders/colorize.frag" Slider { id: colorizeSlider anchors.left: parent.left @@ -288,25 +220,7 @@ Rectangle { //! [properties] //! [vertex] mesh: Qt.size(10, 10) - vertexShader: " - uniform highp mat4 qt_Matrix; - uniform highp float bend; - uniform highp float minimize; - uniform highp float side; - uniform highp float width; - uniform highp float height; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - highp vec4 pos = qt_Vertex; - pos.y = mix(qt_Vertex.y, height, minimize); - highp float t = pos.y / height; - t = (3. - 2. * t) * t * t; - pos.x = mix(qt_Vertex.x, side * width, t * bend); - gl_Position = qt_Matrix * pos; - }" + vertexShader: "qrc:shadereffects/content/shaders/genie.vert" //! [vertex] Slider { id: genieSlider diff --git a/examples/quick/shadereffects/shadereffects.qrc b/examples/quick/shadereffects/shadereffects.qrc index ff296a0155..e66b98a6df 100644 --- a/examples/quick/shadereffects/shadereffects.qrc +++ b/examples/quick/shadereffects/shadereffects.qrc @@ -4,5 +4,17 @@ <file>content/face-smile.png</file> <file>content/qt-logo.png</file> <file>content/Slider.qml</file> + <file>content/shaders/wobble.frag</file> + <file>content/shaders/+hlsl/wobble.frag</file> + <file>content/shaders/blur.frag</file> + <file>content/shaders/+hlsl/blur.frag</file> + <file>content/shaders/shadow.frag</file> + <file>content/shaders/+hlsl/shadow.frag</file> + <file>content/shaders/outline.frag</file> + <file>content/shaders/+hlsl/outline.frag</file> + <file>content/shaders/colorize.frag</file> + <file>content/shaders/+hlsl/colorize.frag</file> + <file>content/shaders/genie.vert</file> + <file>content/shaders/+hlsl/genie.vert</file> </qresource> </RCC> |