summaryrefslogtreecommitdiffstats
path: root/src/quick3d/imports/scene3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick3d/imports/scene3d')
-rw-r--r--src/quick3d/imports/scene3d/plugins.qmltypes38
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp81
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp23
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer_p.h3
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp1
-rw-r--r--src/quick3d/imports/scene3d/scene3dview.cpp2
6 files changed, 125 insertions, 23 deletions
diff --git a/src/quick3d/imports/scene3d/plugins.qmltypes b/src/quick3d/imports/scene3d/plugins.qmltypes
index da3d7ec3e..aca01ac25 100644
--- a/src/quick3d/imports/scene3d/plugins.qmltypes
+++ b/src/quick3d/imports/scene3d/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene3D 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene3D 2.14'
Module {
dependencies: ["Qt3D.Core 2.0", "QtQuick 2.0"]
@@ -12,8 +12,11 @@ Module {
name: "Qt3DRender::Scene3DItem"
defaultProperty: "entity"
prototype: "QQuickItem"
- exports: ["QtQuick.Scene3D/Scene3D 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Scene3D/Scene3D 2.0",
+ "QtQuick.Scene3D/Scene3D 2.14"
+ ]
+ exportMetaObjectRevisions: [0, 14]
Enum {
name: "CameraAspectRatioMode"
values: {
@@ -21,11 +24,19 @@ Module {
"UserAspectRatio": 1
}
}
+ Enum {
+ name: "CompositingMode"
+ values: {
+ "FBO": 0,
+ "Underlay": 1
+ }
+ }
Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
Property { name: "aspects"; type: "QStringList" }
Property { name: "multisample"; type: "bool" }
Property { name: "cameraAspectRatioMode"; type: "CameraAspectRatioMode" }
Property { name: "hoverEnabled"; type: "bool" }
+ Property { name: "compositingMode"; revision: 14; type: "CompositingMode" }
Signal {
name: "cameraAspectRatioModeChanged"
Parameter { name: "mode"; type: "CameraAspectRatioMode" }
@@ -47,9 +58,30 @@ Module {
Parameter { name: "enabled"; type: "bool" }
}
Method {
+ name: "setCompositingMode"
+ Parameter { name: "mode"; type: "CompositingMode" }
+ }
+ Method {
name: "setItemAreaAndDevicePixelRatio"
Parameter { name: "area"; type: "QSize" }
Parameter { name: "devicePixelRatio"; type: "double" }
}
}
+ Component {
+ name: "Qt3DRender::Scene3DView"
+ defaultProperty: "entity"
+ prototype: "QQuickItem"
+ exports: ["QtQuick.Scene3D/Scene3DView 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ Property { name: "scene3D"; type: "Qt3DRender::Scene3DItem"; isPointer: true }
+ Method {
+ name: "setEntity"
+ Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ }
+ Method {
+ name: "setScene3D"
+ Parameter { name: "scene3D"; type: "Scene3DItem"; isPointer: true }
+ }
+ }
}
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp
index f3f7acd71..f824d2c4e 100644
--- a/src/quick3d/imports/scene3d/scene3ditem.cpp
+++ b/src/quick3d/imports/scene3d/scene3ditem.cpp
@@ -137,6 +137,11 @@ namespace Qt3DRender {
\li The Scene3D instance is instantiated prior to any Scene3DView
\li The Scene3D entity property is left unset
\endlist
+
+ \note Åšetting the visibility of the Scene3D element to false will halt the
+ Qt 3D simulation loop. This means that binding the visible property to an
+ expression that depends on property updates driven by the Qt 3D simulation
+ loop (FrameAction) will never reavaluates.
*/
Scene3DItem::Scene3DItem(QQuickItem *parent)
: QQuickItem(parent)
@@ -154,6 +159,7 @@ Scene3DItem::Scene3DItem(QQuickItem *parent)
, m_disableClearWindow(false)
, m_cameraAspectRatioMode(AutomaticAspectRatio)
, m_compositingMode(FBO)
+ , m_dummySurface(nullptr)
{
setFlag(QQuickItem::ItemHasContents, true);
setAcceptedMouseButtons(Qt::MouseButtonMask);
@@ -427,12 +433,26 @@ void Scene3DItem::applyRootEntityChange()
bool Scene3DItem::needsRender()
{
+ // We need the dirty flag which is connected to the change arbiter
+ // receiving updates to know whether something in the scene has changed
+
+ // Ideally we would use shouldRender() alone but given that it becomes true
+ // only after the arbiter has sync the changes and might be reset before
+ // process jobs is completed, we cannot fully rely on it. It would require
+ // splitting processFrame in 2 parts.
+
+ // We only use it for cases where Qt3D render may require several loops of
+ // the simulation to fully process a frame (e.g shaders are loaded in frame
+ // n and we can only build render commands for the new shader at frame n +
+ // This is where renderer->shouldRender() comes into play as it knows
+ // whether some states remain dirty or not (even after processFrame is
+ // called)
+
auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect));
const bool dirty = m_dirty
|| (renderAspectPriv
&& renderAspectPriv->m_renderer
- && renderAspectPriv->m_renderer->settings()
- && renderAspectPriv->m_renderer->settings()->renderPolicy() == QRenderSettings::Always);
+ && renderAspectPriv->m_renderer->shouldRender());
m_dirty = false;
return dirty;
}
@@ -454,8 +474,12 @@ bool Scene3DItem::needsRender()
// processFrame will block and wait for renderer to have been finished
void Scene3DItem::onBeforeSync()
{
- // Has anything in the 3D scene actually changed that requires us to render?
- if (!needsRender())
+ static bool dontRenderWhenHidden = !qgetenv("QT3D_SCENE3D_STOP_RENDER_HIDDEN").isEmpty();
+
+ // If we are not visible, don't processFrame changes as we would end up
+ // waiting forever for the scene to be rendered which won't happen
+ // if the Scene3D item is not visible
+ if (!isVisible() && dontRenderWhenHidden)
return;
Q_ASSERT(QThread::currentThread() == thread());
@@ -498,6 +522,7 @@ void Scene3DItem::onBeforeSync()
// start rendering before this function has been called
// We add in a safety to skip such frames as this could otherwise
// make Qt3D enter a locked state
+ m_renderer->setSkipFrame(!needsRender());
m_renderer->allowRender();
// Note: it's too early to request an update at this point as
@@ -546,7 +571,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject)
/*!
\qmlmethod void Scene3D::setItemAreaAndDevicePixelRatio(size area, real devicePixelRatio)
- \brief \TODO
+ Sets the item area to \a area and the pixel ratio to \a devicePixelRatio.
*/
void Scene3DItem::setItemAreaAndDevicePixelRatio(QSize area, qreal devicePixelRatio)
{
@@ -569,25 +594,45 @@ bool Scene3DItem::isHoverEnabled() const
void Scene3DItem::setCameraAspectModeHelper()
{
- switch (m_cameraAspectRatioMode) {
- case AutomaticAspectRatio:
- connect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
- connect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
- // Update the aspect ratio the first time the surface is set
- updateCameraAspectRatio();
- break;
- case UserAspectRatio:
- disconnect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
- disconnect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
- break;
+ if (m_compositingMode == FBO) {
+ switch (m_cameraAspectRatioMode) {
+ case AutomaticAspectRatio:
+ connect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ connect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ // Update the aspect ratio the first time the surface is set
+ updateCameraAspectRatio();
+ break;
+ case UserAspectRatio:
+ disconnect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ disconnect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ break;
+ }
+ } else {
+ // In Underlay mode, we rely on the window for aspect ratio and not the size of the Scene3DItem
+ switch (m_cameraAspectRatioMode) {
+ case AutomaticAspectRatio:
+ connect(window(), &QWindow::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ connect(window(), &QWindow::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ // Update the aspect ratio the first time the surface is set
+ updateCameraAspectRatio();
+ break;
+ case UserAspectRatio:
+ disconnect(window(), &QWindow::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ disconnect(window(), &QWindow::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ break;
+ }
}
}
void Scene3DItem::updateCameraAspectRatio()
{
if (m_camera) {
- m_camera->setAspectRatio(static_cast<float>(width()) /
- static_cast<float>(height()));
+ if (m_compositingMode == FBO)
+ m_camera->setAspectRatio(static_cast<float>(width()) /
+ static_cast<float>(height()));
+ else
+ m_camera->setAspectRatio(static_cast<float>(window()->width()) /
+ static_cast<float>(window()->height()));
}
}
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index 1e375ccbb..fafeeedf4 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -161,7 +161,9 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_forceRecreate(false)
, m_shouldRender(false)
, m_dirtyViews(false)
+ , m_skipFrame(false)
, m_allowRendering(0)
+ , m_compositingMode(Scene3DItem::FBO)
{
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
@@ -277,6 +279,19 @@ void Scene3DRenderer::beforeSynchronize()
// We could otherwise enter a deadlock state
if (!m_allowRendering.tryAcquire(std::max(m_allowRendering.available(), 1)))
return;
+
+ // In the case of OnDemand rendering, we still need to get to this
+ // point to ensure we have processed jobs for all aspects.
+ // We also still need to call render() to allow proceeding with the
+ // next frame. However it won't be performing any 3d rendering at all
+ // so we do it here and return early. This prevents a costly QtQuick
+ // SceneGraph update for nothing
+ if (m_skipFrame) {
+ m_skipFrame = false;
+ static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(false);
+ return;
+ }
+
m_shouldRender = true;
// Check size / multisampling
@@ -359,6 +374,11 @@ void Scene3DRenderer::setCompositingMode(Scene3DItem::CompositingMode mode)
m_compositingMode = mode;
}
+void Scene3DRenderer::setSkipFrame(bool skip)
+{
+ m_skipFrame = skip;
+}
+
// Main Thread, Render Thread locked
void Scene3DRenderer::setScene3DViews(const QVector<Scene3DView *> views)
{
@@ -422,7 +442,8 @@ void Scene3DRenderer::render()
// Only show the node once Qt3D has rendered to it
// Avoids showing garbage on the first frame
- m_node->show();
+ if (m_node)
+ m_node->show();
}
// Reset the state used by the Qt Quick scenegraph to avoid any
diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h
index 4f3651cd3..08a2c60a3 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer_p.h
+++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h
@@ -87,7 +87,7 @@ public:
void setCleanerHelper(Scene3DCleaner *cleaner);
void allowRender();
void setCompositingMode(Scene3DItem::CompositingMode mode);
-
+ void setSkipFrame(bool skip);
void setScene3DViews(const QVector<Scene3DView *> views);
public Q_SLOTS:
@@ -119,6 +119,7 @@ private:
bool m_forceRecreate;
bool m_shouldRender;
bool m_dirtyViews;
+ bool m_skipFrame;
QSemaphore m_allowRendering;
Scene3DItem::CompositingMode m_compositingMode;
QVector<Scene3DView *> m_views;
diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
index 55538ad1f..cfe39e8c7 100644
--- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
+++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
@@ -76,6 +76,7 @@ Scene3DSGMaterialShader::Scene3DSGMaterialShader()
: QSGMaterialShader()
, m_matrixId(-1)
, m_opacityId(-1)
+ , m_visibleId(-1)
{
}
diff --git a/src/quick3d/imports/scene3d/scene3dview.cpp b/src/quick3d/imports/scene3d/scene3dview.cpp
index 9d298b435..f38d135f0 100644
--- a/src/quick3d/imports/scene3d/scene3dview.cpp
+++ b/src/quick3d/imports/scene3d/scene3dview.cpp
@@ -278,6 +278,8 @@ QSGNode *Scene3DView::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
if (m_dirtyFlags & DirtyTexture) {
fboNode->setTexture(m_texture);
m_dirtyFlags.setFlag(DirtyTexture, false);
+ // Show FBO Node at this point
+ fboNode->show();
}
if (m_dirtyFlags & DirtyNode) {
fboNode->markDirty(QSGNode::DirtyMaterial);