Three scene graph examples with docs.
authorGunnar Sletta <gunnar.sletta@nokia.com>
Mon, 30 Jul 2012 09:09:23 +0000 (11:09 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 13 Aug 2012 13:06:46 +0000 (15:06 +0200)
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 <gunnar.sletta@nokia.com>
22 files changed:
examples/quick/customitems/customitems.pro
examples/quick/doc/customgeometry.qdoc [new file with mode: 0644]
examples/quick/doc/images/custom-geometry-example.png [new file with mode: 0644]
examples/quick/quick.pro
examples/quick/scenegraph/customgeometry/beziercurve.cpp [new file with mode: 0644]
examples/quick/scenegraph/customgeometry/beziercurve.h [new file with mode: 0644]
examples/quick/scenegraph/customgeometry/customgeometry.pro [new file with mode: 0644]
examples/quick/scenegraph/customgeometry/main.cpp [new file with mode: 0644]
examples/quick/scenegraph/customgeometry/main.qml [new file with mode: 0644]
examples/quick/scenegraph/openglunderqml/main.cpp [moved from examples/quick/customitems/glitem/main.cpp with 96% similarity]
examples/quick/scenegraph/openglunderqml/main.qml [moved from examples/quick/customitems/glitem/main.qml with 96% similarity]
examples/quick/scenegraph/openglunderqml/openglunderqml.pro [moved from examples/quick/customitems/glitem/glitem.pro with 100% similarity]
examples/quick/scenegraph/openglunderqml/squircle.cpp [moved from examples/quick/customitems/glitem/squircle.cpp with 83% similarity]
examples/quick/scenegraph/openglunderqml/squircle.h [moved from examples/quick/customitems/glitem/squircle.h with 95% similarity]
examples/quick/scenegraph/scenegraph.pro [new file with mode: 0644]
examples/quick/scenegraph/simplematerial/main.qml [new file with mode: 0644]
examples/quick/scenegraph/simplematerial/simplematerial.cpp [new file with mode: 0644]
examples/quick/scenegraph/simplematerial/simplematerial.pro [new file with mode: 0644]
src/quick/doc/qtquick.qdocconf
src/quick/items/qquickwindow.cpp
src/quick/scenegraph/coreapi/qsggeometry.cpp
src/quick/scenegraph/util/qsgsimplematerial.cpp

index 2349fce..68a240c 100644 (file)
@@ -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 (file)
index 0000000..e17990c
--- /dev/null
@@ -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 (file)
index 0000000..33739f7
Binary files /dev/null and b/examples/quick/doc/images/custom-geometry-example.png differ
index 809ddea..3884c7f 100644 (file)
@@ -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 (file)
index 0000000..dde24d0
--- /dev/null
@@ -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 <QtQuick/qsgnode.h>
+#include <QtQuick/qsgflatcolormaterial.h>
+
+//! [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<QSGGeometryNode *>(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 (file)
index 0000000..7b750f3
--- /dev/null
@@ -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 <QtQuick/QQuickItem>
+
+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 (file)
index 0000000..8657820
--- /dev/null
@@ -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 (file)
index 0000000..63396f3
--- /dev/null
@@ -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 <QtGui>
+#include <QtQuick>
+
+#include "beziercurve.h"
+
+//! [1]
+int main(int argc, char **argv)
+{
+    QGuiApplication app(argc, argv);
+
+    qmlRegisterType<BezierCurve>("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 (file)
index 0000000..46a11e0
--- /dev/null
@@ -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]
 
 #include "squircle.h"
 
+//! [1]
 int main(int argc, char **argv)
 {
     QGuiApplication app(argc, argv);
 
-    qmlRegisterType<Squircle>("OpenGLUnderQML", 2, 0, "Squircle");
+    qmlRegisterType<Squircle>("OpenGLUnderQML", 1, 0, "Squircle");
 
     QQuickView view;
     view.setSource(QUrl("main.qml"));
     view.show();
 
     return app.exec();
-
 }
+//! [1]
@@ -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]
 #include "squircle.h"
 
 #include <QtQuick/qquickwindow.h>
-#include <QOpenGLShaderProgram>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
 
+//! [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]
 
 
@@ -45,6 +45,7 @@
 #include <QtQuick/QQuickItem>
 #include <QtGui/QOpenGLShaderProgram>
 
+//! [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 (file)
index 0000000..96ffbd4
--- /dev/null
@@ -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 (file)
index 0000000..b5d5c58
--- /dev/null
@@ -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 (file)
index 0000000..a91c3b5
--- /dev/null
@@ -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 <qguiapplication.h>
+
+#include <qsgmaterial.h>
+#include <qsgnode.h>
+
+#include <qquickitem.h>
+#include <qquickview.h>
+
+#include <qsgsimplerectnode.h>
+
+#include <qsgsimplematerial.h>
+
+//! [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<Color>
+{
+    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<QByteArray> attributes() const
+    {
+        return QList<QByteArray>() << "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<Color> *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<Item>("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 (file)
index 0000000..10dec99
--- /dev/null
@@ -0,0 +1,8 @@
+
+QT += quick
+
+SOURCES += \
+    simplematerial.cpp
+
+OTHER_FILES += \
+    test.qml
index 0c6e00f..24acb3e 100644 (file)
@@ -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
index 3e1de8b..ca94570 100644 (file)
@@ -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)
index 54c5100..8855e5c 100644 (file)
@@ -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}
 
  */
 
index 1a25fac..73f1a2d 100644 (file)
     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}
  */
 
 /*!