summaryrefslogtreecommitdiffstats
path: root/src/datavisualizationqml2
diff options
context:
space:
mode:
authorPasi Keranen <pasi.keranen@digia.com>2014-02-17 09:29:48 +0200
committerPasi Keränen <pasi.keranen@digia.com>2014-02-17 13:48:21 +0200
commit7eb24d68115619d8d78e6a427d5c723e5ffc15a5 (patch)
treef66ef63a5b6894377413fadd212405cae63082e6 /src/datavisualizationqml2
parent4f32a3e71e90c314e0a2f9f2bb19cc2eeb97292d (diff)
First step towards FXAA based antialiasing.
Change-Id: I40e767373156cf3e7f89c05767846a4949df319c Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src/datavisualizationqml2')
-rw-r--r--src/datavisualizationqml2/abstractdeclarative.cpp114
-rw-r--r--src/datavisualizationqml2/abstractdeclarative_p.h24
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2.pro6
-rw-r--r--src/datavisualizationqml2/declarativerendernode.cpp83
-rw-r--r--src/datavisualizationqml2/declarativerendernode_p.h64
5 files changed, 258 insertions, 33 deletions
diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp
index 2dc600c2..7415df9b 100644
--- a/src/datavisualizationqml2/abstractdeclarative.cpp
+++ b/src/datavisualizationqml2/abstractdeclarative.cpp
@@ -19,6 +19,7 @@
#include "abstractdeclarative_p.h"
#include "qvalue3daxis.h"
#include "declarativetheme_p.h"
+#include "declarativerendernode_p.h"
#include <QThread>
#include <QGuiApplication>
@@ -33,7 +34,9 @@ static QHash<QQuickWindow *, bool> windowClearList;
AbstractDeclarative::AbstractDeclarative(QQuickItem *parent) :
QQuickItem(parent),
m_controller(0),
- m_clearWindowBeforeRendering(true)
+ m_renderMode(DirectToBackground),
+ m_node(0),
+ m_initialisedSize(0, 0)
{
connect(this, &QQuickItem::windowChanged, this, &AbstractDeclarative::handleWindowChanged);
setAntialiasing(true);
@@ -45,6 +48,68 @@ AbstractDeclarative::~AbstractDeclarative()
checkWindowList(0);
}
+void AbstractDeclarative::setRenderingMode(AbstractDeclarative::RenderingMode mode)
+{
+ if (mode == m_renderMode)
+ return;
+
+ m_renderMode = mode;
+
+ switch (mode) {
+ case DirectToBackground:
+ // Intentional flowthrough
+ case DirectToBackground_NoClear:
+ // Delete render node
+ delete m_node;
+ m_node = 0;
+ m_initialisedSize = QSize(0, 0);
+ setAntialiasing(true);
+ setFlag(QQuickItem::ItemHasContents, false);
+ break;
+ case Indirect_NoAA:
+ // Force recreation of render node by resetting the initialized size
+ setAntialiasing(false);
+ m_initialisedSize = QSize(0, 0);
+ setFlag(QQuickItem::ItemHasContents, true);
+ break;
+ }
+
+ updateWindowParameters();
+
+ emit renderingModeChanged(mode);
+}
+
+AbstractDeclarative::RenderingMode AbstractDeclarative::renderingMode() const
+{
+ return m_renderMode;
+}
+
+QSGNode *AbstractDeclarative::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ // If old node exists and has right size, reuse it.
+ if (oldNode && m_initialisedSize == boundingRect().size().toSize()) {
+ // Update bounding rectangle (that has same size as before).
+ DeclarativeRenderNode *renderNode = static_cast<DeclarativeRenderNode *>(oldNode);
+ renderNode->setRect(boundingRect());
+ return oldNode;
+ }
+
+ // Create a new render node when size changes or if there is no node yet
+ m_initialisedSize = boundingRect().size().toSize();
+
+ // Delete old node
+ if (oldNode) {
+ m_node = 0;
+ delete oldNode;
+ }
+
+ // Create a new one and set its bounding rectangle
+ DeclarativeRenderNode *node = new DeclarativeRenderNode(window(), m_controller, m_renderMode, this);
+ node->setRect(boundingRect());
+ m_node = node;
+ return node;
+}
+
Declarative3DScene* AbstractDeclarative::scene() const
{
return static_cast<Declarative3DScene *>(m_controller->scene());
@@ -65,19 +130,6 @@ void AbstractDeclarative::clearSelection()
m_controller->clearSelection();
}
-void AbstractDeclarative::setClearWindowBeforeRendering(bool enable)
-{
- if (m_clearWindowBeforeRendering != enable) {
- m_clearWindowBeforeRendering = enable;
- emit clearWindowBeforeRenderingChanged(enable);
- }
-}
-
-bool AbstractDeclarative::clearWindowBeforeRendering() const
-{
- return m_clearWindowBeforeRendering;
-}
-
void AbstractDeclarative::setSelectionMode(SelectionFlags mode)
{
int intmode = int(mode);
@@ -130,7 +182,7 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller)
void AbstractDeclarative::synchDataToRenderer()
{
- if (m_clearWindowBeforeRendering && clearList.size())
+ if (m_renderMode == DirectToBackground && clearList.size())
clearList.clear();
m_controller->initializeOpenGL();
m_controller->synchDataToRenderer();
@@ -143,12 +195,14 @@ void AbstractDeclarative::handleWindowChanged(QQuickWindow *window)
if (!window)
return;
- connect(window, &QQuickWindow::beforeSynchronizing, this,
- &AbstractDeclarative::synchDataToRenderer, Qt::DirectConnection);
- connect(window, &QQuickWindow::beforeRendering, this,
- &AbstractDeclarative::render, Qt::DirectConnection);
- connect(m_controller.data(), &Abstract3DController::needRender, window,
- &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeSynchronizing,
+ this, &AbstractDeclarative::synchDataToRenderer,
+ Qt::DirectConnection);
+ connect(window, &QQuickWindow::beforeRendering,
+ this, &AbstractDeclarative::render,
+ Qt::DirectConnection);
+ connect(m_controller.data(), &Abstract3DController::needRender,
+ window, &QQuickWindow::update);
updateWindowParameters();
}
@@ -184,9 +238,15 @@ void AbstractDeclarative::updateWindowParameters()
win->update();
}
- QPointF point = QQuickItem::mapToScene(QPointF(0.0f, 0.0f));
- scene->d_ptr->setViewport(QRect(point.x(), point.y(), m_cachedGeometry.width(),
- m_cachedGeometry.height()));
+ if (m_renderMode == DirectToBackground || m_renderMode == DirectToBackground_NoClear) {
+ // Origo mapping is needed when rendering directly to background
+ QPointF point = QQuickItem::mapToScene(QPointF(0.0f, 0.0f));
+ scene->d_ptr->setViewport(QRect(point.x(), point.y(), m_cachedGeometry.width(),
+ m_cachedGeometry.height()));
+ } else {
+ // No translation needed when rendering to FBO
+ scene->d_ptr->setViewport(m_cachedGeometry.toRect());
+ }
}
}
@@ -205,9 +265,13 @@ void AbstractDeclarative::render()
{
updateWindowParameters();
+ // If we're not rendering directly to the background, return
+ if (m_renderMode != DirectToBackground && m_renderMode != DirectToBackground_NoClear)
+ return;
+
// Clear the background once per window as that is not done by default
const QQuickWindow *win = window();
- if (m_clearWindowBeforeRendering && !clearList.contains(win)) {
+ if (m_renderMode == DirectToBackground && !clearList.contains(win)) {
clearList.append(win);
QColor clearColor = win->color();
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h
index 16effca0..83a1bbdb 100644
--- a/src/datavisualizationqml2/abstractdeclarative_p.h
+++ b/src/datavisualizationqml2/abstractdeclarative_p.h
@@ -42,17 +42,20 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+class DeclarativeRenderNode;
+
class AbstractDeclarative : public QQuickItem
{
Q_OBJECT
Q_ENUMS(ShadowQuality)
+ Q_ENUMS(RenderingMode)
Q_FLAGS(SelectionFlag SelectionFlags)
Q_PROPERTY(SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged)
Q_PROPERTY(ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged)
Q_PROPERTY(Declarative3DScene* scene READ scene NOTIFY sceneChanged)
Q_PROPERTY(QAbstract3DInputHandler* inputHandler READ inputHandler WRITE setInputHandler NOTIFY inputHandlerChanged)
Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged)
- Q_PROPERTY(bool clearWindowBeforeRendering READ clearWindowBeforeRendering WRITE setClearWindowBeforeRendering NOTIFY clearWindowBeforeRenderingChanged)
+ Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged)
public:
enum SelectionFlag {
@@ -79,10 +82,19 @@ public:
ShadowQualitySoftHigh
};
+ enum RenderingMode {
+ DirectToBackground = 0,
+ DirectToBackground_NoClear,
+ Indirect_NoAA
+ };
+
public:
explicit AbstractDeclarative(QQuickItem *parent = 0);
virtual ~AbstractDeclarative();
+ virtual void setRenderingMode(RenderingMode mode);
+ virtual AbstractDeclarative::RenderingMode renderingMode() const;
+
virtual void setSelectionMode(SelectionFlags mode);
virtual AbstractDeclarative::SelectionFlags selectionMode() const;
@@ -99,9 +111,6 @@ public:
Q_INVOKABLE virtual void clearSelection();
- virtual void setClearWindowBeforeRendering(bool enable);
- virtual bool clearWindowBeforeRendering() const;
-
virtual void geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry);
void setSharedController(Abstract3DController *controller);
@@ -128,6 +137,7 @@ protected:
virtual void updateWindowParameters();
virtual void handleSelectionModeChange(QAbstract3DGraph::SelectionFlags mode);
virtual void handleShadowQualityChange(QAbstract3DGraph::ShadowQuality quality);
+ virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
signals:
void selectionModeChanged(SelectionFlags mode);
@@ -135,12 +145,14 @@ signals:
void sceneChanged(Q3DScene *scene);
void inputHandlerChanged(QAbstract3DInputHandler *inputHandler);
void themeChanged(Q3DTheme *theme);
- void clearWindowBeforeRenderingChanged(bool enable);
+ void renderingModeChanged(RenderingMode mode);
private:
QPointer<Abstract3DController> m_controller;
QRectF m_cachedGeometry;
- bool m_clearWindowBeforeRendering;
+ AbstractDeclarative::RenderingMode m_renderMode;
+ DeclarativeRenderNode *m_node;
+ QSize m_initialisedSize;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractDeclarative::SelectionFlags)
diff --git a/src/datavisualizationqml2/datavisualizationqml2.pro b/src/datavisualizationqml2/datavisualizationqml2.pro
index d6e8570c..254fefde 100644
--- a/src/datavisualizationqml2/datavisualizationqml2.pro
+++ b/src/datavisualizationqml2/datavisualizationqml2.pro
@@ -25,7 +25,8 @@ SOURCES += \
declarativeseries.cpp \
declarativetheme.cpp \
declarativecolor.cpp \
- declarativescene.cpp
+ declarativescene.cpp \
+ declarativerendernode.cpp
HEADERS += \
datavisualizationqml2_plugin.h \
@@ -37,7 +38,8 @@ HEADERS += \
declarativeseries_p.h \
declarativetheme_p.h \
declarativecolor_p.h \
- declarativescene_p.h
+ declarativescene_p.h \
+ declarativerendernode_p.h
OTHER_FILES = qmldir
diff --git a/src/datavisualizationqml2/declarativerendernode.cpp b/src/datavisualizationqml2/declarativerendernode.cpp
new file mode 100644
index 00000000..612d11df
--- /dev/null
+++ b/src/datavisualizationqml2/declarativerendernode.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativerendernode_p.h"
+#include <QtQuick/QQuickWindow>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+DeclarativeRenderNode::DeclarativeRenderNode(QQuickWindow *window, Abstract3DController *controller, AbstractDeclarative::RenderingMode mode, QObject *parent)
+ : QObject(parent),
+ m_fbo(0),
+ m_texture(0),
+ m_window(window),
+ m_controller(controller),
+ m_mode(mode)
+{
+ connect(window, &QQuickWindow::beforeRendering,
+ this, &DeclarativeRenderNode::renderFBO,
+ Qt::DirectConnection);
+}
+
+DeclarativeRenderNode::~DeclarativeRenderNode()
+{
+ delete m_texture;
+ delete m_fbo;
+}
+
+void DeclarativeRenderNode::renderFBO()
+{
+ QSize size = rect().size().toSize();
+
+ // Create FBO
+ if (!m_fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ m_fbo = new QOpenGLFramebufferObject(size, format);
+ m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+
+ setTexture(m_texture);
+
+ // Flip texture
+ QSize ts = m_texture->textureSize();
+ QRectF sourceRect(0, 0, ts.width(), ts.height());
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ QSGGeometry *geometry = this->geometry();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect(),
+ m_texture->convertToNormalizedSourceRect(sourceRect));
+ markDirty(DirtyMaterial);
+ }
+
+ // Call the shared rendering function
+ m_fbo->bind();
+ glDisable(GL_BLEND);
+
+ m_controller->render(m_fbo->handle());
+
+ glEnable(GL_BLEND);
+
+ m_fbo->release();
+
+ // New view is in the FBO, request repaint of scene graph
+ m_window->update();
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualizationqml2/declarativerendernode_p.h b/src/datavisualizationqml2/declarativerendernode_p.h
new file mode 100644
index 00000000..b8250512
--- /dev/null
+++ b/src/datavisualizationqml2/declarativerendernode_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVERENDERNODE_P_H
+#define DECLARATIVERENDERNODE_P_H
+
+#include <QObject>
+#include "datavisualizationglobal_p.h"
+#include "abstract3dcontroller_p.h"
+#include "abstractdeclarative_p.h"
+#include <qsgsimpletexturenode.h>
+
+class QOpenGLFramebufferObject;
+class QSGTexture;
+class QQuickWindow;
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class DeclarativeRenderNode : public QObject, public QSGSimpleTextureNode
+{
+ Q_OBJECT
+public:
+ explicit DeclarativeRenderNode(QQuickWindow *window, Abstract3DController *controller, AbstractDeclarative::RenderingMode mode, QObject *parent = 0);
+ virtual ~DeclarativeRenderNode();
+
+ // Renders view to FBO before render cycle starts.
+ void renderFBO();
+
+private:
+ QOpenGLFramebufferObject *m_fbo;
+ QSGTexture *m_texture;
+ QQuickWindow *m_window;
+ QPointer<Abstract3DController> m_controller;
+ AbstractDeclarative::RenderingMode m_mode;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif // DECLARATIVERENDERNODE_P_H