diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-04 16:10:37 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-07 09:26:16 +0000 |
commit | 03811c1729cf5ddec63ce3e288bf132abcc40c27 (patch) | |
tree | 74537fdbc2ddd26b5b3753858a04fd561b79577f /src | |
parent | 41ecc6360b96569fc500a46593b804082af1d1f7 (diff) |
Add a property to Scene3D to control multisampling
Change-Id: I94ad9870a819af165fbbeae3a51db05c043d40ca
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick3d/imports/scene3d/scene3ditem.cpp | 58 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3ditem_p.h | 7 |
2 files changed, 57 insertions, 8 deletions
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index 68dfb2bea..6fc49f98a 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -156,7 +156,8 @@ public: , m_multisampledFBO(Q_NULLPTR) , m_finalFBO(Q_NULLPTR) , m_texture(Q_NULLPTR) - , m_enableMultisampledFBO(true) + , m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead + , m_lastMultisample(false) { Q_CHECK_PTR(m_item); Q_CHECK_PTR(m_item->window()); @@ -213,6 +214,8 @@ public: } } + void synchronize(); + public Q_SLOTS: void render(); @@ -253,7 +256,8 @@ private: Scene3DSGNode *m_node; // Will be released by the QtQuick SceneGraph Scene3DCleaner *m_cleaner; QSize m_lastSize; - bool m_enableMultisampledFBO; + bool m_multisample; + bool m_lastMultisample; friend class Scene3DCleaner; }; @@ -415,7 +419,6 @@ private: QRectF m_rect; }; - /*! \class Qt3D::Scene3DItem \internal @@ -436,6 +439,7 @@ Scene3DItem::Scene3DItem(QQuickItem *parent) , m_renderAspect(new Qt3D::QRenderAspect(Qt3D::QRenderAspect::Synchronous)) , m_renderer(Q_NULLPTR) , m_rendererCleaner(new Scene3DCleaner()) + , m_multisample(true) { setFlag(QQuickItem::ItemHasContents, true); setAcceptedMouseButtons(Qt::MouseButtonMask); @@ -501,6 +505,34 @@ void Scene3DItem::applyRootEntityChange() m_aspectEngine->setRootEntity(m_entity); } +/*! + \return \c true if a multisample renderbuffer is in use. + */ +bool Scene3DItem::multisample() const +{ + return m_multisample; +} + +/*! + Enables or disables the usage of multisample renderbuffers based on \a enable. + + By default multisampling is enabled. If the OpenGL implementation has no + support for multisample renderbuffers or framebuffer blits, the request to + use multisampling is ignored. + + \note Refrain from changing the value frequently as it involves expensive + and potentially slow initialization of framebuffers and other OpenGL + resources. + */ +void Scene3DItem::setMultisample(bool enable) +{ + if (m_multisample != enable) { + m_multisample = enable; + emit multisampleChanged(); + update(); + } +} + QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *) { // If the node already exists @@ -516,12 +548,20 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode m_renderer->setCleanerHelper(m_rendererCleaner); } + // The main thread is blocked, it is now time to sync data between the renderer and the item. + m_renderer->synchronize(); + Scene3DSGNode *fboNode = new Scene3DSGNode(); fboNode->setRect(boundingRect()); m_renderer->setSGNode(fboNode); return fboNode; } +void Scene3DRenderer::synchronize() +{ + m_multisample = m_item->multisample(); +} + void Scene3DRenderer::setSGNode(Scene3DSGNode *node) Q_DECL_NOEXCEPT { m_node = node; @@ -542,14 +582,15 @@ void Scene3DRenderer::render() ContextSaver saver; const QSize currentSize = m_item->boundingRect().size().toSize(); - const bool forceRecreate = currentSize != m_lastSize; + const bool forceRecreate = currentSize != m_lastSize || m_multisample != m_lastMultisample; // Rebuild FBO and textures if never created or a resize has occurred - if ((m_multisampledFBO.isNull() || forceRecreate) && m_enableMultisampledFBO) { + if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) { + qCDebug(Scene3D) << Q_FUNC_INFO << "Creating multisample framebuffer"; m_multisampledFBO.reset(createMultisampledFramebufferObject(m_item->boundingRect().size().toSize())); - if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { - m_enableMultisampledFBO = false; + qCDebug(Scene3D) << Q_FUNC_INFO << "Failed to create multisample framebuffer"; + m_multisample = false; m_multisampledFBO.reset(Q_NULLPTR); } } @@ -563,9 +604,10 @@ void Scene3DRenderer::render() // Store the current size as a comparison // point for the next frame m_lastSize = currentSize; + m_lastMultisample = m_multisample; //Only try to use MSAA when available - if (m_enableMultisampledFBO) { + if (m_multisample) { // Bind FBO m_multisampledFBO->bind(); diff --git a/src/quick3d/imports/scene3d/scene3ditem_p.h b/src/quick3d/imports/scene3d/scene3ditem_p.h index d1f5b3389..3b620ec7f 100644 --- a/src/quick3d/imports/scene3d/scene3ditem_p.h +++ b/src/quick3d/imports/scene3d/scene3ditem_p.h @@ -55,6 +55,7 @@ class Scene3DItem : public QQuickItem Q_OBJECT Q_PROPERTY(Qt3D::QEntity* entity READ entity WRITE setEntity NOTIFY entityChanged) Q_PROPERTY(QStringList aspects READ aspects WRITE setAspects NOTIFY aspectsChanged) + Q_PROPERTY(bool multisample READ multisample WRITE setMultisample NOTIFY multisampleChanged) Q_CLASSINFO("DefaultProperty", "entity") public: explicit Scene3DItem(QQuickItem *parent = 0); @@ -63,6 +64,9 @@ public: QStringList aspects() const; Qt3D::QEntity *entity() const; + bool multisample() const; + void setMultisample(bool enable); + public Q_SLOTS: void setAspects(const QStringList &aspects); void setEntity(Qt3D::QEntity *entity); @@ -70,6 +74,7 @@ public Q_SLOTS: Q_SIGNALS: void aspectsChanged(); void entityChanged(); + void multisampleChanged(); private Q_SLOTS: void applyRootEntityChange(); @@ -84,6 +89,8 @@ private: Qt3D::QRenderAspect *m_renderAspect; Scene3DRenderer *m_renderer; Scene3DCleaner *m_rendererCleaner; + + bool m_multisample; }; } // Qt3D |