aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick/scenegraph/openglunderqml
diff options
context:
space:
mode:
Diffstat (limited to 'examples/quick/scenegraph/openglunderqml')
-rw-r--r--examples/quick/scenegraph/openglunderqml/doc/images/openglunderqml-example.jpgbin0 -> 20640 bytes
-rw-r--r--examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc168
-rw-r--r--examples/quick/scenegraph/openglunderqml/main.cpp2
-rw-r--r--examples/quick/scenegraph/openglunderqml/main.qml2
-rw-r--r--examples/quick/scenegraph/openglunderqml/squircle.cpp22
-rw-r--r--examples/quick/scenegraph/openglunderqml/squircle.h4
6 files changed, 189 insertions, 9 deletions
diff --git a/examples/quick/scenegraph/openglunderqml/doc/images/openglunderqml-example.jpg b/examples/quick/scenegraph/openglunderqml/doc/images/openglunderqml-example.jpg
new file mode 100644
index 0000000000..69ee04d2ea
--- /dev/null
+++ b/examples/quick/scenegraph/openglunderqml/doc/images/openglunderqml-example.jpg
Binary files differ
diff --git a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
new file mode 100644
index 0000000000..5ded717e5f
--- /dev/null
+++ b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example quick/scenegraph/openglunderqml
+ \title OpenGL Under QML
+ \ingroup qtquickexamples
+ \brief Shows how to render OpenGL under a Qt Quick scene.
+
+ \image openglunderqml-example.jpg
+
+ The OpenGL under QML example shows how an application can make use
+ of the \l QQuickWindow::beforeRendering() signal to draw custom
+ OpenGL content under a Qt Quick scene. This signal is emitted at
+ the start of every frame, before the scene graph starts its
+ rendering, thus any OpenGL draw calls that are made as a response
+ to this signal, will stack under the Qt Quick items.
+
+ As an alternative, applications that wish to render OpenGL content
+ on top of the Qt Quick scene, can do so by connecting to the \l
+ QQuickWindow::afterRendering() signal.
+
+ In this example, we will also see how it is possible to have
+ values that are exposed to QML which affect the OpenGL
+ rendering. We animate the threshold value using a NumberAnimation
+ in the QML file and this value is used by the OpenGL shader
+ program that draws the squircles.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.h 1
+
+ First of all, we need a QObject with a slot to connect the signals
+ to. We subclass QQuickItem in order to use the \l
+ QQuickItem::window() which holds the window instance we want to
+ connect to.
+
+ We use two values of \c t. The variable \c m_t is the property
+ value as it exists in the GUI thread. The \c m_thread_t value is a
+ copy of \c m_t for use in the rendering thread. We need an
+ explicit copy because the scene graph can render in one thread
+ while updating properties on the GUI thread in preparation for the
+ next frame. If we had used only one value, the animation could
+ have updated the value to that of the next frame before we got a
+ chance to render it.
+
+ \note In this example, a wrong value for \c t will have minimal
+ consequences, but we emphasize that rendering and GUI thread
+ objects and values must stay separate to avoid race conditions,
+ undesired behavior and in the worst case, crashes.
+
+ Lets move on to the implementation.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 7
+
+ The constructor of the \c Squircle class simply initializes the
+ values. The shader program will be initialized during rendering
+ later.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 8
+
+ The property setter checks that the value has indeed changed
+ before updating its internal variable. It then calls \l
+ QQuickWindow::update() which will trigger another frame to be
+ rendered. Note that the setter might be called during
+ initialization, before the object has been entered into the scene
+ and before it has a window.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 1
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 2
+
+ For our paint function to be called, we need to connect to the
+ window's signals. When Squircle object is populated into the
+ scene, the itemChange function is called with the change type \c
+ ItemSceneChange. We connect \l QQuickWindow::beforeRendering() to
+ \c paint() to do the rendering, and \l
+ QQuickWindow::beforeSynchronizing() to \c sync() to copy the state
+ of the \c t property for the upcoming frame.
+
+ \note Since the Squircle object has affinity to the GUI thread and
+ the signals are emitted from the rendering thread, it is crucial
+ that the connections are made with \l
+ Qt::DirectConnection. Failing to do so, will result in that the
+ slots are invoked on the wrong thread with no OpenGL context
+ present.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 3
+
+ The default behavior of the scene graph is to clear the
+ framebuffer before rendering. Since we render before the scene
+ graph, we need to turn this clearing off. This means that we need
+ to clear ourselves in the \c paint() function.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 4
+
+ The first thing we do in the \c paint() function is to
+ initialize the shader program. By initializing the shader program
+ here, we make sure that the OpenGL context is bound and that we
+ are on the correct thread.
+
+ We also connect to the QOpenGLContext::aboutToBeDestroyed()
+ signal, so that we can clean up the shader program when the
+ context is destroyed. Again, this is a \l Qt::DirectConnection as
+ all rendering related operations must happen on the rendering
+ thread.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 5
+
+ We use the shader program to draw the squircle. At the end of the
+ \c paint function we release the program and disable the
+ attributes we used so that the OpenGL context is in a "clean"
+ state for the scene graph to pick it up.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 6
+
+ In the \c cleanup() function we delete the program.
+
+ \snippet quick/scenegraph/openglunderqml/squircle.cpp 9
+
+ We use the \c sync() function to copy the state of the
+ object in the GUI thread into the rendering thread.
+
+ The signal is emitted on the rendering thread while the GUI
+ thread is blocked, so it is safe to simply copy the value without
+ any additional protection.
+
+ \snippet quick/scenegraph/openglunderqml/main.cpp 1
+
+ The application's \c main() function instantiates a QQuickView and
+ launches the \c main.qml file. The only thing worth noting is that
+ we export the \c Squircle class to QML using the \l
+ qmlRegisterType() macro.
+
+ \snippet quick/scenegraph/openglunderqml/main.qml 1
+
+ We import the Squircle QML type with the name we registered in the
+ \c main() function. We then instantiate it and create a running
+ NumberAnimation on the its \c t property.
+
+ \snippet quick/scenegraph/openglunderqml/main.qml 2
+
+ Then we overlay a short descriptive text, so that it is clearly
+ visible that we are in fact rendering OpenGL under our Qt Quick
+ scene.
+
+ */
diff --git a/examples/quick/scenegraph/openglunderqml/main.cpp b/examples/quick/scenegraph/openglunderqml/main.cpp
index adc389cb4c..dadaec8d8c 100644
--- a/examples/quick/scenegraph/openglunderqml/main.cpp
+++ b/examples/quick/scenegraph/openglunderqml/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
diff --git a/examples/quick/scenegraph/openglunderqml/main.qml b/examples/quick/scenegraph/openglunderqml/main.qml
index 0c3695fb7b..897316545d 100644
--- a/examples/quick/scenegraph/openglunderqml/main.qml
+++ b/examples/quick/scenegraph/openglunderqml/main.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp
index 867ce4a7e0..8e34144af0 100644
--- a/examples/quick/scenegraph/openglunderqml/squircle.cpp
+++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
@@ -48,6 +48,8 @@
//! [7]
Squircle::Squircle()
: m_program(0)
+ , m_t(0)
+ , m_thread_t(0)
{
}
//! [7]
@@ -70,8 +72,8 @@ 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)
+ QQuickWindow *win = window();
+ if (!win)
return;
//! [1]
@@ -79,15 +81,17 @@ void Squircle::itemChange(ItemChange change, const ItemChangeData &)
// 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);
+ connect(win, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection);
+ connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), 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);
+ win->setClearBeforeRendering(false);
}
}
+
//! [3] //! [4]
void Squircle::paint()
{
@@ -128,7 +132,7 @@ void Squircle::paint()
1, 1
};
m_program->setAttributeArray(0, GL_FLOAT, values, 2);
- m_program->setUniformValue("t", (float) m_t);
+ m_program->setUniformValue("t", (float) m_thread_t);
glViewport(0, 0, window()->width(), window()->height());
@@ -157,4 +161,10 @@ void Squircle::cleanup()
}
//! [6]
+//! [9]
+void Squircle::sync()
+{
+ m_thread_t = m_t;
+}
+//! [9]
diff --git a/examples/quick/scenegraph/openglunderqml/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h
index 3d0a46e2ec..e292ca325f 100644
--- a/examples/quick/scenegraph/openglunderqml/squircle.h
+++ b/examples/quick/scenegraph/openglunderqml/squircle.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
@@ -67,11 +67,13 @@ protected:
public slots:
void paint();
void cleanup();
+ void sync();
private:
QOpenGLShaderProgram *m_program;
qreal m_t;
+ qreal m_thread_t;
};
//! [1]