From: Gunnar Sletta Date: Mon, 30 Jul 2012 09:09:23 +0000 (+0200) Subject: Three scene graph examples with docs. X-Git-Tag: upstream/5.2.1~1273 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ddf7f1cf638091c8c7c7380bf0414dcc1145d2c;p=platform%2Fupstream%2Fqtdeclarative.git Three scene graph examples with docs. How to make a custom QSGGeometry, how to use QSGSimpleMaterial and how to use render with raw GL. Change-Id: I3e5a32b6ae12d7d781c11050ed26a54845e92cca Reviewed-by: Gunnar Sletta --- diff --git a/examples/quick/customitems/customitems.pro b/examples/quick/customitems/customitems.pro index 2349fce..68a240c 100644 --- a/examples/quick/customitems/customitems.pro +++ b/examples/quick/customitems/customitems.pro @@ -2,7 +2,6 @@ TEMPLATE = subdirs SUBDIRS = \ #dialcontrol \ #flipable \ - glitem \ painteditem \ #progressbar \ #scrollbar \ diff --git a/examples/quick/doc/customgeometry.qdoc b/examples/quick/doc/customgeometry.qdoc new file mode 100644 index 0000000..e17990c --- /dev/null +++ b/examples/quick/doc/customgeometry.qdoc @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example quick/scenegraph/customgeometry + \title Custom Geometry Example + \ingroup examples + + The custom geometry example shows how to create a QQuickItem which + uses the scene graph API to build a custom geometry for the scene + graph. It does this by creating a BezierCurve item which is made + part of the CustomGeometry module and makes use of this in a QML + file. + + \image custom-geometry-example.png + + \section1 BezierCurve Declaration + + \snippet quick/scenegraph/customgeometry/beziercurve.h 1 + + The item declaration subclasses the QQuickItem class and adds five + properties. One for each of the four control points in the bezier + curve and a parameter to control the number of segments the curve + is subdivided into. For each of the properties we have + corresponding getter and setter functions. Since these properties + can be bound to in QML, it is also preferable to have notifier + signals for each of them so changes will be picked up the QML + engine and used accordingly. + + \snippet quick/scenegraph/customgeometry/beziercurve.h 2 + + The synchronization point between the QML scene and the rendering + scene graph is the virtual function \l + QQuickItem::updatePaintNode() which all items with custom scene + graph logic must implement. + + \e { The scene graph will on many hardware configurations be + rendering on a separate thread. It is therefore crucial that + interaction with the scene graph happens in a controlled + manner, first and foremost through the \l + QQuickItem::updatePaintNode() function. } + + \section1 BezierCurve Implementation + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 1 + + The BezierCurve constructor sets up default values for the + control points and the number of segments. The bezier curve + is specified in normalized coordinates relative to the item's + bounding rectangle. + + The constructor also sets the flag \l + QQuickItem::ItemHasContents. This flags tells the canvas that this + item provides visual content and will call \l + QQuickItem::updatePaintNode() when it is time for the QML scene to + be synchronized with the rendering scene graph. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 2 + + The BezierCurve class has no data members that need to be cleaned + up so the destructor does nothing. It is worth mentioning that the + rendering scene graph is managed by the scene graph it self, + potentially in a different thread, so one should never retain + QSGNode references in the QQuickItem class nor try to clean them + up explicitly. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 3 + + The setter function for the p1 property checks if the value is + unchanged and exits early if this is the case. Then it updates the + internal value and emits the changed signal. It then proceeds to + call the \l QQuickItem::update() function which will notify the + rendering scene graph, that the state of this object has changed + and needs to be synchronized with the rendering scene graph. + A call to update() will result in a call to + QQuickItem::updatePaintNode() at a later time. + + The other property setters are equivalent, and are omitted from + this example. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 4 + + The updatePaintNode() function is the primary integration point + for synchronizing the state of the QML scene with the rendering + scene graph. The function gets passed a QSGNode which is the + instance that was returned on the last call to the function. It + will be null the first time the function gets called and we create + our QSGGeometryNode which we will fill with geometry and a + material. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 5 + + We then create the geometry and add it to the node. The first + argument to the QSGGeometry constructor is a definition of the + vertex type, called an "attribute set". Since the graphics often + used in QML centers around a few common standard attribute sets, + these are provided by default. Here we use the Point2D attribute + set which has two floats, one for x coordinates and one for y + coordinates. The second argument is the vertex count. + + \e {Custom attribute sets can also created, but that is not + covered in this example}. + + Since we do not have any special needs for memory managing the + geometry, we specify that the QSGGeometryNode should own the + geometry. + + \e {To minimize allocations, reduce memory fragmentation and + improve performance, it would also be possible to make the + geometry a member of a QSGGeometryNode subclass, in which case, we + would not have set the QSGGeometryNode::OwnsGeometry flag}. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 6 + + The scene graph API provides a few commonly used used material + implementations. In this example we use the QSGFlatColorMaterial + which will fill the shape defined by the geometry with a solid + color. Again we pass the ownership of the material to the node, so + it can be cleaned up by the scene graph. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 7 + + In the case where the QML item has changed and we only want to + modify the existing node's geometry, we cast the \c oldNode to a + QSGGeometryNode instance and extract it's geometry. In case the + segment count has changed, we call QSGGeometry::allocate() to make + sure it has the right number of vertices. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 8 + + To fill the geometry, we first extract the vertex array from + it. Since we are using one of the default attribute sets, we can + use the convenience function QSGGeometry::vertexDataAsPoint2D(). + Then we go through each segment and calculate its position and + write that value to the vertex. + + \snippet quick/scenegraph/customgeometry/beziercurve.cpp 9 + + In the end of the function, we return the node so the scene graph + can render it. + + \section1 Application Entry-Point + + \snippet quick/scenegraph/customgeometry/main.cpp 1 + + The application is a straightforward QML application, with a + QGuiApplication and a QQuickView that we pass a .qml file. To make + use of the BezierCurve item, we need to register it in the QML + engine, using the qmlRegisterType function. We give it the name + BezierCurve and make it part of the \c {CustomGeometry 1.0} + module. + + \section1 Using the Item + + \snippet quick/scenegraph/customgeometry/LineTester.qml 1 + + Our .qml file imports the \c {QtQuick 2.0} module to get the + standard elements and also our own \c {CustomGeometry 1.0} module + which contains our newly created BezierCurve element. + + \snippet quick/scenegraph/customgeometry/LineTester.qml 2 + + Then we create the our root item and an instance of the + BezierCurve which we anchor to fill the root. + + \snippet quick/scenegraph/customgeometry/LineTester.qml 3 + + To make the example a bit more interesting we add an animation to + change the two control points in the curve. The end points stay + unchanged. + + \snippet quick/scenegraph/customgeometry/LineTester.qml 4 + + Finally we overlay a short text outlining what the example shows. + + */ + diff --git a/examples/quick/doc/images/custom-geometry-example.png b/examples/quick/doc/images/custom-geometry-example.png new file mode 100644 index 0000000..33739f7 Binary files /dev/null and b/examples/quick/doc/images/custom-geometry-example.png differ diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro index 809ddea..3884c7f 100644 --- a/examples/quick/quick.pro +++ b/examples/quick/quick.pro @@ -9,6 +9,7 @@ SUBDIRS = accessibility \ mousearea \ positioners \ righttoleft \ + scenegraph \ shadereffects \ text \ threading \ diff --git a/examples/quick/scenegraph/customgeometry/beziercurve.cpp b/examples/quick/scenegraph/customgeometry/beziercurve.cpp new file mode 100644 index 0000000..dde24d0 --- /dev/null +++ b/examples/quick/scenegraph/customgeometry/beziercurve.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "beziercurve.h" + +#include +#include + +//! [1] +BezierCurve::BezierCurve(QQuickItem *parent) + : QQuickItem(parent) + , m_p1(0, 0) + , m_p2(1, 0) + , m_p3(0, 1) + , m_p4(1, 1) + , m_segmentCount(32) +{ + setFlag(ItemHasContents, true); +} +//! [1] + +//! [2] +BezierCurve::~BezierCurve() +{ +} +//! [2] + +//! [3] +void BezierCurve::setP1(const QPointF &p) +{ + if (p == m_p1) + return; + + m_p1 = p; + emit p1Changed(p); + update(); +} +//! [3] + +void BezierCurve::setP2(const QPointF &p) +{ + if (p == m_p2) + return; + + m_p2 = p; + emit p2Changed(p); + update(); +} + +void BezierCurve::setP3(const QPointF &p) +{ + if (p == m_p3) + return; + + m_p3 = p; + emit p3Changed(p); + update(); +} + +void BezierCurve::setP4(const QPointF &p) +{ + if (p == m_p4) + return; + + m_p4 = p; + emit p4Changed(p); + update(); +} + +void BezierCurve::setSegmentCount(int count) +{ + if (m_segmentCount == count) + return; + + m_segmentCount = count; + emit segmentCountChanged(count); + update(); +} + +//! [4] +QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QSGGeometryNode *node = 0; + QSGGeometry *geometry = 0; + + if (!oldNode) { + node = new QSGGeometryNode; +//! [4] //! [5] + geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount); + geometry->setLineWidth(2); + geometry->setDrawingMode(GL_LINE_STRIP); + node->setGeometry(geometry); + node->setFlag(QSGNode::OwnsGeometry); +//! [5] //! [6] + QSGFlatColorMaterial *material = new QSGFlatColorMaterial; + material->setColor(QColor(255, 0, 0)); + node->setMaterial(material); + node->setFlag(QSGNode::OwnsMaterial); +//! [6] //! [7] + } else { + node = static_cast(oldNode); + geometry = node->geometry(); + geometry->allocate(m_segmentCount); + } +//! [7] + +//! [8] + QRectF bounds = boundingRect(); + QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); + for (int i = 0; i < m_segmentCount; ++i) { + qreal t = i / qreal(m_segmentCount - 1); + qreal invt = 1 - t; + + QPointF pos = invt * invt * invt * m_p1 + + 3 * invt * invt * t * m_p2 + + 3 * invt * t * t * m_p3 + + t * t * t * m_p4; + + float x = bounds.x() + pos.x() * bounds.width(); + float y = bounds.y() + pos.y() * bounds.height(); + + vertices[i].set(x, y); + } +//! [8] + +//! [9] + return node; +} +//! [9] + diff --git a/examples/quick/scenegraph/customgeometry/beziercurve.h b/examples/quick/scenegraph/customgeometry/beziercurve.h new file mode 100644 index 0000000..7b750f3 --- /dev/null +++ b/examples/quick/scenegraph/customgeometry/beziercurve.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BEZIERCURVE_H +#define BEZIERCURVE_H + +//! [1] +#include + +class BezierCurve : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QPointF p1 READ p1 WRITE setP1 NOTIFY p1Changed) + Q_PROPERTY(QPointF p2 READ p2 WRITE setP2 NOTIFY p2Changed) + Q_PROPERTY(QPointF p3 READ p3 WRITE setP3 NOTIFY p3Changed) + Q_PROPERTY(QPointF p4 READ p4 WRITE setP4 NOTIFY p4Changed) + + Q_PROPERTY(int segmentCount READ segmentCount WRITE setSegmentCount NOTIFY segmentCountChanged) + +public: + BezierCurve(QQuickItem *parent = 0); + ~BezierCurve(); + +//! [2] + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); +//! [2] + + QPointF p1() const { return m_p1; } + QPointF p2() const { return m_p2; } + QPointF p3() const { return m_p3; } + QPointF p4() const { return m_p4; } + + int segmentCount() const { return m_segmentCount; } + + void setP1(const QPointF &p); + void setP2(const QPointF &p); + void setP3(const QPointF &p); + void setP4(const QPointF &p); + + void setSegmentCount(int count); + +signals: + void p1Changed(const QPointF &p); + void p2Changed(const QPointF &p); + void p3Changed(const QPointF &p); + void p4Changed(const QPointF &p); + + void segmentCountChanged(int count); + +private: + QPointF m_p1; + QPointF m_p2; + QPointF m_p3; + QPointF m_p4; + + int m_segmentCount; +}; +//! [1] + +#endif + diff --git a/examples/quick/scenegraph/customgeometry/customgeometry.pro b/examples/quick/scenegraph/customgeometry/customgeometry.pro new file mode 100644 index 0000000..8657820 --- /dev/null +++ b/examples/quick/scenegraph/customgeometry/customgeometry.pro @@ -0,0 +1,10 @@ +TARGET = customgeometry +QT += quick + +SOURCES += \ + main.cpp \ + beziercurve.cpp + +HEADERS += \ + beziercurve.h + diff --git a/examples/quick/scenegraph/customgeometry/main.cpp b/examples/quick/scenegraph/customgeometry/main.cpp new file mode 100644 index 0000000..63396f3 --- /dev/null +++ b/examples/quick/scenegraph/customgeometry/main.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "beziercurve.h" + +//! [1] +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("CustomGeometry", 1, 0, "BezierCurve"); + + QQuickView view; + view.setSource(QUrl("main.qml")); + view.show(); + + app.exec(); +} +//! [1] diff --git a/examples/quick/scenegraph/customgeometry/main.qml b/examples/quick/scenegraph/customgeometry/main.qml new file mode 100644 index 0000000..46a11e0 --- /dev/null +++ b/examples/quick/scenegraph/customgeometry/main.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import QtQuick 2.0 +import CustomGeometry 1.0 +//! [1] //! [2] +Item { + width: 300 + height: 200 + + BezierCurve { + id: line + anchors.fill: parent + anchors.margins: 20 +//! [2] //! [3] + property real t + SequentialAnimation on t { + NumberAnimation { to: 1; duration: 2000; easing.type: Easing.InOutQuad } + NumberAnimation { to: 0; duration: 2000; easing.type: Easing.InOutQuad } + loops: Animation.Infinite + } + + p2: Qt.point(t, 1 - t) + p3: Qt.point(1 - t, t) + } +//! [3] //! [4] + Text { + anchors.bottom: line.bottom + + x: 20 + width: parent.width - 40 + wrapMode: Text.WordWrap + + text: "This curve is a custom scene graph item, implemented using GL_LINE_STRIP" + } +} +//! [4] diff --git a/examples/quick/customitems/glitem/main.cpp b/examples/quick/scenegraph/openglunderqml/main.cpp similarity index 96% rename from examples/quick/customitems/glitem/main.cpp rename to examples/quick/scenegraph/openglunderqml/main.cpp index 8d1a91b..223f8bf 100644 --- a/examples/quick/customitems/glitem/main.cpp +++ b/examples/quick/scenegraph/openglunderqml/main.cpp @@ -45,16 +45,17 @@ #include "squircle.h" +//! [1] int main(int argc, char **argv) { QGuiApplication app(argc, argv); - qmlRegisterType("OpenGLUnderQML", 2, 0, "Squircle"); + qmlRegisterType("OpenGLUnderQML", 1, 0, "Squircle"); QQuickView view; view.setSource(QUrl("main.qml")); view.show(); return app.exec(); - } +//! [1] diff --git a/examples/quick/customitems/glitem/main.qml b/examples/quick/scenegraph/openglunderqml/main.qml similarity index 96% rename from examples/quick/customitems/glitem/main.qml rename to examples/quick/scenegraph/openglunderqml/main.qml index 66bc08b..1823d2a 100644 --- a/examples/quick/customitems/glitem/main.qml +++ b/examples/quick/scenegraph/openglunderqml/main.qml @@ -39,8 +39,9 @@ ** ****************************************************************************/ +//! [1] import QtQuick 2.0 -import OpenGLUnderQML 2.0 +import OpenGLUnderQML 1.0 Item { @@ -48,8 +49,6 @@ Item { height: 480 Squircle { - width: 320 - height: 320 SequentialAnimation on t { NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad } NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad } @@ -57,9 +56,9 @@ Item { running: true } } - +//! [1] //! [2] Rectangle { - color: Qt.rgba(1, 1, 1, 0.8); + color: Qt.rgba(1, 1, 1, 0.7) radius: 10 border.width: 1 border.color: "white" @@ -77,5 +76,5 @@ Item { anchors.bottom: parent.bottom anchors.margins: 20 } - } +//! [2] diff --git a/examples/quick/customitems/glitem/glitem.pro b/examples/quick/scenegraph/openglunderqml/openglunderqml.pro similarity index 100% rename from examples/quick/customitems/glitem/glitem.pro rename to examples/quick/scenegraph/openglunderqml/openglunderqml.pro diff --git a/examples/quick/customitems/glitem/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp similarity index 83% rename from examples/quick/customitems/glitem/squircle.cpp rename to examples/quick/scenegraph/openglunderqml/squircle.cpp index b134068..f7bbeb9 100644 --- a/examples/quick/customitems/glitem/squircle.cpp +++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp @@ -42,31 +42,53 @@ #include "squircle.h" #include -#include +#include +#include +//! [7] Squircle::Squircle() : m_program(0) { - setFlag(ItemHasContents); } +//! [7] +//! [8] +void Squircle::setT(qreal t) +{ + if (t == m_t) + return; + m_t = t; + emit tChanged(); + if (canvas()) + canvas()->update(); +} +//! [8] + + +//! [1] void Squircle::itemChange(ItemChange change, const ItemChangeData &) { // The ItemSceneChange event is sent when we are first attached to a window. if (change == ItemSceneChange) { QQuickWindow *c = window(); + if (!c) + return; +//! [1] - // Connect our the beforeRendering signal to our paint function. + // Connect the beforeRendering signal to our paint function. // Since this call is executed on the rendering thread it must be // a Qt::DirectConnection +//! [2] connect(c, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection); +//! [2] // If we allow QML to do the clearing, they would clear what we paint // and nothing would show. +//! [3] c->setClearBeforeRendering(false); } } - +//! [3] //! [4] void Squircle::paint() { if (!m_program) { @@ -83,14 +105,18 @@ void Squircle::paint() "varying highp vec2 coords;" "void main() {" " lowp float i = 1. - (pow(coords.x, 4.) + pow(coords.y, 4.));" - " i = smoothstep(t - 0.3, t + 0.3, i);" - " gl_FragColor = vec4(coords / 2. + .5, i, i);" + " i = smoothstep(t - 0.8, t + 0.8, i);" + " i = floor(i * 20.) / 20.;" + " gl_FragColor = vec4(coords * .5 + .5, i, i);" "}"); m_program->bindAttributeLocation("vertices", 0); m_program->link(); - } + connect(canvas()->openglContext(), SIGNAL(aboutToBeDestroyed()), + this, SLOT(cleanup()), Qt::DirectConnection); + } +//! [4] //! [5] m_program->bind(); m_program->enableAttributeArray(0); @@ -119,5 +145,16 @@ void Squircle::paint() m_program->disableAttributeArray(0); m_program->release(); } +//! [5] + +//! [6] +void Squircle::cleanup() +{ + if (m_program) { + delete m_program; + m_program = 0; + } +} +//! [6] diff --git a/examples/quick/customitems/glitem/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h similarity index 95% rename from examples/quick/customitems/glitem/squircle.h rename to examples/quick/scenegraph/openglunderqml/squircle.h index 9e7a03b..43b0022 100644 --- a/examples/quick/customitems/glitem/squircle.h +++ b/examples/quick/scenegraph/openglunderqml/squircle.h @@ -45,6 +45,7 @@ #include #include +//! [1] class Squircle : public QQuickItem { Q_OBJECT @@ -55,22 +56,23 @@ public: Squircle(); qreal t() const { return m_t; } - void setT(qreal t) { m_t = t; emit tChanged(); update(); } - - void itemChange(ItemChange change, const ItemChangeData &); + void setT(qreal t); signals: void tChanged(); +protected: + void itemChange(ItemChange change, const ItemChangeData &); + public slots: void paint(); + void cleanup(); private: QOpenGLShaderProgram *m_program; qreal m_t; - bool m_render_under; - bool m_render_over; }; +//! [1] #endif // SQUIRCLE_H diff --git a/examples/quick/scenegraph/scenegraph.pro b/examples/quick/scenegraph/scenegraph.pro new file mode 100644 index 0000000..96ffbd4 --- /dev/null +++ b/examples/quick/scenegraph/scenegraph.pro @@ -0,0 +1,4 @@ + +TEMPLATE = subdirs +SUBDIRS += customgeometry simplematerial openglunderqml + diff --git a/examples/quick/scenegraph/simplematerial/main.qml b/examples/quick/scenegraph/simplematerial/main.qml new file mode 100644 index 0000000..b5d5c58 --- /dev/null +++ b/examples/quick/scenegraph/simplematerial/main.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import QtQuick 2.0 +import SimpleMaterial 1.0 + +Rectangle { + width: 640 + height: 360 + + gradient: Gradient { + GradientStop { position: 0; color: "#00ffff" } + GradientStop { position: 1; color: "#00ff00" } + } + +//! [1] //! [2] + SimpleMaterialItem { + + anchors.fill: parent + SequentialAnimation on scale { + NumberAnimation { to: 100; duration: 60000; easing.type: Easing.InCubic } + NumberAnimation { to: 1; duration: 60000; easing.type: Easing.OutCubic } + loops: Animation.Infinite + } + + rotation: scale * 10 - 10 + } +//! [2] //! [3] + Rectangle { + color: Qt.rgba(0, 0, 0, 0.8) + radius: 10 + border.width: 1 + border.color: "black" + anchors.fill: label + anchors.margins: -10 + } + + Text { + id: label + color: "white" + wrapMode: Text.WordWrap + text: "The background here is implemented as one QSGGeometryNode node which uses QSGSimpleMaterial to implement a mandlebrot fractal fill" + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 20 + } +} +//! [3] diff --git a/examples/quick/scenegraph/simplematerial/simplematerial.cpp b/examples/quick/scenegraph/simplematerial/simplematerial.cpp new file mode 100644 index 0000000..a91c3b5 --- /dev/null +++ b/examples/quick/scenegraph/simplematerial/simplematerial.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include + +#include + +//! [1] +struct Color +{ + QColor color; + + int compare(const Color *other) const { + uint rgb = color.rgba(); + uint otherRgb = other->color.rgba(); + + if (rgb == otherRgb) { + return 0; + } else if (rgb < otherRgb) { + return -1; + } else { + return 1; + } + } +}; +//! [1] + +//! [2] +class Shader : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(Shader, Color); +//! [2] //! [3] +public: + + const char *vertexShader() const { + return + "attribute highp vec4 aVertex; \n" + "attribute highp vec2 aTexCoord; \n" + "uniform highp mat4 qt_Matrix; \n" + "varying highp vec2 texCoord; \n" + "void main() { \n" + " gl_Position = qt_Matrix * aVertex; \n" + " texCoord = aTexCoord; \n" + "}"; + } + + const char *fragmentShader() const { + return + "uniform lowp float qt_Opacity; \n" + "uniform lowp vec4 color; \n" + "varying highp vec2 texCoord; \n" + "void main () \n" + "{ \n" + " highp vec2 z = texCoord; \n" + " gl_FragColor = vec4(0); \n" + " const highp float maxIterations = 100.; \n" + " for (float i = 0.; i < maxIterations; i += 1.0) { \n" + " z = vec2(z.x*z.x - z.y*z.y, 2.0*z.x*z.y) + texCoord; \n" + " if (dot(z, z) > 4.0) { \n" + " float col = pow(1. - i / maxIterations, sqrt(maxIterations / 10.)); \n" + " gl_FragColor = color * col * qt_Opacity; \n" + " break; \n" + " } \n" + " } \n" + "} \n"; + } +//! [3] //! [4] + QList attributes() const + { + return QList() << "aVertex" << "aTexCoord"; + } +//! [4] //! [5] + void updateState(const Color *color, const Color *) + { + program()->setUniformValue(id_color, color->color); + } +//! [5] //! [6] + void resolveUniforms() + { + id_color = program()->uniformLocation("color"); + } + +private: + int id_color; +}; +//! [6] + + +//! [7] +class TestNode : public QSGGeometryNode +{ +public: + TestNode(const QRectF &bounds) + : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) + { + QSGGeometry::updateTexturedRectGeometry(&m_geometry, bounds, QRectF(-0.60, -0.66, 0.08, 0.04)); + setGeometry(&m_geometry); + +//! [7] //! [8] + QSGSimpleMaterial *material = Shader::createMaterial(); + material->state()->color = Qt::blue; + material->setFlag(QSGMaterial::Blending); + + setMaterial(material); + setFlag(OwnsMaterial); + } +//! [8] //! [9] + QSGGeometry m_geometry; +}; +//! [9] + + +//! [10] +class Item : public QQuickItem +{ + Q_OBJECT +public: + + Item() + { + setFlag(ItemHasContents, true); + } + + QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) + { + delete node; + return new TestNode(boundingRect()); + } +}; +//! [10] + + + +//! [11] +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("SimpleMaterial", 1, 0, "SimpleMaterialItem"); + + QQuickView view; + view.setSource(QUrl("main.qml")); + view.show(); + + return app.exec(); +} +//! [11] + +#include "simplematerial.moc" diff --git a/examples/quick/scenegraph/simplematerial/simplematerial.pro b/examples/quick/scenegraph/simplematerial/simplematerial.pro new file mode 100644 index 0000000..10dec99 --- /dev/null +++ b/examples/quick/scenegraph/simplematerial/simplematerial.pro @@ -0,0 +1,8 @@ + +QT += quick + +SOURCES += \ + simplematerial.cpp + +OTHER_FILES += \ + test.qml diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 0c6e00f..24acb3e 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -84,14 +84,15 @@ codeindent = 1 headerdirs += .. -sourcedirs += .. +sourcedirs += .. ../../../examples/quick/doc exampledirs += ../../../ \ - ../../../examples \ + ../../../examples/ \ ../ \ snippets -imagedirs += images + +imagedirs += images ../../../examples/quick/doc/images #add qml sources because of dependencies headerdirs += ../../qml diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 3e1de8b..ca94570 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -887,6 +887,8 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) may result in the entire scene graph and its OpenGL context being deleted. The sceneGraphInvalidated() signal will be emitted when this happens. + \sa {OpenGL Under QML Example} + */ QQuickWindow::QQuickWindow(QWindow *parent) : QWindow(*(new QQuickWindowPrivate), parent) diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index 54c5100..8855e5c 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -284,7 +284,7 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() setIndexDataPattern() functions. Whether this hint is respected or not is implementation specific. - \sa QSGGeometryNode + \sa QSGGeometryNode, {Custom Geometry Example} */ diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp index 1a25fac..73f1a2d 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.cpp +++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp @@ -140,6 +140,8 @@ renderer internally uses to identify this shader. For this reason, the unique QSGSimpleMaterialShader implemenation must be instantiated with a unique C++ type. + + \sa {Simple Material Example} */ /*!