aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-06-06 16:53:33 +0200
committerLaszlo Agocs <laszlo.agocs@digia.com>2014-06-19 20:55:57 +0200
commit2bc44ba16bb86bd7ebc7eb59ae78eda80a737984 (patch)
tree5000e2f744b0f61a0f9f4eeb2cfed5306dde1772 /examples/quick
parenta560018d08d4212bc65c163eb608639f19b38df2 (diff)
Add a QQuickWidget - QQuickView comparison example
Besides serving as a side-by-side test tool for QQuickView and QQuickWidget (including multisampling), it also demonstrates some useful practices for rendering 3D content via QQuickFramebufferObject. Done-with: Paul Olav Tvete <paul.tvete@digia.com> Change-Id: Ie73e998ee91e32ef1535dd6f0f65c8a69addcc5e Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'examples/quick')
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp273
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.h136
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/logo.cpp141
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/logo.h65
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/main.cpp56
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp216
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h80
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro17
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc5
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/test.qml210
-rw-r--r--examples/quick/quickwidgets/quickwidgets.pro3
11 files changed, 1201 insertions, 1 deletions
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
new file mode 100644
index 0000000000..3b9f2e97f3
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fbitem.h"
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+
+FbItem::FbItem(QQuickItem *parent)
+ : QQuickFramebufferObject(parent),
+ m_target(0, 0, -1),
+ m_syncState(AllNeedsSync),
+ m_multisample(false)
+{
+}
+
+QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
+{
+ return new FbItemRenderer(m_multisample);
+}
+
+void FbItem::setEye(const QVector3D &v)
+{
+ if (m_eye != v) {
+ m_eye = v;
+ m_syncState |= CameraNeedsSync;
+ update();
+ }
+}
+
+void FbItem::setTarget(const QVector3D &v)
+{
+ if (m_target != v) {
+ m_target = v;
+ m_syncState |= CameraNeedsSync;
+ update();
+ }
+}
+
+void FbItem::setRotation(const QVector3D &v)
+{
+ if (m_rotation != v) {
+ m_rotation = v;
+ m_syncState |= RotationNeedsSync;
+ update();
+ }
+}
+
+int FbItem::swapSyncState()
+{
+ int s = m_syncState;
+ m_syncState = 0;
+ return s;
+}
+
+FbItemRenderer::FbItemRenderer(bool multisample)
+ : m_inited(false),
+ m_multisample(multisample),
+ m_dirty(DirtyAll)
+{
+ m_camera.setToIdentity();
+ m_baseWorld.setToIdentity();
+ m_baseWorld.translate(0, 0, -1);
+ m_world = m_baseWorld;
+}
+
+void FbItemRenderer::synchronize(QQuickFramebufferObject *qfbitem)
+{
+ FbItem *item = static_cast<FbItem *>(qfbitem);
+ int syncState = item->swapSyncState();
+ if (syncState & FbItem::CameraNeedsSync) {
+ m_camera.setToIdentity();
+ m_camera.lookAt(item->eye(), item->eye() + item->target(), QVector3D(0, 1, 0));
+ m_dirty |= DirtyCamera;
+ }
+ if (syncState & FbItem::RotationNeedsSync) {
+ m_rotation = item->rotation();
+ m_dirty |= DirtyWorld;
+ }
+}
+
+struct StateBinder
+{
+ StateBinder(FbItemRenderer *r)
+ : m_r(r) {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glEnable(GL_DEPTH_TEST);
+ f->glEnable(GL_CULL_FACE);
+ f->glDepthMask(GL_TRUE);
+ f->glDepthFunc(GL_LESS);
+ f->glFrontFace(GL_CCW);
+ f->glCullFace(GL_BACK);
+ m_r->m_program->bind();
+ }
+ ~StateBinder() {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ m_r->m_program->release();
+ f->glDisable(GL_CULL_FACE);
+ f->glDisable(GL_DEPTH_TEST);
+ }
+ FbItemRenderer *m_r;
+};
+
+void FbItemRenderer::updateDirtyUniforms()
+{
+ if (m_dirty & DirtyProjection)
+ m_program->setUniformValue(m_projMatrixLoc, m_proj);
+
+ if (m_dirty & DirtyCamera)
+ m_program->setUniformValue(m_camMatrixLoc, m_camera);
+
+ if (m_dirty & DirtyWorld) {
+ m_program->setUniformValue(m_worldMatrixLoc, m_world);
+ QMatrix3x3 normalMatrix = m_world.normalMatrix();
+ m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
+ }
+
+ if (m_dirty & DirtyLight)
+ m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
+
+ m_dirty = 0;
+}
+
+void FbItemRenderer::render()
+{
+ ensureInit();
+
+ QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
+ if (!m_vao.isCreated())
+ setupVertexAttribs();
+
+ StateBinder state(this);
+
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glClearColor(0, 0, 0, 0);
+ f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (m_dirty & DirtyWorld) {
+ m_world = m_baseWorld;
+ m_world.rotate(m_rotation.x(), 1, 0, 0);
+ m_world.rotate(m_rotation.y(), 0, 1, 0);
+ m_world.rotate(m_rotation.z(), 0, 0, 1);
+ }
+
+ updateDirtyUniforms();
+
+ f->glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
+}
+
+QOpenGLFramebufferObject *FbItemRenderer::createFramebufferObject(const QSize &size)
+{
+ m_dirty |= DirtyProjection;
+ m_proj.setToIdentity();
+ m_proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
+
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ format.setSamples(m_multisample ? 4 : 0);
+ return new QOpenGLFramebufferObject(size, format);
+}
+
+void FbItemRenderer::ensureInit()
+{
+ if (m_inited)
+ return;
+
+ m_inited = true;
+
+ initBuf();
+ initProgram();
+}
+
+void FbItemRenderer::initBuf()
+{
+ m_vao.create();
+ QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
+
+ m_logoVbo.create();
+ m_logoVbo.bind();
+ m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
+
+ setupVertexAttribs();
+}
+
+void FbItemRenderer::setupVertexAttribs()
+{
+ m_logoVbo.bind();
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glEnableVertexAttribArray(0);
+ f->glEnableVertexAttribArray(1);
+ f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
+ f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
+ m_logoVbo.release();
+}
+
+static const char *vertexShaderSource =
+ "attribute vec4 vertex;\n"
+ "attribute vec3 normal;\n"
+ "varying vec3 vert;\n"
+ "varying vec3 vertNormal;\n"
+ "uniform mat4 projMatrix;\n"
+ "uniform mat4 camMatrix;\n"
+ "uniform mat4 worldMatrix;\n"
+ "uniform mat3 normalMatrix;\n"
+ "void main() {\n"
+ " vert = vertex.xyz;\n"
+ " vertNormal = normalMatrix * normal;\n"
+ " gl_Position = projMatrix * camMatrix * worldMatrix * vertex;\n"
+ "}\n";
+
+static const char *fragmentShaderSource =
+ "varying highp vec3 vert;\n"
+ "varying highp vec3 vertNormal;\n"
+ "uniform highp vec3 lightPos;\n"
+ "void main() {\n"
+ " highp vec3 L = normalize(lightPos - vert);\n"
+ " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
+ " highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
+ " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
+ " gl_FragColor = vec4(col, 1.0);\n"
+ "}\n";
+
+void FbItemRenderer::initProgram()
+{
+ m_program.reset(new QOpenGLShaderProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->bindAttributeLocation("vertex", 0);
+ m_program->bindAttributeLocation("normal", 1);
+ m_program->link();
+ m_projMatrixLoc = m_program->uniformLocation("projMatrix");
+ m_camMatrixLoc = m_program->uniformLocation("camMatrix");
+ m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
+ m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
+ m_lightPosLoc = m_program->uniformLocation("lightPos");
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
new file mode 100644
index 0000000000..b29998c253
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FBITEM_H
+#define FBITEM_H
+
+#include <QQuickFramebufferObject>
+#include <QOpenGLVertexArrayObject>
+#include <QOpenGLBuffer>
+#include <QOpenGLShaderProgram>
+#include <QVector3D>
+#include "logo.h"
+
+struct StateBinder;
+
+class FbItemRenderer : public QQuickFramebufferObject::Renderer
+{
+public:
+ FbItemRenderer(bool multisample);
+ void synchronize(QQuickFramebufferObject *item) Q_DECL_OVERRIDE;
+ void render() Q_DECL_OVERRIDE;
+ QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) Q_DECL_OVERRIDE;
+
+private:
+ void ensureInit();
+ void initBuf();
+ void setupVertexAttribs();
+ void initProgram();
+ void updateDirtyUniforms();
+
+ bool m_inited;
+ bool m_multisample;
+ QMatrix4x4 m_proj;
+ QMatrix4x4 m_camera;
+ QMatrix4x4 m_baseWorld;
+ QMatrix4x4 m_world;
+ QOpenGLVertexArrayObject m_vao;
+ QOpenGLBuffer m_logoVbo;
+ Logo m_logo;
+ QScopedPointer<QOpenGLShaderProgram> m_program;
+ int m_projMatrixLoc;
+ int m_camMatrixLoc;
+ int m_worldMatrixLoc;
+ int m_normalMatrixLoc;
+ int m_lightPosLoc;
+ QVector3D m_rotation;
+
+ enum Dirty {
+ DirtyProjection = 0x01,
+ DirtyCamera = 0x02,
+ DirtyWorld = 0x04,
+ DirtyLight = 0x08,
+ DirtyAll = 0xFF
+ };
+ int m_dirty;
+
+ friend struct StateBinder;
+};
+
+class FbItem : public QQuickFramebufferObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector3D eye READ eye WRITE setEye)
+ Q_PROPERTY(QVector3D target READ target WRITE setTarget)
+ Q_PROPERTY(QVector3D rotation READ rotation WRITE setRotation)
+ Q_PROPERTY(bool multisample READ multisample WRITE setMultisample)
+
+public:
+ explicit FbItem(QQuickItem *parent = 0);
+
+ QQuickFramebufferObject::Renderer *createRenderer() const Q_DECL_OVERRIDE;
+
+ QVector3D eye() const { return m_eye; }
+ void setEye(const QVector3D &v);
+ QVector3D target() const { return m_target; }
+ void setTarget(const QVector3D &v);
+
+ QVector3D rotation() const { return m_rotation; }
+ void setRotation(const QVector3D &v);
+
+ enum SyncState {
+ CameraNeedsSync = 0x01,
+ RotationNeedsSync = 0x02,
+ AllNeedsSync = 0xFF
+ };
+ int swapSyncState();
+
+ bool multisample() const { return m_multisample; }
+ void setMultisample(bool m) { m_multisample = m; }
+
+private:
+ QVector3D m_eye;
+ QVector3D m_target;
+ QVector3D m_rotation;
+ int m_syncState;
+ bool m_multisample;
+};
+
+#endif // FBITEM_H
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp b/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp
new file mode 100644
index 0000000000..1ba47ddfb5
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "logo.h"
+#include <qmath.h>
+
+Logo::Logo()
+ : m_count(0)
+{
+ m_data.resize(2500 * 6);
+
+ const GLfloat x1 = +0.06f;
+ const GLfloat y1 = -0.14f;
+ const GLfloat x2 = +0.14f;
+ const GLfloat y2 = -0.06f;
+ const GLfloat x3 = +0.08f;
+ const GLfloat y3 = +0.00f;
+ const GLfloat x4 = +0.30f;
+ const GLfloat y4 = +0.22f;
+
+ quad(x1, y1, x2, y2, y2, x2, y1, x1);
+ quad(x3, y3, x4, y4, y4, x4, y3, x3);
+
+ extrude(x1, y1, x2, y2);
+ extrude(x2, y2, y2, x2);
+ extrude(y2, x2, y1, x1);
+ extrude(y1, x1, x1, y1);
+ extrude(x3, y3, x4, y4);
+ extrude(x4, y4, y4, x4);
+ extrude(y4, x4, y3, x3);
+
+ const int NumSectors = 100;
+
+ for (int i = 0; i < NumSectors; ++i) {
+ GLfloat angle = (i * 2 * M_PI) / NumSectors;
+ GLfloat angleSin = qSin(angle);
+ GLfloat angleCos = qCos(angle);
+ const GLfloat x5 = 0.30f * angleSin;
+ const GLfloat y5 = 0.30f * angleCos;
+ const GLfloat x6 = 0.20f * angleSin;
+ const GLfloat y6 = 0.20f * angleCos;
+
+ angle = ((i + 1) * 2 * M_PI) / NumSectors;
+ angleSin = qSin(angle);
+ angleCos = qCos(angle);
+ const GLfloat x7 = 0.20f * angleSin;
+ const GLfloat y7 = 0.20f * angleCos;
+ const GLfloat x8 = 0.30f * angleSin;
+ const GLfloat y8 = 0.30f * angleCos;
+
+ quad(x5, y5, x6, y6, x7, y7, x8, y8);
+
+ extrude(x6, y6, x7, y7);
+ extrude(x8, y8, x5, y5);
+ }
+}
+
+void Logo::add(const QVector3D &v, const QVector3D &n)
+{
+ GLfloat *p = m_data.data() + m_count;
+ *p++ = v.x();
+ *p++ = v.y();
+ *p++ = v.z();
+ *p++ = n.x();
+ *p++ = n.y();
+ *p++ = n.z();
+ m_count += 6;
+}
+
+void Logo::quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4)
+{
+ QVector3D n = QVector3D::normal(QVector3D(x4 - x1, y4 - y1, 0.0f), QVector3D(x2 - x1, y2 - y1, 0.0f));
+
+ add(QVector3D(x1, y1, -0.05f), n);
+ add(QVector3D(x4, y4, -0.05f), n);
+ add(QVector3D(x2, y2, -0.05f), n);
+
+ add(QVector3D(x3, y3, -0.05f), n);
+ add(QVector3D(x2, y2, -0.05f), n);
+ add(QVector3D(x4, y4, -0.05f), n);
+
+ n = QVector3D::normal(QVector3D(x1 - x4, y1 - y4, 0.0f), QVector3D(x2 - x4, y2 - y4, 0.0f));
+
+ add(QVector3D(x4, y4, 0.05f), n);
+ add(QVector3D(x1, y1, 0.05f), n);
+ add(QVector3D(x2, y2, 0.05f), n);
+
+ add(QVector3D(x2, y2, 0.05f), n);
+ add(QVector3D(x3, y3, 0.05f), n);
+ add(QVector3D(x4, y4, 0.05f), n);
+}
+
+void Logo::extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ QVector3D n = QVector3D::normal(QVector3D(0.0f, 0.0f, -0.1f), QVector3D(x2 - x1, y2 - y1, 0.0f));
+
+ add(QVector3D(x1, y1, +0.05f), n);
+ add(QVector3D(x1, y1, -0.05f), n);
+ add(QVector3D(x2, y2, +0.05f), n);
+
+ add(QVector3D(x2, y2, -0.05f), n);
+ add(QVector3D(x2, y2, +0.05f), n);
+ add(QVector3D(x1, y1, -0.05f), n);
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/logo.h b/examples/quick/quickwidgets/qquickviewcomparison/logo.h
new file mode 100644
index 0000000000..29bb7fa241
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/logo.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOGO_H
+#define LOGO_H
+
+#include <qopengl.h>
+#include <QVector>
+#include <QVector3D>
+
+class Logo
+{
+public:
+ Logo();
+ const GLfloat *constData() const { return m_data.constData(); }
+ int count() const { return m_count; }
+ int vertexCount() const { return m_count / 6; }
+
+private:
+ void quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4);
+ void extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+ void add(const QVector3D &v, const QVector3D &n);
+
+ QVector<GLfloat> m_data;
+ int m_count;
+};
+
+#endif // LOGO_H
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
new file mode 100644
index 0000000000..5f006c3fb6
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char **argv)
+{
+ qputenv("QML_BAD_GUI_RENDER_LOOP", "1"); // QTBUG-39507
+
+ QApplication app(argc, argv);
+
+ MainWindow widgetWindow;
+ widgetWindow.resize(1024, 768);
+ widgetWindow.show();
+
+ return app.exec();
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
new file mode 100644
index 0000000000..dbf4121518
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "fbitem.h"
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QLabel>
+#include <QQuickItem>
+
+MainWindow::MainWindow()
+ : m_currentView(0),
+ m_currentRootObject(0)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+
+ QGroupBox *groupBox = new QGroupBox(tr("Type"));
+ QVBoxLayout *vbox = new QVBoxLayout;
+ m_radioView = new QRadioButton(tr("QQuickView in a window container (direct)"));
+ m_radioWidget = new QRadioButton(tr("QQuickWidget (indirect through framebuffer objects)"));
+ vbox->addWidget(m_radioView);
+ vbox->addWidget(m_radioWidget);
+ m_radioView->setChecked(true);
+ connect(m_radioView, &QRadioButton::toggled, this, &MainWindow::updateView);
+ connect(m_radioWidget, &QRadioButton::toggled, this, &MainWindow::updateView);
+ groupBox->setLayout(vbox);
+
+ layout->addWidget(groupBox);
+
+ m_checkboxMultiSample = new QCheckBox(tr("Multisample (4x)"));
+ connect(m_checkboxMultiSample, &QCheckBox::toggled, this, &MainWindow::updateView);
+ layout->addWidget(m_checkboxMultiSample);
+
+ m_labelStatus = new QLabel;
+ layout->addWidget(m_labelStatus);
+
+ qmlRegisterType<FbItem>("fbitem", 1, 0, "FbItem");
+
+ QWidget *quickContainer = new QWidget;
+ layout->addWidget(quickContainer);
+ layout->setStretchFactor(quickContainer, 8);
+ m_containerLayout = new QVBoxLayout;
+ quickContainer->setLayout(m_containerLayout);
+
+ // Add an overlay widget to demonstrate that it will _not_ work with
+ // QQuickView, whereas it is perfectly fine with QQuickWidget.
+ QPalette semiTransparent(QColor(255,0,0,128));
+ semiTransparent.setBrush(QPalette::Text, Qt::white);
+ semiTransparent.setBrush(QPalette::WindowText, Qt::white);
+
+ m_overlayLabel = new QLabel("This is a\nsemi-transparent\n overlay widget\nwhich is placed\non top\n of the Quick\ncontent.", this);
+ m_overlayLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
+ m_overlayLabel->setAutoFillBackground(true);
+ m_overlayLabel->setPalette(semiTransparent);
+ QFont f = font();
+ f.setPixelSize(QFontInfo(f).pixelSize()*2);
+ f.setWeight(QFont::Bold);
+ m_overlayLabel->setFont(f);
+ m_overlayLabel->hide();
+
+ m_checkboxOverlayVisible = new QCheckBox(tr("Show widget overlay"));
+ connect(m_checkboxOverlayVisible, &QCheckBox::toggled, m_overlayLabel, &QWidget::setVisible);
+ layout->addWidget(m_checkboxOverlayVisible);
+
+ setLayout(layout);
+
+ updateView();
+}
+
+void MainWindow::resizeEvent(QResizeEvent*)
+{
+ int margin = width() / 10;
+ int top = m_checkboxMultiSample->y();
+ int bottom = m_checkboxOverlayVisible->geometry().bottom();
+ m_overlayLabel->setGeometry(margin, top, width() - 2 * margin, bottom - top);
+}
+
+void MainWindow::switchTo(QWidget *view)
+{
+ if (m_containerLayout->count())
+ m_containerLayout->takeAt(0);
+
+ delete m_currentView;
+ m_currentView = view;
+ m_containerLayout->addWidget(m_currentView);
+ m_currentView->setFocus();
+}
+
+void MainWindow::updateView()
+{
+ QString text = m_currentRootObject
+ ? m_currentRootObject->property("currentText").toString()
+ : QStringLiteral("Hello Qt");
+
+ QUrl source("qrc:qquickviewcomparison/test.qml");
+ QSurfaceFormat format;
+ format.setDepthBufferSize(16);
+ format.setStencilBufferSize(8);
+ if (m_checkboxMultiSample->isChecked())
+ format.setSamples(4);
+
+ if (m_radioView->isChecked()) {
+ QQuickView *quickView = new QQuickView;
+ quickView->setFormat(format);
+ quickView->setResizeMode(QQuickView::SizeRootObjectToView);
+ connect(quickView, &QQuickView::statusChanged, this, &MainWindow::onStatusChangedView);
+ connect(quickView, &QQuickView::sceneGraphError, this, &MainWindow::onSceneGraphError);
+ quickView->setSource(source);
+ m_currentRootObject = quickView->rootObject();
+ switchTo(QWidget::createWindowContainer(quickView));
+ } else {
+ QQuickWidget *quickWidget = new QQuickWidget;
+ quickWidget->setFormat(format);
+ quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ connect(quickWidget, &QQuickWidget::statusChanged, this, &MainWindow::onStatusChangedWidget);
+ connect(quickWidget, &QQuickWidget::sceneGraphError, this, &MainWindow::onSceneGraphError);
+ quickWidget->setSource(source);
+ m_currentRootObject = quickWidget->rootObject();
+ switchTo(quickWidget);
+ }
+
+ m_currentRootObject->setProperty("currentText", text);
+ m_currentRootObject->setProperty("multisample", m_checkboxMultiSample->isChecked());
+
+ m_overlayLabel->raise();
+}
+
+void MainWindow::onStatusChangedView(QQuickView::Status status)
+{
+ QString s;
+ switch (status) {
+ case QQuickView::Null:
+ s = tr("Null");
+ break;
+ case QQuickView::Ready:
+ s = tr("Ready");
+ break;
+ case QQuickView::Loading:
+ s = tr("Loading");
+ break;
+ case QQuickView::Error:
+ s = tr("Error");
+ break;
+ default:
+ s = tr("Unknown");
+ break;
+ }
+ m_labelStatus->setText(tr("QQuickView status: %1").arg(s));
+}
+
+void MainWindow::onStatusChangedWidget(QQuickWidget::Status status)
+{
+ QString s;
+ switch (status) {
+ case QQuickWidget::Null:
+ s = tr("Null");
+ break;
+ case QQuickWidget::Ready:
+ s = tr("Ready");
+ break;
+ case QQuickWidget::Loading:
+ s = tr("Loading");
+ break;
+ case QQuickWidget::Error:
+ s = tr("Error");
+ break;
+ default:
+ s = tr("Unknown");
+ break;
+ }
+ m_labelStatus->setText(tr("QQuickWidget status: %1").arg(s));
+}
+
+void MainWindow::onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message)
+{
+ m_labelStatus->setText(tr("Scenegraph error %1: %2").arg(error).arg(message));
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
new file mode 100644
index 0000000000..c7bd514d81
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QWidget>
+#include <QQuickWidget>
+#include <QQuickView>
+
+QT_FORWARD_DECLARE_CLASS(QRadioButton)
+QT_FORWARD_DECLARE_CLASS(QCheckBox)
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QLayout)
+
+class MainWindow : public QWidget
+{
+public:
+ MainWindow();
+
+protected:
+ void resizeEvent(QResizeEvent*);
+private slots:
+ void updateView();
+ void onStatusChangedView(QQuickView::Status status);
+ void onStatusChangedWidget(QQuickWidget::Status status);
+ void onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
+
+private:
+ void switchTo(QWidget *view);
+
+ QRadioButton *m_radioView;
+ QRadioButton *m_radioWidget;
+ QCheckBox *m_checkboxMultiSample;
+ QLabel *m_labelStatus;
+ QLayout *m_containerLayout;
+ QWidget *m_currentView;
+ QObject *m_currentRootObject;
+ QLabel *m_overlayLabel;
+ QCheckBox *m_checkboxOverlayVisible;
+};
+
+#endif
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro
new file mode 100644
index 0000000000..9d70f7aa5a
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = qquickviewcomparison
+
+QT += quick widgets quickwidgets
+
+SOURCES += main.cpp \
+ mainwindow.cpp \
+ logo.cpp \
+ fbitem.cpp
+
+HEADERS += mainwindow.h \
+ logo.h \
+ fbitem.h
+
+RESOURCES += qquickviewcomparison.qrc
+
+OTHER_FILES += test.qml
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc
new file mode 100644
index 0000000000..2b259fdeec
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qquickviewcomparison">
+ <file>test.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/test.qml b/examples/quick/quickwidgets/qquickviewcomparison/test.qml
new file mode 100644
index 0000000000..2e8c83024a
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/test.qml
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Particles 2.0
+import fbitem 1.0
+
+Rectangle {
+ id: root
+ color: "lightBlue"
+ property alias currentText: edit.text
+ property alias multisample: fbitem.multisample
+
+ ParticleSystem {
+ anchors.fill: parent
+ running: true
+
+ ImageParticle {
+ source: "qrc:///particleresources/glowdot.png"
+ alpha: 0
+ colorVariation: 1
+ }
+
+ Emitter {
+ anchors.fill: parent
+ lifeSpan: 3000
+ emitRate: 30
+ size: 50
+ sizeVariation: 10
+ velocity: PointDirection { xVariation: 10; yVariation: 10; }
+ acceleration: PointDirection {
+ y: -10
+ xVariation: 5
+ yVariation: 5
+ }
+ }
+ }
+
+ Rectangle {
+ y: 10
+ width: parent.width / 2
+ height: edit.contentHeight + 4
+ anchors.horizontalCenter: parent.horizontalCenter
+ border.color: "gray"
+ border.width: 2
+ radius: 8
+ color: "lightGray"
+ clip: true
+ TextInput {
+ id: edit
+ anchors.horizontalCenter: parent.horizontalCenter
+ maximumLength: 30
+ focus: true
+ font.pointSize: 20
+ }
+ }
+
+ Rectangle {
+ width: 300
+ height: 300
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 20000; loops: Animation.Infinite; }
+ }
+
+ FbItem {
+ id: fbitem
+ anchors.fill: parent
+ SequentialAnimation on eye.y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 0.15
+ duration: 1000
+ }
+ NumberAnimation {
+ from: 0.15
+ to: 0
+ duration: 2000
+ }
+ }
+ SequentialAnimation on eye.x {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: -0.5
+ duration: 3000
+ }
+ NumberAnimation {
+ from: -0.5
+ to: 0.5
+ duration: 3000
+ easing.type: Easing.OutQuad
+ }
+ NumberAnimation {
+ from: 0.5
+ to: 0
+ duration: 1000
+ }
+ }
+ SequentialAnimation on rotation.y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 360
+ duration: 5000
+ }
+ NumberAnimation {
+ from: 360
+ to: 0
+ duration: 2500
+ }
+ }
+ SequentialAnimation on rotation.x {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 360
+ duration: 6000
+ }
+ NumberAnimation {
+ from: 360
+ to: 0
+ duration: 3000
+ }
+ }
+ }
+
+ Text {
+ id: effText
+ text: edit.text
+ anchors.centerIn: parent
+ font.pointSize: 60
+ style: Text.Outline
+ styleColor: "green"
+ }
+
+ ShaderEffectSource {
+ id: effSource
+ sourceItem: effText
+ hideSource: true
+ }
+
+ ShaderEffect {
+ SequentialAnimation on scale {
+ loops: Animation.Infinite
+ NumberAnimation { from: 1.0; to: 2.0; duration: 1000; easing.type: Easing.InCirc }
+ PauseAnimation { duration: 1000 }
+ NumberAnimation { from: 2.0; to: 0.5; duration: 1000; easing.type: Easing.OutExpo }
+ NumberAnimation { from: 0.5; to: 1.0; duration: 500 }
+ PauseAnimation { duration: 1000 }
+ }
+ width: effText.width
+ height: effText.height
+ anchors.centerIn: parent
+ property variant source: effSource
+ property real amplitude: 0.002
+ property real frequency: 10
+ property real time: 0
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 1000 }
+ fragmentShader:
+ "uniform lowp float qt_Opacity;" +
+ "uniform highp float amplitude;" +
+ "uniform highp float frequency;" +
+ "uniform highp float time;" +
+ "uniform sampler2D source;" +
+ "varying highp vec2 qt_TexCoord0;" +
+ "void main() {" +
+ " highp vec2 p = sin(time + frequency * qt_TexCoord0);" +
+ " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" +
+ "}"
+ }
+}
diff --git a/examples/quick/quickwidgets/quickwidgets.pro b/examples/quick/quickwidgets/quickwidgets.pro
index 07192b6696..be932f33d0 100644
--- a/examples/quick/quickwidgets/quickwidgets.pro
+++ b/examples/quick/quickwidgets/quickwidgets.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = quickwidget
+SUBDIRS = quickwidget \
+ qquickviewcomparison