summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/qt3d/scene3d/main.qml13
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp58
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem_p.h7
3 files changed, 70 insertions, 8 deletions
diff --git a/examples/qt3d/scene3d/main.qml b/examples/qt3d/scene3d/main.qml
index bed04161e..6419309a8 100644
--- a/examples/qt3d/scene3d/main.qml
+++ b/examples/qt3d/scene3d/main.qml
@@ -50,6 +50,18 @@ Item {
}
}
+ Text {
+ text: "Multisample: " + scene3d.multisample
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: scene3d.multisample = !scene3d.multisample
+ }
+ }
+
Rectangle {
id: scene
width: Math.min(parent.width, parent.height) - 100
@@ -67,6 +79,7 @@ Item {
}
Scene3D {
+ id: scene3d
anchors.fill: parent
anchors.margins: 10
focus: true
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