From 3ddf7f1cf638091c8c7c7380bf0414dcc1145d2c Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 30 Jul 2012 11:09:23 +0200 Subject: [PATCH] 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 --- examples/quick/customitems/customitems.pro | 1 - examples/quick/customitems/glitem/glitem.pro | 6 - examples/quick/customitems/glitem/main.cpp | 60 ------ examples/quick/customitems/glitem/main.qml | 81 -------- examples/quick/customitems/glitem/squircle.cpp | 123 ------------ examples/quick/customitems/glitem/squircle.h | 76 -------- examples/quick/doc/customgeometry.qdoc | 201 ++++++++++++++++++++ .../quick/doc/images/custom-geometry-example.png | Bin 0 -> 27636 bytes examples/quick/quick.pro | 1 + .../scenegraph/customgeometry/beziercurve.cpp | 168 ++++++++++++++++ .../quick/scenegraph/customgeometry/beziercurve.h | 100 ++++++++++ .../scenegraph/customgeometry/customgeometry.pro | 10 + examples/quick/scenegraph/customgeometry/main.cpp | 60 ++++++ examples/quick/scenegraph/customgeometry/main.qml | 76 ++++++++ examples/quick/scenegraph/openglunderqml/main.cpp | 61 ++++++ examples/quick/scenegraph/openglunderqml/main.qml | 80 ++++++++ .../scenegraph/openglunderqml/openglunderqml.pro | 6 + .../quick/scenegraph/openglunderqml/squircle.cpp | 160 ++++++++++++++++ .../quick/scenegraph/openglunderqml/squircle.h | 78 ++++++++ examples/quick/scenegraph/scenegraph.pro | 4 + examples/quick/scenegraph/simplematerial/main.qml | 88 +++++++++ .../scenegraph/simplematerial/simplematerial.cpp | 195 +++++++++++++++++++ .../scenegraph/simplematerial/simplematerial.pro | 8 + src/quick/doc/qtquick.qdocconf | 7 +- src/quick/items/qquickwindow.cpp | 2 + src/quick/scenegraph/coreapi/qsggeometry.cpp | 2 +- src/quick/scenegraph/util/qsgsimplematerial.cpp | 2 + 27 files changed, 1305 insertions(+), 351 deletions(-) delete mode 100644 examples/quick/customitems/glitem/glitem.pro delete mode 100644 examples/quick/customitems/glitem/main.cpp delete mode 100644 examples/quick/customitems/glitem/main.qml delete mode 100644 examples/quick/customitems/glitem/squircle.cpp delete mode 100644 examples/quick/customitems/glitem/squircle.h create mode 100644 examples/quick/doc/customgeometry.qdoc create mode 100644 examples/quick/doc/images/custom-geometry-example.png create mode 100644 examples/quick/scenegraph/customgeometry/beziercurve.cpp create mode 100644 examples/quick/scenegraph/customgeometry/beziercurve.h create mode 100644 examples/quick/scenegraph/customgeometry/customgeometry.pro create mode 100644 examples/quick/scenegraph/customgeometry/main.cpp create mode 100644 examples/quick/scenegraph/customgeometry/main.qml create mode 100644 examples/quick/scenegraph/openglunderqml/main.cpp create mode 100644 examples/quick/scenegraph/openglunderqml/main.qml create mode 100644 examples/quick/scenegraph/openglunderqml/openglunderqml.pro create mode 100644 examples/quick/scenegraph/openglunderqml/squircle.cpp create mode 100644 examples/quick/scenegraph/openglunderqml/squircle.h create mode 100644 examples/quick/scenegraph/scenegraph.pro create mode 100644 examples/quick/scenegraph/simplematerial/main.qml create mode 100644 examples/quick/scenegraph/simplematerial/simplematerial.cpp create mode 100644 examples/quick/scenegraph/simplematerial/simplematerial.pro 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/customitems/glitem/glitem.pro b/examples/quick/customitems/glitem/glitem.pro deleted file mode 100644 index 64a58b3..0000000 --- a/examples/quick/customitems/glitem/glitem.pro +++ /dev/null @@ -1,6 +0,0 @@ -QT += qml quick - -HEADERS += squircle.h -SOURCES += squircle.cpp main.cpp - -OTHER_FILES += main.qml diff --git a/examples/quick/customitems/glitem/main.cpp b/examples/quick/customitems/glitem/main.cpp deleted file mode 100644 index 8d1a91b..0000000 --- a/examples/quick/customitems/glitem/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** 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 "squircle.h" - -int main(int argc, char **argv) -{ - QGuiApplication app(argc, argv); - - qmlRegisterType("OpenGLUnderQML", 2, 0, "Squircle"); - - QQuickView view; - view.setSource(QUrl("main.qml")); - view.show(); - - return app.exec(); - -} diff --git a/examples/quick/customitems/glitem/main.qml b/examples/quick/customitems/glitem/main.qml deleted file mode 100644 index 66bc08b..0000000 --- a/examples/quick/customitems/glitem/main.qml +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -import QtQuick 2.0 -import OpenGLUnderQML 2.0 - -Item { - - width: 320 - 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 } - loops: Animation.Infinite - running: true - } - } - - Rectangle { - color: Qt.rgba(1, 1, 1, 0.8); - radius: 10 - border.width: 1 - border.color: "white" - anchors.fill: label - anchors.margins: -10 - } - - Text { - id: label - color: "black" - wrapMode: Text.WordWrap - text: "The background here is a squircle rendered with raw OpenGL using the 'beforeRender()' signal in QQuickWindow. This text label and its border is rendered using QML" - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.margins: 20 - } - -} diff --git a/examples/quick/customitems/glitem/squircle.cpp b/examples/quick/customitems/glitem/squircle.cpp deleted file mode 100644 index b134068..0000000 --- a/examples/quick/customitems/glitem/squircle.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** 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 "squircle.h" - -#include -#include - -Squircle::Squircle() - : m_program(0) -{ - setFlag(ItemHasContents); -} - -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(); - - // Connect our the beforeRendering signal to our paint function. - // Since this call is executed on the rendering thread it must be - // a Qt::DirectConnection - connect(c, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection); - - // If we allow QML to do the clearing, they would clear what we paint - // and nothing would show. - c->setClearBeforeRendering(false); - } -} - -void Squircle::paint() -{ - if (!m_program) { - m_program = new QOpenGLShaderProgram(); - m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, - "attribute highp vec4 vertices;" - "varying highp vec2 coords;" - "void main() {" - " gl_Position = vertices;" - " coords = vertices.xy;" - "}"); - m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, - "uniform lowp float t;" - "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);" - "}"); - - m_program->bindAttributeLocation("vertices", 0); - m_program->link(); - } - - m_program->bind(); - - m_program->enableAttributeArray(0); - - float values[] = { - -1, -1, - 1, -1, - -1, 1, - 1, 1 - }; - m_program->setAttributeArray(0, GL_FLOAT, values, 2); - m_program->setUniformValue("t", (float) m_t); - - glViewport(0, 0, window()->width(), window()->height()); - - glDisable(GL_DEPTH_TEST); - - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - m_program->disableAttributeArray(0); - m_program->release(); -} - - diff --git a/examples/quick/customitems/glitem/squircle.h b/examples/quick/customitems/glitem/squircle.h deleted file mode 100644 index 9e7a03b..0000000 --- a/examples/quick/customitems/glitem/squircle.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** 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 SQUIRCLE_H -#define SQUIRCLE_H - -#include -#include - -class Squircle : public QQuickItem -{ - Q_OBJECT - - Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged) - -public: - Squircle(); - - qreal t() const { return m_t; } - void setT(qreal t) { m_t = t; emit tChanged(); update(); } - - void itemChange(ItemChange change, const ItemChangeData &); - -signals: - void tChanged(); - -public slots: - void paint(); - -private: - QOpenGLShaderProgram *m_program; - - qreal m_t; - bool m_render_under; - bool m_render_over; -}; - -#endif // SQUIRCLE_H 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 0000000000000000000000000000000000000000..33739f78b8cde4a330c7b3c51e978618e74905f4 GIT binary patch literal 27636 zcma&MV{~Or6EJ#W+qP|MVoYpL>||nF6B`pd6VFK|wr$(Co$oyF{qDc}(v($CfUXN#r7jiz>d8Grq@_Fp&#eLgc))+;nnjwdijFd=${}si^ zB=^TEaTuK{ky5=geg5m~BmKyy^G)!nvy1PlQP1}X zBoV}~H2~Yxx|BlrfbrjgGtI}tT)vP!=dKcBkmvsxQIYuTxVxIyeU<~_`05h&m6}3tpq4*WNdoT8SI6O?UYKIY0{`EaMJMfEY z?xNX%?*^kB5v5*$7wYDn-}iRWaDmVXiN)mgx(K)$_&2{;aia`^oj z)av17@fGELhNJDq#|7JqO$(mxOH6|%7o}A_!AuizWW~s!$?(WH%J?xp z*0nAb@GOdYEtwl|+z?PG5G-*Gmv{k&m+E+pzO=$ zL2n6AT)PfE;3WRG9I&{_KpXbS;^+JM`0SCR(6ih+kAys6Ge9>$67c$EI;f3N#kNRj z8w(77IO?^vKSEdB^_(>>1?N* zS(2#{)W;tHd&_)$183FgZbj5T85uj1ZADBP zu^FSi4ycZJ7R4&S|FEr%)kJ=-U1N9mVvMHgB6L;PS@tcv<0~JE79yWNqQA9Y#7c|?tU0KPVSO@Sx<8St zdmXyFLthtB=#dAhW6?N)CfRxbjz(QIw}t`pVVrnSZNp`$9nMV(CiR=x<6To6oWZ-1e-By!m<*zec@61=C0B4qp6GNtoZtq53MXY zkvcGPLMOlBwE)lO=N=NR?W9kHi&?e&cCob@dH?(+^0!4QHQLLI^s!XgeXjx5e6&LPgy$J+-V zB#}URjG7JG6KeKNxFBs>7MF6IgPk3o!{JARC8EjtP{x$!uN&q)*gf>bSlaKLY(e~YS+}=0~PAo>!RxM|ElUFYa{5?)+5(3Ck#_kB{9*(q)4`kwo3mt>-+nw zKC|uxSn@aZ@5T=Tsy;I`AX=uBB2{{_z{uXYwmY0V!lUt{_&LrB$=@mGx}SE3PCJoD zwEI>ExQC&91AI)p;(RW=XMAsb={z@%?92O2C)=f~-~F<%TRdCtTi%=5TTYvEU6@?d zn!h)TH^)2kICt%c-O1c7-}T>Q@0{#s9-1F5?3UbE+%DdA?uy^Y-tk>u>@w_~?dWae zZ1e2J?~4osLL_cm%CKr(r)|T)!wdwX%Z-$|DqDm-hmMDt zgigW>q3fchp}J!$qSavdQ+z|6LA}8l!Lr85#KOYdpl{V{(7jK^4ao@C&R>@O>+o0d zC)`i18^jx_8(BDJID}skzifVq$x_P-jpQViBuy39sp6}Wsg{)x%NG@Elt7dql=zq{ zv)izXv6q?W4x5-Y4Tq1VjUo@D9U$(T98?@g?eiT}AE@mU99UvXUuAa zB~u5gN?H$y$B-EcQ;Rf$76fdqZCl;$H0L$Ps)w48S0h(K*EmV{U=R&Z98cxn00-H+WV1-$tTo!$@4j#KvTS9NCj23t152F%;!Q^yJ`|DLfe{osLW z5^_LU_gW8G&k}SZW+uiWMp#p5%vt8{G;s5Ief%Us7ufY!zuUh-e6V{kxheEExEb_p z^ESHv6#G|_ri$as=o{s0VJ+2=+z{XS+S$^n=Fjgx^uGCa_Dph@hd2$#OU#N@j+24I zOJs(rj>?H+N32iSj%z}oiU-6$#n;6NN4Z08Bc8-2M&CpuLq#LGp;V=27jpJ2JDkK2 zusqSckD{fukycmZ6mTB7_>~y5Lc)PwNuY=OCNxQPDJMuLEZ9jS#=m3S`zA5h@6tBi zX4SUpfpDR?DFhrco?4-#9ijQ-S3A7f(6RS6{+OdgO&LKcqM)L{mv+mw!1a$WR>a6S3oP$-c#*ztE1`uHoik`)+b*G8;|AUG-g- z;;&qO=Tm7h3eZ8&ZorNKi(Pe&0PdPIpYI@^FzU7`Rl;!&aI`#EPCA%eF=F7lk z;4kO&+e;VxqY8RYdSs3FD#Ths;VY-kBDs!=Q}C^@Y#Vhqg$MPC$KOLZu`JvRqYJs! zdsPCiaQaa#_dCF+gHP|u*GC3?Et}dX1EyA~&a@Q(7bWL7H#9dgPYaJwi-T83hfd|o zD$)x zY~CBrG6(8mrtEV?PCPCH*y{X@pTn-AN74&ejtmDnb-g+qQ8_YR!XLhGqHZal=>2JO z>$B;rrWm9Ux+2`_ATEjZCyd5_W6S04;Y@roy!KltzBL<5Iho%>Srd*4hyfYJoX=nP zf2^dO4^J&WriAJp>i1mkTNYS!?$+;8jd%j=jq3DpU$GzU&Drh*o}TXH@#QzhYR0a# zcKx^g_rFqJSKh}?m$q$|Pi-hu6%D%JyJaL_-XN|^&`0#v!AM1*1H0b^cvfjyonJ)B zlyHtoZD^{3*8KzwDoqgkoEC4`5Iq8MGIf2i=aIXTU1;Rp@&!9tciNc6(S<(F5iL`DOIU4sn;k;RIKvWc_I?gYnZleWVb8 z7n<_c@XRaId{v(v^__Yqy4fN?B|gS8!>A%6#~39T#BC%L#=0Q~`dCtQu+y`62Pn8Q zGEI_gl8SNvoMX0Hy1xt(vX|xZQM!~@M3(<4&n1_U6l==8L`FrFl?qZ5I0 zWM+9}MlvGo{k&YT2ji@!cs>#>jQ9J>WwfNbP`Og(k#h@gkYj8BgDQT~kZyuy&EV2y zvi)0UQit=wdt1dD4zm`{e6c=awOh?x8>L&O?~B&QerlOkRt*-{xot65rhdBBAdk}K zu>;@IZ(o-;riZnvrn1%5)w`=u4_r5Ak4ZP7%T8yWE5lvCDVT7fB$P}NWx4xj;+zDXuq3=nQCVqnP${pM}p>|GN8$nF2pYig1q@?M^kKk{GnX&X}(3=7&yS zc2oNOzQy?4x&D(NB`OZGyah|PdI%RTquIlbE_}vFKhu{-m!FSs`?GBa9t=ey)c*dj z4{mO58(-A45ZYk5Vog8T>*9F51Ytgf#BmCO*`jgB_6O`H3nxdFOejCd8R~qT_njY| zde%<`gW4@$Hes(}SJi-F-V(5d7A9{4SF*b$j3xEvxg&6+F!cIr!KwBdiuS}B$!hU) zR!e5{&hyOkcr(efC>-TH`s|BbvRw9TK0k!bZ#Lj^&RZgFKj}E4SfR#?W<%x!NZuRntHqI| z_kFc_@V;+}&>JDL+&ESOWYmEhMeYN4@gs`w)5;oF1$ua-t9Z z{c-C|k70>kEIJ#iaWxe3V5;tEnrW83=YM>4y}Kje(W}sn-%@DBa$f70s51D7GlNm0 zalxrL^LZNIxbbnkd=fdnXnCqTQgOUW9#YD?f9mjjJzd$pEBM?A@?aS>RBZSDdhOf3 z&sr&XY1#@;-xMn{G3DNa!$`d{QcM(H_7&v+aF%*?IXyqdIeQ^Mpx-*}tYqBKX8T~f zX0Yn}x}BDuw_Zkzl{OmcH(982X{Po?58(@nXB}G>8#jfw;QoPT@*>#_{Fzj;(&Uuk z)M^KRxH{w)d_?X@vxWKvBo&ZU8J6PxMyYpSs9pQqPMMyP>l&z#c23m-_L3L%O|En_ zh(0sRR-L5cyDe&yjLmP`7n`dEy4mW5%0&^=1k(&NOp|kqLPvUsL1S*~P3xb7?5m^m zzc;)+&!7letAAer4J!STLQ4CB_o&KHE!mEmn4xME9mX9tE=P!e6W^`bG{T&tuCr}> z^^f%u+&UCczuMjC6mvaGz0ti*yevV5Ldn4>LTf<2g)4vC48;y@2~Fq*m!!1lHM*f5IFYYhQ$qhdrVDk7=ug}%_*f$eNMswzWTud%q z@~twjM==C2?8y9P@MiwJu1vODKPv4e&l9tMQ~Z@iivLSUAZVCM;L}SRpTgq`gtDK5LJGo<==HWm1JD}Th!;LGqZd6)a8x!_Sy!(T~#T&Pp+ zN!03aKASUU{_sc3w^rA1&Q94b#R|QBa$(#*Wd56tdDn=K{CT5u*3Y)LobtHr$<~_A z%MzcIHv!@pLBZ*^mm5!`k@`UY4V>B9eds3S1H=Hl4GuCMDB;NfYF{?(;TPdA3X_Si zt}hBb25m0D=t@GMCvu?6ydz_2L^g>KV3`eUy8$Zy5dkny4IT*e{>&vooizcYFoqBm z#iRw;Q%<=`vtJsJ!i-SYQoQV8LW;M`q*=ku~CJWD*yZl7J8B?fqKg;7DY#ch5BH|=Op(x7>vi-YO z0pq5(gv>W3=opE=bGNwEQ!5}Ua_wCwCZn|cc)cqu#=r$F!$zj z119yPKeKct(`z*Nz+`^*Pbz^(#L^QAY>T}y7+M0DNCIS55SkODKPfRG^g%upVxU(f zR#GTp!G*G53c>H-O1q#?FzU0!v{#@8e|q_HDqwcFh{UQa}rs!$~EjXTWbZ2f%&6_ z)Rhh;J1taF9MYA#Z=I73#IiMM-v?W?=VsX({)MMXV_wwy@tIkjo(83O$V3Vo`XIU$`F21e%Ah`U_C+gJtGC@KNipi6DjWZt!6TEn=>F2`z_m0 zC{Hd75+m5i2<$ry;6SBETlb$!5H}=pK zpmICvmT+Bq!(<=2vk}I2cT@1RlRQSETDqh3W}#_8aU^w=)4BOcU7yhenFgUr{Hgw- z(YzDDX$+w3MxYGDXO&#^$CZH!%Lls;(&>K!CO}~V%tbYnQ8=S_MXif`RU%Zrm$PL+ zo>4G-GQMNRirW?yP2)@#;rg5XJ2H8#v(uJ7hdYbFiqIR(+I6`xMYKVL!P`Vv zhg%7ylfoEeC#U#{a)Y48ItN+Laz`l-IR3l zY>}(83D)WU=^X^$V27j!raG+_yvg z%AC|0UD?mRl8%V;$SW7oaXyv#F?zDRJ6-Q@zIoJ6FH~8+5Qmd`s?F?Ian<5oKvpzT zrc)nQ;`Xd*ulG)rqd4t$c3JaQfg&u#c;Ob%yY6v)5^|*6^(uNCos{lZ+mpXeP*%{~ zyZ)(f3c1kiJ@r#|y=zhT+ z?4Q%gTAXC>?!uKoTAe&jI#F6zZT4rulj*+YDNCZ!MdhaLXZ)>}ilK-wX(1UPqhMjd z>nFfz2=MIX>gHDB>h@rXmt=tE&I3sYj(5Of~Nf#h@{=jsr<2k2!8mH5y1Y=ADZ(s5QW> z(iTrD8B=Sv|Kcqd{3#duAV?R|bifGr7Dj3g;iz#S`)M+7#HKfOvG_sO-}??PHcI?? z*3dek#(2pDFLE6!tW#-Q@bU~`7G>=E{quf>N($$B#ao3pA#)$b>1 z(*d4Q2|!nW!%mGL&CM?-wkPqbZ0VH<3oDDPI;y^EpG{*VYU_sG#ezEP_BQ8q{C=wS zgcbJCu9{0j2b9Qj^+!k}5tG9a&W<(jx>dHxE%v9mO`baC9zUac1hpJzM*dIsjX zKjwwD(nR2U?YhNvak((25t`0aC92Yz$LdU;7DPZfH{?yl)gOC)dsCa?nuI&z&0U`} zuS&sM-!dW;Z(>B76eKZl7$pm)dBhUzA*^vfNjhN?y{R==d2ufw)W7T~+dHRd8z`v+ zK+j!gSs|oOqBX3dc#0uZpv|w%UHLOCZLif&)$!6By-&S=K;7DRBC$vN6L|=yUis- z@v~go1AMKZaHm?#gXhPJUE}!wT6??T3O;9JO=JFFHCWY(8_Fs*eZZu{en9;SA*f+v zTX5oInGbzM#lPie^lNFKy-0XP&16d*OQ%(9p5+L5NT?tp{MR_LCZYxyoEE0HlAxxv zN;1?M=?6$`d`rZ@{HYiUB5aKrfzVNpsOg+;H`5@0ewcGSnK2KWO#6;0*+kQEzE6E-`4qj8Jt${I zzQHUMB73v^a2+erh~;k2iSmb21@rGGMDZt-7%Utd8-8q)!^Y_NIOPtpo_y38u+_X$ zC9U_Xzv+3*`yH=av!U>FKBX+p^Xv2D`r1hh)s8!>3OI}h4YFPd;NxYXxnLUs3gV95?NnH4*+m!u!AyMgAfyBQxCL^F&Tgew-T41YrOXAgi2`(=V&6 z8QWQ?yr?GVh9M$YNy;hw{v1y!p4R>wP%TPm=iFUj z1(NTVEH`kRgvr@Eu|DV$mhaby)QOyxh~#3_vRay1GUbRd>omVvfq?v|?4r1wd}R(d z#Om_#ih^x8B7VZh?Ae2zxcQR!t?>tp-N)P+k^z=aW@2_{ksCRiMLu1yYX4AaVC6H$b#!&6A&WeCmzFGQ}8yNDRHZGcHc1(1{jNFpWN4!mVp7+Vr-)~Q0YzQ>< z(@N^3ar9B@&jW8p_gY+z6eT1eKV(ou0Ibvd)MPoLB~>!Q5<4y480Lp_Fp(wErUe7 zY?HA*O?+!;yX&#X$z=vICM+q%s2U{kIg1`@?#!&g&9QHwu>+e;{K*<0DOfxaw0Y; zrLr{T`Hw>)0;3XGQ-j+L;asIjW)TWbvA54*-&DJ`l{BrIRxoP?iRqQnz6ChHJzmt+ zu>!f>_q9<&P0tpM^qL&3K3W&DxED9tXg*p<9!cg)$|9sfwMNHZ&!&I)nW-yuw03hM z$|lL+2G~u#p8Hk4x!V$MoRamVF>DG`ZVG`vp63q_(}%~Xy*;k=G7M7B!yMih!Z;6o zPOMGZ*{{`0oj{NNipAk-tnWBH8vV?ZpIr@1&u zzc;$2Xk+QJBbC;&U{dR?_R~l!#C=TJij3rzkZ+x=lXBI@C9ksrEXop;4nTB##BIHc zo~#0ck0d5kR_HWpem&jVixKk5=|6 z%ox?Nl7pTtepptM8(E=7Mk#oF{4n<;jWu}&7O-UR_2j}H+#A9$U+qMFfqBt54acqv zQOs6XB;Va&-xy^@NXC}#stREj5c+K>RYq|(o07WUI18J#jHTl<#6>+fE#mPRbaLDL zi5O^byYUk3FFOpX%#{=Qfw_2)R7}c4Z~}=NbwLc#{wfXyZpR&39!UkNi1;v?*;@Eb z9430jD%}toJvzO3tEdxvRZA(9{S_^;)%|r3WHfwlQ%s;@6c}=Sh)w0&6v+;yLvoA@*UBb0#fd06n>t$-oKh0#)DrnMy5d z5||7&Hxw-aM^vK%f2ZPO z*kk=M_KI3^wf4vZIEC#_A#GBobSsvQ6-Ddg^YGU`P12bJm_3=z!xZx7+#bVO>?}5U zWq_*xs(rDBShU-r+Ejr2})LsbZE)*VrD@@7ACXI`g zIv0@r5EJ{6MjE|oHj_mq3ykv4QGxNM#YxLDmn}13ZKVJf$-JrUGkXCofJXPFV5>7^54u7Di`r~=?^g(Qcp%jCzy5~Jdgo&x`T_eP(#MVnxWGEr2F>oF!B z${-YBeEbtNHmloj-`7}g`Q+o%T2$m|289dzrMm=1^tGcXXM zX%ugUn|=`+$T}tpo`ituK?ntu=oCT#;p7@!H=hHN0!zqwGiXEAiS7Znx3`dDAcGD% zFp-00?J}n`S*GfHlM&61a@3{aXoYr=~2@bEC{ zQQZh?LPLVA>$fQKyt5ln?-5_KsY;bFKGfNtZtwF@u4IKs2)>{FH4 zVLqFtHETzNY%N`H#$Smm_{Iddtfs1VYXE>VKM;$`X>W_1!&h8Fi3VO)@S9_F$quvt zBUOv=)xc6$zboH^w-6GQOl%@F3m*;D%WK*9V8!-X6W;760{O|h=;{FOl>9b@p}i9w ziCfeEm}8y7#M2o@s#yhTny!Qu01d2#@+1l!Oduj{3EII0$1=bz(q^1mU{g|v%*R<9rb zG%yU!(Q`A@@|?Iq69JBiyz6>X_pH(4q8=)^$jYesjtD0SFd>g31^zJ1GMCpT7B>OR!M%#>h6r|>R zei(>{ika&0qkv1Hq<~hemaweOf1uiiq9xq!J$T&PcN@9}2vG_#CKtnbZ#~R2YzPV?*vN{%feTR64?UJs`0$jf(xZVs{^` z#Grx-8Pa1s(e8fqzKD7^A*WHqATb2!t|nNj{qUn0(`5s`QXEe6dN0wkYO!WbSa4@u z9jx>FTF09Wmut4@y1H@#^t*n3^d87VOKXSFSJQ_MB&kI$!tqMmo1yRp-4&BHn z1*QrOf>94j2&DYdIfRomdCSIPe?Q&$i7uGXC;m=-Q{MXV@mBW<(!|rnYI%lG*hJ>! z_;c_N8Ji4?(g@X~_M%9+>}n}`fmo;}(9H+X9IyS&b450(e^ONiB1zombpB6sGp`f= zoE2x%-7mx*XecN=`^FeGnyWm4JhwY&K&W~Qa;=I`m7+n`Oh#(zfF?5^gzMyuas7(j z{K{1c(Ri~LKg}II05WVaOrr_|ZEhK?G&`Hn8-M055E(5zB4Ul~s`mjy>r%ft-5)_T z3O2ez_pikQ{J-z~@|v31tVkNphFHV0D3fgsG7$r2?0>ZkyjLi_ma%)e`5N!22-K5u zgwQ?MaP+V8P_qrlyuEPrhn7w#)OJx}rLV83OMIkW$y_Ts2lEN071hutSE_BUU z685n^j|G+nrt$}5hVEzEkoa;r%-!$=;Ler*Q4EvbUNS;iIuO zllCsMBj|g5`th;V>Q?En(aK(X^P6HI`9)DBV4Gg7Q5_in0)MyZZ5V&%Wh-kVv@8B>o*9)8kQ zF8t2Pv1i3y7HD^Nc3$R?H3<&|3+xXBB&4RM=Hz@w=HRog(qsS}yYg2q$SL}vODDX$ zA~pOgi>YJVHvp`n=D zzt*nS^d1CoL`&B$?~_X@ny|MH5qmmGfq{IdzT3zbDByk!p*+f9Zm9t-8L}%Bxe#TM zT9P5bAFGt5tC@gqP-J-ecbpR9k&hsf&ZT4}#BEtX0ug7Jh&4+aILIFCvY3QCo7_Q> zRbNTsbtx+#=X3}ymJgO zB|C2N62snCpivd5lQ$fAe#d}3yB&K-Wgw+2FoUUq1$18$LtV6;y`7vLBH_Iu!otXL zd}piRIFAra8kmpq>4hs=yL5)gzj{+p2EM|{w-C%IcJEA&n@!Q?oqvWVIb+9;p@Tqr z>;?+lh76g+#lPL%-clwgNF|FoPV*gM+jA4pi3lW7B?`Il%+$2EHSJm2OcY>(MIhimBDlNRzP!@n zu;PLIfggpSsXak8j7XR7a+&4eubM0)9d~lQZy&a{cPK0;EE^wDK)8HO!z# zI5R`aODB~Fi#dez|FRW3_Yanfq(K_s5>3W~tI*>+{2)XL|%H<-G#mo>E zw(kO-*clg!ye4ur=cT{^_@8tH14re>ozB0KV1kID^pAWcmpuNG!m7p$|E9Dr+x`w= zi6g2;WM>jYSM@N@U7Mrmf!<7H0U@Ltg3b{yb_dEd6fgfEpjcDHB4GD41`s>WZR}=g zD;1%(S72RCE+zKI9?Y082EqnoQUIy{%sBshD0>v?YUxdH30%B$T3dbV7RdenQ!fPf zj7;WlUz6OxBD@@rXB{18)9&7lW|$;fRu40SW~eTC8zVx&Pkj_IIdD7qVvfV}9NGrB zISFhXMdeo8siS9Lg#0#Db%8zC)6Ek6fJ7b+u^4LYb>jpuR%;CopDwK5a&d30KT1|L z%8tuDp1IDn1h}Tjx+tDt648~1sGmh&KCWd|9%!J9DNi=0PkT1PJ%yu7!I4$&NjD8R zazZN(&F3~f!@f4ed~br{$iMPw#;1)kx+z)(+Eq2sBE*xzqHNJ`aGN>NfCcP@Jy?x2 z+*z?yGF`V-yFVms!2KeXVJq}YhF?=$&}|(I9t4u-^1}O~pIO^U{Y3>b0NT(Sfo3FF zbiO-ikaUQ-oT{G`Z+cEN@c%Bbo5%f6c1GcgtDXF(uyTfbp=bXeX3|B=%;W!KL}}v| zPW;lA@qH(((Txhf!hEGSv24KGlhD20=gaL6Lzpll4Nf%QET!9>UrVdyHW@$LC_ zwi8q+ud464Eb~%Y-HgsXux8?!yJDnN-11!uGkaJ1->SrapK(t^ZQ)Y}V}X0WlKrhI zVhl%}E$sXJB1!XN6-jg)X(Y_`ZwQq0(q(@k*&Db|V6OX5tS+}o5zzxOnGtan-|fHW z`J%0~h)_+rN0KwJItwYao(0O4>)=V*`sH~Pu)95GMG+JFKmX<8bThm^Kzj*iNhx0B zXt`#i^mZWNz(2S^ip|rI3tG=ZJ*RCcgVCNgp)^+`3<%mRB^T0i29ut8&Z68EuV9-O zF`vFYz~-Kl8O00NB!)sRx38o#NF)SGFB%Iu9!hG60=|S24;LJT{^09a{JFl;mz4`< z(u4m84GHIoY2s|BcKxKA8C{lfNL?|ZPPdwIPr zLB&9K`UWB98!YnMhOCGd>HVRUE&x~82g5J~B!b`e;vF)-e5Gl_`Se$$1Kw1kiz(0d z$z^8pkJ$}jC6$v*GWy&Y1O^;GREc;Cf=D|D?cYHB3Q!aDsG;q>YOLb-6={gTz=u_} z!Xzlw6=0g3%!a2L_TJnLIqfSDf}|s)>M_|=jjBF^Ku3>ig9OPBSCG9>Hw`B$XpeBqo@n(EmE1MB;yY0woUn{=uGO7&ms2zb>zl>LlsG3d61z(-XK^BQL(Oz zCjb$2m7oxxP>W-N7uAA7eR!*bNX?NOa{22mdd^p#otT4D*rvTtLCed*Kf0h5#{@0T zneEG*ACb%8K~x{brC=_%;~jxsj0Y~dNPh#5!43M*hos}ke-Jd@mywa{^#@Tvn)c59 zADRI-str&Q8VV`%J?wO0=lx}u89taa4BS-65tk1g<{7oPA!P9`JOxumM)U@xWzf|} zR1{JGz@#0i%n1|-*bj=G$WrlzRh8>mLA;Wc3Dl`4<--GzQk68zhmb~k7*}bL4yQ10 zjs=sJpvFAF!~c379+y&8Wy66MLyhmzu0>6VbeyLp+!Iewg&gz_qvpaI0ckp-m;EBocF84j4sr!zMB>aYlgB#E%h7?op)}AUWF5XAE z`{9TqCP$BZ_JYqo9&twitE$?gJ%vI^x!;vg;q8X_idtM8w0K8Q+|=g9K}oZR2@{+` zIPLuzD%h2n5=!9*tLiLz_JYUWl=U0_zXgSxqDcpkCoM4H`u%?WV)bITTLGt#+OB2- z84l3tLMf>ZVEl@tddgLJmm^3Az;$bfWo3gvY+z&C@>@QVOeln^)*_^&>>f^hxy%y8 zOG=&rtznk`5QVbaIj=4w8#Iz!;Qg@6j2a9HY1M%az`LTTJ*_k(YU_aA)tdIEf_8Q> zva#`RN*7!TdKE`C3Rz_MG3~&Tc~Js_`la(9vVVcPMY{$sfn~FM#(C6mTF*z4jG7mbNgk`o>AMozaJn73;6ZxMWmPxR`pQy z3<@2enc|L2uMr^niMkVp!2FuURVfn{N$L+%9RUFB4}}1CMDPi~LE8L+U`LKd&PDOk zrOTCGd;A5f$_^?GIQ3kcqMAyW4n*4~QJHS>{U5)GE*Thbb*WH140q5mQ?knl+G_iTmRH{_)c(}>j zYE~wQ$xDtFTNp=UL}SpD%#aS92vJ7^$mgRPB76~af?WtEFbG`~IKXjrG`ltdkcSmq zcv&kAL;?)aR($c-`P{^Lh#zeaI~b@?f%p34kR1us;oKoPhd2s_YZ3VgQb>h<+&avl zt0i&NE3$xPwa3B$-vwJbFi=ecRM0cWDoKb2O z0*ubUO9paK5r!&w{$-XBfmCd--upW|=tOdeX6-CwWM4bn{UZO3r6fDMHkm$xx%LOy zYA@6$jY{YusRNPY@Mq*0(CgxFo9E!T_b<5rIcH;;X&z@v;gK`(|0wU0QTVwWZevC$ zb^ip-MM}{7otz9N_-uO?N&R0$MHjTb1kO9IrTyOtW+CtnAp-Z!cmq0{<<)e1v_U%| zprd=~F!0qd3hMq3B$JhWiFZn{9!I4hdp!3HI$Wbkvl5T|_i#NoFF& z&aPzk`ZfH28%z-=-o)jqXdY9s0STGR2@Mq#I=ZqiF{mUZfxRaZEg>N=zRC+6bn;Qi zedxo9tQ%_KrvDC($YzV(8Mw&=`Vw^F36UsoEx-Rm+a;zz;xKQIJ#+p?ZY5Z-p3RH> z(PiO3C==rU4q{|?ru@G+JgB!8`u`@zBqacjruHBR1plLWw(U1o^B-CvWDcM3Kg=8@ z6_|1J(f@YBk9*nj-v)um;Xa^In7q6JvwC?|U8?H?qNBVgWo4bI>@G%9Dt5O0uo)a> zwA||Wuyh|tx>Q9hp4;WaHZa3|5QA)l{N|sHnjBUe=-loGS%{HFVglT6 z9+|SZ?N^gt4bEs6_~9Jc_EW)-0{d0v1k1b|G9uhcIo%#EaCv3~;QEs}KF$JkC6d?iHe-QRwfSvhKA z{P3E)(Q6&nMG@vNl2sQ3+VATeyZPkCWb$sPwg3kNwheJR@acW-NRvdSUgqg@IPN^!{+M`+$6d~LsW*;{sQgR3ScdbA2b)j4cm8{)3j?K)CuEwPwQ7)simfY&hV^7Fh%!fInN zgBjwIIsNinqt|+@dZs9HHz|8P0JBSXul+dF{CE_ym4*j+X*IIwHs3rOs2xymgd;kj zxlwaH)D{Kgj<2>jU1qLUzx}Jmf>xa@v6sjGaNqTp=$H(F`4^7@4yfDEYjXYf&u}Qh zKI^EO?}ruN`HA5_w{-tJ9!nS9k~oS88V$CeB|w9%db^%h@g}6yQ;%bj1~+pdK;Yiy z4U)Y7#!v1!LcOcRP9;iEBF9V1oiV%X(9`gNSxGoie*zrPNHCOU$D5R}%=LO44AnM^ z(He`t$WQ%McktQaw$uJlR;()|g=njlxy2axaK&_Y^x?iaU8lA5+=XI5zvQD_<`m*- zb)XdSor%9c&#?7)y3drRA*waNWURuiO=*KmGr;WHG^YXvEb!qrZ;U&ycC)71|LI*r z`hu$sDWJ-pa3gdh*U$dx*6VB%N`%wZ^+{Lk_TrRcZijcRSHD(aPP~VRJbceL#%ISE1H^F@MU3 z;J(H3)UAfDzTVC!a*1FpXS1!keq6O?XuEJ2#;521cG%KC>6r5u9I&p|=goJ}Wl4 z!ErJ2wdOAm4!AkJs_nR+>E9t5@=I_1@*WJL>&wgYqC^1zitj`^Sob$v#8jM22h^DK zx?0(pXzUld*8X|BUl6@umy8e8#^!iX;sESuIxm;sZyZs~moJHQKF4wu9Ih1oKD56) z{Dqwb-eyOeS_SX-cR87*4=-geY`6n<>zTCJXO$eY+ukD~oxC^4C`8uNMBv>%(w9hl zt`vv?-7Qz%JQp7)xowT(b6reZiPS-^{$syI99KCM?R6WU(;=3sNJ~EWOMiBN zdijk>`<-$Vw7pUT0$l?x$G)CMQg-Z#-vr&BYSmsF@z_606zvBmHvgG!R^}vs{TpFs z(R_U$(tY@}IEgdV(aQ7l`&kMJ*zK$}^gP>JBDr`!eV-Tiuy^u5 z#PAzr5q9Nx8*NR=MM2K-(E$gXEI#rK`QPqD6A`~TEu^K+4GGT{PkC6LP}fZ2Ef;=8 z*mAQdc-`-ii5MQnNjy&N<^7+|&ikLO_y7OLENzXNMNw2$6-Dh4qeiV*wMSdCc58zs3q=XHPF&#yKROI{g2=s+`G zIL5`e)j@ZgRa)(1d!*yo`kAQs=L!LwQQ93i+MNpM_=KIcM_+pW?eGSV%r#kevRKT@ zUiIq7c=|%87yh{|1e7^JLcT6pF7`rZ)IMCZ-+6xf`O+Zf;SP$C#b-KTJ=1{i`&qj6N5B6?7L)e z3E5R;9FqL&yZQ%mZQ-VU$-SOoQEFLSI>JVc%E3j_kGI6!H#D1Gl2uh|9>xZk9;mI| zugf&^*u~wK0*;&~#&=oW%T!~-IF7nU3aBDH zo_b}zI{R-uO2o9SZgr)eA*hTWcQIqWR2(%60^cY3{qQ>AWFMD#ZMqTTNC3=9|D1Lj z|A}+5kra`wnr6}1A71eDbZE8SaMF@?!*EeaHKu2w%!*sa(^}7#YCnlOI6yxxu;|zK zwO(TOKkjvBeB8RXkeVds*$KDuijEa{wK;b@I1Q7%2;>8T(y@021?PRrjGPyujhKCA zFdL!{Z+HIuIU08b)n6k<*vP%o%YI&tGJ3d02Jn2BtoWNKN?Ty1cC)-#GWM2)dIX2i z7^gaJr;%@lJUw2KDqL}WW|k&mK1QUgw~`lqCsa{vu~{|y^PhBK z_G=OIEuLF{ee|}mku^Nk$`gso4ba-$%kix5R57;!C-kL?q!|SJY$hjI7&_o=od1GY zHB+lz;ApWT9+hh0FYZ+;1B}+~qa_{A!c?@_F$XgzlIr@h$rt-gkIvi+3-C=yjViM) z4LfNWE{rc*n~8cf^NdXXrHSVE0a?|HXmP^LAqFmqMzR@mKOOj#i(svT%;G$~{qM3k zUz?4ektM8{`ujK@v;DL3J0fNNa*zJyYa~~UywDy;%Xo0WsQ9U({oCxzC_AWW*z#!i zD1oEJVcL+>z838Nt_yp`ZNzE>UKsM2c3z*(?PH~o;xT*x0G=w{pmG&Lj*8j%`R6+y zdlsaTfv8Zow(GH8GpR8ZK9m6$Z*dY6kkv)B$71|98r{!+TqfmkqaPJQ&_PGzNVjM1 zIrtdwW7#CGK5Lbg7Tk8j9-ChXSTvu)+%(p)H9YA&ADkzJuq7-6o^}!a2L6ki+Voxk zB!2qwkDP?qAP?q;JM@uRY*y?Ne^>B1vI03%*!rPzi~U8EUAwo$>(R6!k`jw-2wJ!Q zpy0)n_Z#!7P0NjsvV26VQ>=Qv<8s#5hMdf-_GQkxaCL^|YeCuDKJY>N(ePJFFC@%m zV?W0HEV1P%(U2%f1$4F^fi+crlv)Ef3w{zFw?JoeyqjuVHS(uBlnv`}^Yy|Xg}W`z z4{hJ$W=XG}-OcH=`P};u68}bU+PBazD1RpstJ(~`UjG_{5ly+e1h;HZhA}9=vA-+a zLi{qP`+dc<-+%i2$9;TWKebW@V|LY_NWLa3nfLlv)J#eaESf-@o=rZ=>E_tJukvM9 zBgJdy64eH~&vLY`fxYuqM#v}m!&5vp8e;iuw>I9ULFsi(pf%f2dv&zP+X)Ho+u*sX zM^j4v`1YdX$n%CLMaEAAzV8br@k*;zH;7F3R#wL-Nle4KY?y|e|iW!Iz< zQ=#WOO_MEJW~cp)$UUb}KCCHvGkCjei=sUv3EjpubNmPZeqoIAEpP4N-$o%=H1=$h z9WLhyy$XqteElM>nQ=--nhDSY;k0B*6Vfg9PX; znlaSOR=KHrn+LOqa6k{WWM%ZIpMbk_H52E3{w*(tK?{}*`;b94ove2Yt{#3Qw^4+8 zk(yTT-o66>Ir9qJ^Z#0v|4ej$ByUT{Of`6g@svw)5D1vNPaPjW;y$4)%K@z02!BF7 z=VB3#poQG3wZrh-bH|a%pLL7j&;`F-i{;B~iyrckrz-O^ErP39K{#KsPFvTSGCR@; zIv8cO&MyA;EgdBQ{O9RcorXk5=2P??IIxfcSzriMuK^BcyDV~9zL!xVC9uDc@4vQU z&-HfrI3mIlwi0tmz`8Rf=F|_PYzSkKbAT9jO3`?X@r;NMEMe={XDx zlJN8X@)($m&h!5qEh~N)k=hLrrI2jCakrc(+}Q*iBYl15E@b64=cTQ0R)#cTZXiQw zZ|!?7wEsG$0_?*ScvPOPrR2)0iETOJal6nlbLy^Qmyt!F_2)CCa4P8Qf;3EnIr}yI zNc7>+mectgCNaO!qHFSlp3d?)(inq#f73i$Ybml5xoQG0?Y1ZV5-A1JeO|+VR@qD#ukGqtc~Uit|*Z`?gqt$El^>TVpTN+fG%Ug3gY^ z`udP!txYvC47k;tb}`K&AIQQTUiN?n?p#N$nt=FgQ&#`Um{{O(nRW!T_#~doT=vb>2G=2BdowsvF-+c7>GAF3}5jLWl_iK{iE`b^c#;K7cL0G04U{ zni2y*XTqTxJhUl|%1if+%YQCteMin^<;{pWS;c&|YKe=%pcZuJ)-H>@#oQSisWcIj=aZAsx3?k3UtvEzmb#{sDEeetgwC+2Z;a?!xAytU z_eyP+i1Dq{N2FhZ1C$x2oNW{ezdk1O4DJxv7}?(RTufhjkF#g|NA`z|QK5DDyjqvy zwr+%m)ph`xnM8}byohi1E0PKK*smkj;r4|Z*9p#;5Q(9b@Wny151A(Zwufi6Xq@lyj6c@R4m^< zk*28FNvc4o}y)m}e0sMOg^G4BN1dH?~FYxq1Cv%zhekTo8RY|&6WvrO9EDej}CXlFT zpUe7?MujhN{vrVYo^~d>*~Oly3OB>4^8>pomjWAg`~U@;=`q-m+I!ZP85%dOMO%tC4N!xw;H{0Uc`tP^z#h-I} z7)eCZ5*oK4s!AN>bfS8mI=fq_g_!8CAtIwMG1))pZ=;=o^}gQ@M$M@Z4}b7jfG7gZ4u}VuWHEqJ;nnVZCI5c9Z9mA9lGsE$+ZrQ%z9)=ix4kh8$BW)`=E{MgXWM8ccpf|WwDGn-r zwOmK$Pb})TZGR7I0J~hC{IJ>Rx~2gD%-!OgJG zXRY5_Twlx1A$W0)4nWY{?9QZ%i0EdzIS=t;%r1&THBTkxDe5nQnu)#G3*%;NfcEPs zLs`-@M`{9y#%uGn#>aSuGLbbxZ`{#y*YIc)d{RGOGKYr(*@`vi2vO|~*xGkkrtClj zTU`aa4E?y>V)ujvTf3C_#?VLAZLKL$Op~1*5HuQIH%l2`QaAgcbOp$B>~7-Pfj~mXBa_@urOi<+Y3KY}=8$toN`s?SeyYHr zKOc!R&j_1Boxs@5tv7rX1VGqiJIlpPZU2|qs9V>*;cv9fb*$&TB75rc9x2{&2Ia_qRO=?y2=?Zntdzz*cu#Y`X-EhCNZ{lKB$t0nuy&X!4R4UfF*IRE3Lo0_BOttPjhtPHGS zu74LD_lUQpB@mm{)6JqHV&v;HBU$=-cwo}4UOh8cf}+h;c8N#xAgaO&6YRvw7~=)o z0TT?%u;6j5IuP)ymb z)qi_2Q8s${_3ka`?7ysfH%%y~Gxlrpx@CfshKy{kS>4psRLbV_i~_h$Me3;GxDjj~ z+_3%4@F*%2=5vU|+@)JQpcsD|xr6QKUIF`LO1T)*_sC37Qo3N*Y6>AT?TV9oiEMS@ zi1x&khbiNY!E@b-59a+&gHoRYV;_WmIi9o4bE{Cjduet*jtds8OQ=7T_aFYhpzv}U z7SeKQpIff#onoC&_f{TIgur-`O{0lxJwc5z4X_dQg#14 zUe7i#(1f`S62K7vvlR1DB8*QQ8hvJejV2+)xDF&nciQ4L4dSz1#;tZI7B`E2=<~$* zNu)}Hi96?Zr;o6u%z)?n2MQtc9O|+D(AmyiQyk<;rp#4wqb|WIBxAKwgt>Yjem0z5 zLltm{w`!fAo+ibXw1I9utQN?*wYFw;!z}XhOR@jb;k^d5K*vLRgjj`LG03iSj13IC z`Lo$SQhRHSt1h?lLS!|)nVsN*sZZWY&`W+;yRhDV_WBczguv~kCjzd-hx!N#+(QU@ zl^8^V)rhw({2kgtI5)jQvOJ(6vrE)oKdC4K>otgvRwc44`fJEEXjrMQMq{gF`KVcB zauFr-ty5@q$}zpdo!^D2>kYyd23&v;mk5~MRtVC}VB{$@QZ70DdAMbTr+v=u_RpJk zx6G-5cq6Vi-f!G5IHmOWQXg!Ep2G)Omjkln6TCK)5#rx8{SfbLC!Ut{!9XnMvq48V zN2$?#d#rvX1S*0DnA1Czpe-%Jypk%I(ttLyL*mPBI0w9Z{i2J%zDmrE)b+#Q8w)JDC#E`rNc07fy zN3KNy7j6p%0YgIgiN?q}0BrR}CrZ1`u)9BHc`hTdesV=&&<+5!1^@E`XvI)m8J$qx zgUJb3z2&=57FMk*%Es_}Z6qc;y?sy}!*3P%^4`pVxRW#JCGY2@KNpPASU(#@-E+ddxsS3W)eBoyLL~o`G&)b-PK?}o|cIXJJygw03Y%#TU)Fe@o{T%P)q;I{rDX` zh#$Z6-6|h6CwoBU-+MmOk!r+%6cTT^z>!Xl*PtSHg@m}9uujlxTX29_mEQiAi+`FN zsIKkrVsv_z3O);edFTOUANq9}&{tCLA$@NAJy5uy%Je+;awhR45c{cj`Kv3%Y=fHw zWFUnd61gS3e3SMijd)(B^2+oC{M1tmQf+^ldq4$!vC`k`6KLlB_r1aPN-Eb*&wScN zPXbumc=D!__W9c1LxX@v1b^S$yfrrboQ! z?%~DvEq(7bpR1vHRh&k-`4|+GDYhBhdGD7Q#kba#LAd}o`UmjQqRGa+ z{WWFg?F|m@lul6wNH1;dhN2IQW^*Ayn}Kjm_LuiF4z6!RBe)m9>vfH0SXvVyv}xq9wYp z;6CRUVcj8rpCV_xRT;&E8ALK$X>H#MX87P*Wq0 zvwgCX@qGIVWkSFrN~rx&k(~A4LQr5O38xe2AGTNxh#e5!9q)hidZysvLZy9!Zv-)L z{T=Zl#RD_J1lMXh{Jzdw;^?3NM`4ngU_aU0I~0`-iCkioSC4m{ax3a;pfg z_wUVl%#3U|Ta~n~!I*=|lZ8OL<{>?~3hzGgTSPoLAaBIwH%f$x-~q31Bt926knz4& z=O?WL`JY{q+anKO>%N>+V~#aSeAHO72N8|=JYW#UdU%w)LNTcL8~`M~-tAX1H4#jg zc+;+J7>2p8duFPNFge}#uv&d+oqCbkWWO8>!PPQm|Ly+LY)J7Tu(0&s2c5ppc5yWG zZrhV?Obj=2_7)q-%g?=-Pj!gZfRHLvOzY;g@&Hcac^j*1I1^ zCQ7_M-&CRddKu?cG+6w^1?KOT(=e71{g%6g3+xpbS$J$0s{TVW?=keJ9{J3$PD?sQ z7SS0EClguwUAURIq^+bref>6^il02!EpV-iL{0nq$;Q1_!hm*5CRL!bv@;7>?Jcoq ziJ4_GkerEwV%1ghJJBO9W@KvwK`R5jebQ}#@mrZ1ImH-NmVyhuDGWHF2`QG}H=DMr z`Rs+%b68Sy6%RXWvJl~CMLY>7^gRU}lP`I{$CCxhn?0~OF?nqPZh4!WnZ)n~dvd5ZKm<2cEdMQ+9nup4q#rij@5(|V+4fiO;$0#Dwo)H5;kehJ(bz3zp` zk#EYFfXsXzJa}LgaHJfJ=iJmdu9hPN@oE9z+$NV{Bn44hzVE*I(Ws}hm>kU5*x1f) z{d8*_Yi3BSkZ^f(GJ+2{ba!=4y*BxB*7^(6P*y>=g&xZCFS^`#CffB5$ws13Y5bz9 zs>6iiG^EG$k{#+ONh4OR^_FVwO0D2U_Tm70&Mo@R_$dNKI8$kV3< zir?;r!#*b8idsIGK1ZAml=a^oa!PvlbcMBG**;=%8VNOW7awICS5S@ zLvvY2=0WPlWoam%gOqMnR`v769ZGXPBmRt$-0>~7UBjTeim}1~+EQNM{#DqxgGuY; zzrWKTit3=?y9azX(iJ@J`zt>3RhD#o+DAHX;_}9~9#MwQRB?bfmQVc7@W7+|VJ{@} z8TgY;td+?8Gt2{n(~URb;KQ~v;)mwt0{woF@rXS{>2nL4E0{ z?z0Z&mf{5q;UZ1Sl`D9<{;-_9QEaVgWsY#+l?yWVw$~m-oACWmO{e$#{YSQGVGA7@ zwuP?fW%A*ym`lo(ehR!`hu8;Y?WU*etn{=w+Ay1{U0PHEMyUXf>#z8pUBfb*;X=hT&&$Xa?+S6lby^FD~ znqRiI=PprPYGYhZ4$K!Bhn%@Fxx9h-D76VgKEB9~H?jORD&u^brKeqxkhrc(8AmRk zYWElmz=%E$UP+Kq)@xf}&G_4GOSR58hM(T-egG#0Z@h!dPtx?=pdZhtJPl#Y_X55o zx}^HRXZ{D-vz1g9q2=V2dsQrNR6Ebk>E2Niy)iOhoWE01#g>73hiNK1xFlyF<|X?5 zm9tUB%(4C$<+E$u6tF^X@O2P&D*mlHbFuR>!_-dfXStJ(B#m?PAJ1A4pBVtq?DVg@ zlN5xOGVClFv*{&K8+1KG{x~|JH}DI;Cye%^ERxWc);)LWe6fX=HtHy*`bE9vO62p< zW}ME`6t(1Dsb5=rQSxv{_h^hP8eW=c663|5brxIwE$4+yLuSq*9fjHqYZ~G6Z2WB` z9boW9(Ess#aSP$pS|mO5@oJjQ-LJz}WXu^wBzC4sV-UJp{Q0;$ z$zJ~~QAd>~7HfTyo9y1QP$oaN9arOh639LozZHYE8uQ5#=FIXyevq%a7{E}b{J5t; zy_rs0Dv5$DI!gWT7>nG5+bE*RcUoHB&Yal0<_F&i64%Rq78%>2_2hTR)q~Sa#T2;l z&mW=bFN!O<7yiDRvXFqjB+-mT=AB@@2BS{|3Ijm63q?Z0lbt0(+S6iQFv|4mta4|g zp~BdpGwpKN40J7w(l_7`lnee(Rk~W>l?}j=v=NPb-&C}$1)&p784hZ;Nz_3Xmj>&FRRF>yn zUb**THiA%}u7-*Exxr1*isdt)VkG=X$#*fm8gN~W&KpZak1 zI8v=4dcf}rf`=_*T@GXwv5ws6s0skBMc?mu420fs^F<%dr5%z&m<{)QZRgI z^2UaH1CK+Bf)6L9jcgp_C8I6g?LBS5QKnpw1^snrb5g1o;d{9P32_=R5<(FTu?a9! z^F}?}4)O`lIgsZ?>6=qGZpKg%T|NGZ<~&e9*1BE{E49{V=B(77#FPABnW0TsmIg+f zZihrzJ*dK$`FVHa>xGYk?aJ;{EEDZ6aoW%FMMtC5@mKHk;Xy$sPVgh>#Z?W_1Qgj z#0}mzQi~p__$AlMA&IW+68NnsL*925+adq-UR_7HMM23jv@cb|#Z-x5|H$koz5Gh< zh*Nj6Tk7YusEfyGYNc=Yyk*{5CaEH6@b4Eh{lHw`d9mmRS^V4eUAHFF49k11?M|^w z2RiN!2+uGV?elxq5+XS!2;*0CkJ^1Tz$59VNl*dTAXc?}sVrPGG7&QV<;iAlh&87E zW-;T1%qlc=1y5SP9(x+Tub=Ll*dHxGBw~TTD?y$EA@G)WL%$JlSEH)0H~Vz=*>Uvl zJqTa&yW3dvcaXY}otC_gk8hf3mL*cHTQ z)G=Q0)oWFx0+s}C5W9Pql6Uqn@F%n<)S_&7icZdPeDnP8{j68;d+G)8^b;=48<#uf zIg8uUhTb<|n@{kvkx~z+i*O_IOHj-KaX$V@rD7cQQIpTvlw(c~UVjKD6-FQ3>zLB| zMA5N@IE-F7I!G%ZcD)XXxkK`_EEo1mb0Z*;4IlCTIcsP`kfD;yU|!w_p?%d8O7nVv zhM7(Gexor(@SWv&t;+$@v&%7g!;tFF$N74*KM7Zo?L};=r}C2?c$MP1W0)&*iPrE#%k!5Z|9MuEsL#Dg`rFx>rqmUZ?Z5PKFQ8H zrcVc7l}cA#&9}BxlGocbqW-B-t4#+?XoizrNBtcX{M=Aft-99>N^Q`OCJ2Rnla7GoM&A z`)znMR=)`2M}+uR9i6rQdXm&sKB=8x@uke1FLcUJHFW(g?t0}cGY8R@?wai#pRhm3 zGsw**zvWwa-5Oc6h@YrcS5z!B(~%Ue+cvCS6p01c%8t^(XK`16*3pv5G>cO3Npa3C z9nQ#H9&eJ1cL(cwcQpO5h;7o;b+3LlvWLqmZpx`=D~gB_&r0=q^u?&fwfB&aGbXLpLO z4qn9n#p#)9RIgMt{Ui2|fBFAT4Cvt#Jh^)hdK@Ca?^lEuBYO)E30TvL+LU{QF|l2E z0eH=rtj_jCNa=SQsPQ7CH~?W-uc%!7F-4nSng4-;I&V15SY`Hy!~CZTzlP_YgI(6b z2lUMhXL-Sg!Dk(e%S7~jege`upNf`I^bzGLA&+gz8w!ZH#~d_t%wSo|3eTRdDLgQy zy8B#iQKl$GRfxo3Zo|(w^cvqyv-LujWXXzT-x&o}$uzXAa3E{h=oAC8*vkAQ^s_I`_V`QaA1V+MgGn!K*kvCb z=->Rk70ZK+6noG{GjK~gBIWsfbQOA5zJ75)d}xaEq;%=FZ5i{h3g_!gGHEn}oY p@Ik0y-ev?d#;kmneRj)!PRi-=nmgPD|1~e*jk5OZ3dMIJ{|9&!h#&v} literal 0 HcmV?d00001 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/scenegraph/openglunderqml/main.cpp b/examples/quick/scenegraph/openglunderqml/main.cpp new file mode 100644 index 0000000..223f8bf --- /dev/null +++ b/examples/quick/scenegraph/openglunderqml/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 "squircle.h" + +//! [1] +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("OpenGLUnderQML", 1, 0, "Squircle"); + + QQuickView view; + view.setSource(QUrl("main.qml")); + view.show(); + + return app.exec(); +} +//! [1] diff --git a/examples/quick/scenegraph/openglunderqml/main.qml b/examples/quick/scenegraph/openglunderqml/main.qml new file mode 100644 index 0000000..1823d2a --- /dev/null +++ b/examples/quick/scenegraph/openglunderqml/main.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** 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 OpenGLUnderQML 1.0 + +Item { + + width: 320 + height: 480 + + Squircle { + SequentialAnimation on t { + NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad } + NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad } + loops: Animation.Infinite + running: true + } + } +//! [1] //! [2] + Rectangle { + color: Qt.rgba(1, 1, 1, 0.7) + radius: 10 + border.width: 1 + border.color: "white" + anchors.fill: label + anchors.margins: -10 + } + + Text { + id: label + color: "black" + wrapMode: Text.WordWrap + text: "The background here is a squircle rendered with raw OpenGL using the 'beforeRender()' signal in QQuickWindow. This text label and its border is rendered using QML" + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 20 + } +} +//! [2] diff --git a/examples/quick/scenegraph/openglunderqml/openglunderqml.pro b/examples/quick/scenegraph/openglunderqml/openglunderqml.pro new file mode 100644 index 0000000..64a58b3 --- /dev/null +++ b/examples/quick/scenegraph/openglunderqml/openglunderqml.pro @@ -0,0 +1,6 @@ +QT += qml quick + +HEADERS += squircle.h +SOURCES += squircle.cpp main.cpp + +OTHER_FILES += main.qml diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp new file mode 100644 index 0000000..f7bbeb9 --- /dev/null +++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** 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 "squircle.h" + +#include +#include +#include + +//! [7] +Squircle::Squircle() + : m_program(0) +{ +} +//! [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 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) { + m_program = new QOpenGLShaderProgram(); + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, + "attribute highp vec4 vertices;" + "varying highp vec2 coords;" + "void main() {" + " gl_Position = vertices;" + " coords = vertices.xy;" + "}"); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, + "uniform lowp float t;" + "varying highp vec2 coords;" + "void main() {" + " lowp float i = 1. - (pow(coords.x, 4.) + pow(coords.y, 4.));" + " 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); + + float values[] = { + -1, -1, + 1, -1, + -1, 1, + 1, 1 + }; + m_program->setAttributeArray(0, GL_FLOAT, values, 2); + m_program->setUniformValue("t", (float) m_t); + + glViewport(0, 0, window()->width(), window()->height()); + + glDisable(GL_DEPTH_TEST); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + 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/scenegraph/openglunderqml/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h new file mode 100644 index 0000000..43b0022 --- /dev/null +++ b/examples/quick/scenegraph/openglunderqml/squircle.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 SQUIRCLE_H +#define SQUIRCLE_H + +#include +#include + +//! [1] +class Squircle : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged) + +public: + Squircle(); + + qreal t() const { return m_t; } + 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; +}; +//! [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} */ /*! -- 1.7.2.5