summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2020-11-18 12:29:48 +0000
committerMike Krus <mike.krus@kdab.com>2020-11-20 14:58:17 +0000
commitc6aec09f4f6030fa11b9ba911e4c0df2fe7485b2 (patch)
tree3f2fbc49f76264fefaa8ceccbeacbde1b7ddaae7
parentb0dbd67d7b95cb4c74a502e04b68e3b3f9dc8e6b (diff)
Introduce QGeometryRenderer::sortIndex
Lets user override the sorting order of entities. [ChangeLog] Add sortIndex property to QGeometryRenderer to explicitly control the order in which entities are rendered Pick-to: 5.15 Change-Id: Iab7fd0d705f7ddcb424a59f86f8c2c28059813d1 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/renderer/renderview.cpp4
-rw-r--r--src/plugins/renderers/rhi/renderer/renderview.cpp4
-rw-r--r--src/render/geometry/geometryrenderer.cpp4
-rw-r--r--src/render/geometry/geometryrenderer_p.h2
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp65
-rw-r--r--src/render/geometry/qgeometryrenderer.h6
-rw-r--r--src/render/geometry/qgeometryrenderer_p.h1
-rw-r--r--tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp14
-rw-r--r--tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp10
9 files changed, 110 insertions, 0 deletions
diff --git a/src/plugins/renderers/opengl/renderer/renderview.cpp b/src/plugins/renderers/opengl/renderer/renderview.cpp
index db1b6123c..3f0f9061e 100644
--- a/src/plugins/renderers/opengl/renderer/renderview.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderview.cpp
@@ -1089,6 +1089,10 @@ void RenderView::updateRenderCommand(const EntityRenderCommandDataSubView &subVi
// view vector. This gives a depth value suitable as the key
// for BackToFront sorting.
command.m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_eyePos, m_eyeViewDir);
+
+ auto geometryRenderer = m_manager->geometryRendererManager()->data(command.m_geometryRenderer);
+ if (geometryRenderer && !qFuzzyCompare(geometryRenderer->sortIndex(), -1.f))
+ command.m_depth = geometryRenderer->sortIndex();
} else { // Compute
// Note: if frameCount has reached 0 in the previous frame, isEnabled
// would be false
diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp
index 682a9e28b..073c7fb04 100644
--- a/src/plugins/renderers/rhi/renderer/renderview.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderview.cpp
@@ -1145,6 +1145,10 @@ void RenderView::updateRenderCommand(const EntityRenderCommandDataSubView &subVi
command.m_depth = Vector3D::dotProduct(
entity->worldBoundingVolume()->center() - m_eyePos, m_eyeViewDir);
+ auto geometryRenderer = m_manager->geometryRendererManager()->data(command.m_geometryRenderer);
+ if (geometryRenderer && !qFuzzyCompare(geometryRenderer->sortIndex(), -1.f))
+ command.m_depth = geometryRenderer->sortIndex();
+
environmentLight = m_environmentLight;
lightSources = m_lightSources;
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index d314e87ce..3cbf6f066 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -69,6 +69,7 @@ GeometryRenderer::GeometryRenderer()
, m_primitiveType(QGeometryRenderer::Triangles)
, m_dirty(false)
, m_manager(nullptr)
+ , m_sortIndex(-1.f)
{
}
@@ -92,6 +93,7 @@ void GeometryRenderer::cleanup()
m_geometryId = Qt3DCore::QNodeId();
m_dirty = false;
m_geometryFactory.reset();
+ m_sortIndex = -1.f;
}
void GeometryRenderer::setManager(GeometryRendererManager *manager)
@@ -162,6 +164,8 @@ void GeometryRenderer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
}
}
+ m_sortIndex = node->sortIndex();
+
markDirty(AbstractRenderer::GeometryDirty);
}
diff --git a/src/render/geometry/geometryrenderer_p.h b/src/render/geometry/geometryrenderer_p.h
index 5693a21d3..c2232f43a 100644
--- a/src/render/geometry/geometryrenderer_p.h
+++ b/src/render/geometry/geometryrenderer_p.h
@@ -99,6 +99,7 @@ public:
inline Qt3DCore::QGeometryFactoryPtr geometryFactory() const { return m_geometryFactory; }
void unsetDirty();
bool hasView() const { return m_hasView; }
+ float sortIndex() const { return m_sortIndex; }
private:
Qt3DCore::QNodeId m_geometryId;
@@ -116,6 +117,7 @@ private:
bool m_hasView;
Qt3DCore::QGeometryFactoryPtr m_geometryFactory;
GeometryRendererManager *m_manager;
+ float m_sortIndex;
};
class GeometryRendererFunctor : public Qt3DCore::QBackendNodeMapper
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index fa9c20378..036235624 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -61,6 +61,7 @@ QGeometryRendererPrivate::QGeometryRendererPrivate()
, m_primitiveRestart(false)
, m_geometry(nullptr)
, m_primitiveType(QGeometryRenderer::Triangles)
+ , m_sortIndex(-1.f)
{
m_primaryProvider = false;
}
@@ -221,6 +222,30 @@ void QGeometryRendererPrivate::setView(QGeometryView *view)
\endlist
\sa Qt3DRender::QGeometryRenderer::PrimitiveType
*/
+/*!
+ \qmlproperty float GeometryRenderer::sortIndex
+ \since 6.0
+
+ Overrides the sorting index when depth sorting is enabled.
+
+ If depth sorting is enabled on the frame graph, the renderer will sort
+ objects based on how far the center of the bounding volume is from
+ the camera and render objects from the furthest to the closest.
+
+ This property can be used to override the depth index and precisely
+ control the order in which objects are rendered. This is useful when
+ all objects are at the same physical distance from the camera.
+
+ The actual values are not significant, only that they define an order
+ to sort the objects. These are sorted such as the object with the
+ smallest value is drawn first, then the second smallest, and so on.
+
+ \note Setting this to -1.f will disable the explicit sorting for this
+ entity and revert to using the distance from the center of the bounding
+ volume.
+
+ \sa SortPolicy
+*/
/*!
@@ -367,6 +392,36 @@ QGeometryRenderer::PrimitiveType QGeometryRenderer::primitiveType() const
return d->m_primitiveType;
}
+/*!
+ \property QGeometryRenderer::sortIndex
+ \since 6.0
+
+ Overrides the sorting index when depth sorting is enabled.
+
+ If depth sorting is enabled on the frame graph, the renderer will sort
+ objects based on how far the center of the bounding volume is from
+ the camera and render objects from the furthest to the closest.
+
+ This property can be used to override the depth index and precisely
+ control the order in which objects are rendered. This is useful when
+ all objects are at the same physical distance from the camera.
+
+ The actual values are not significant, only that they define an order
+ to sort the objects. These are sorted such as the object with the
+ smallest value is drawn first, then the second smallest, and so on.
+
+ \note Setting this to -1.f will disable the explicit sorting for this
+ entity and revert to using the distance from the center of the bounding
+ volume.
+
+ \sa Qt3DRender::QSortPolicy
+*/
+float QGeometryRenderer::sortIndex() const
+{
+ Q_D(const QGeometryRenderer);
+ return d->m_sortIndex;
+}
+
void QGeometryRenderer::setInstanceCount(int instanceCount)
{
Q_D(QGeometryRenderer);
@@ -487,6 +542,16 @@ void QGeometryRenderer::setPrimitiveType(QGeometryRenderer::PrimitiveType primit
emit primitiveTypeChanged(primitiveType);
}
+void QGeometryRenderer::setSortIndex(float sortIndex)
+{
+ Q_D(QGeometryRenderer);
+ if (qFuzzyCompare(d->m_sortIndex, sortIndex))
+ return;
+
+ d->m_sortIndex = sortIndex;
+ emit sortIndexChanged(d->m_sortIndex);
+}
+
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/geometry/qgeometryrenderer.h b/src/render/geometry/qgeometryrenderer.h
index 14d8bbccc..c0e14eaaf 100644
--- a/src/render/geometry/qgeometryrenderer.h
+++ b/src/render/geometry/qgeometryrenderer.h
@@ -65,6 +65,7 @@ class Q_3DRENDERSHARED_EXPORT QGeometryRenderer : public Qt3DCore::QBoundingVolu
Q_PROPERTY(bool primitiveRestartEnabled READ primitiveRestartEnabled WRITE setPrimitiveRestartEnabled NOTIFY primitiveRestartEnabledChanged)
Q_PROPERTY(Qt3DCore::QGeometry* geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
Q_PROPERTY(PrimitiveType primitiveType READ primitiveType WRITE setPrimitiveType NOTIFY primitiveTypeChanged)
+ Q_PROPERTY(float sortIndex READ sortIndex WRITE setSortIndex NOTIFY sortIndexChanged)
public:
explicit QGeometryRenderer(Qt3DCore::QNode *parent = nullptr);
~QGeometryRenderer();
@@ -99,6 +100,7 @@ public:
bool primitiveRestartEnabled() const;
Qt3DCore::QGeometry *geometry() const;
PrimitiveType primitiveType() const;
+ float sortIndex() const;
public Q_SLOTS:
void setInstanceCount(int instanceCount);
@@ -112,6 +114,7 @@ public Q_SLOTS:
void setPrimitiveRestartEnabled(bool enabled);
void setGeometry(Qt3DCore::QGeometry *geometry);
void setPrimitiveType(PrimitiveType primitiveType);
+ void setSortIndex(float sortIndex);
Q_SIGNALS:
void instanceCountChanged(int instanceCount);
@@ -126,11 +129,14 @@ Q_SIGNALS:
void geometryChanged(Qt3DCore::QGeometry *geometry);
void primitiveTypeChanged(PrimitiveType primitiveType);
+ void sortIndexChanged(float sortIndex);
+
protected:
explicit QGeometryRenderer(QGeometryRendererPrivate &dd, Qt3DCore::QNode *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QGeometryRenderer)
+ float m_sortIndex;
};
} // namespace Qt3DRender
diff --git a/src/render/geometry/qgeometryrenderer_p.h b/src/render/geometry/qgeometryrenderer_p.h
index 6d195bf35..18f4b270f 100644
--- a/src/render/geometry/qgeometryrenderer_p.h
+++ b/src/render/geometry/qgeometryrenderer_p.h
@@ -83,6 +83,7 @@ public:
Qt3DCore::QGeometry *m_geometry;
QGeometryRenderer::PrimitiveType m_primitiveType;
Qt3DCore::QGeometryFactoryPtr m_geometryFactory;
+ float m_sortIndex;
};
} // namespace Qt3DRender
diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
index 9d236b516..3338eb3b3 100644
--- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
+++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
@@ -67,6 +67,7 @@ private Q_SLOTS:
geometryRenderer.setPrimitiveType(Qt3DRender::QGeometryRenderer::Patches);
geometryRenderer.setGeometry(&geometry);
geometryRenderer.setEnabled(false);
+ geometryRenderer.setSortIndex(42.f);
// WHEN
renderGeometryRenderer.setRenderer(&renderer);
@@ -86,6 +87,8 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.primitiveType(), geometryRenderer.primitiveType());
QCOMPARE(renderGeometryRenderer.geometryId(), geometry.id());
QCOMPARE(renderGeometryRenderer.isEnabled(), false);
+ QCOMPARE(renderGeometryRenderer.sortIndex(), geometryRenderer.sortIndex());
+ QCOMPARE(renderGeometryRenderer.sortIndex(), 42.f);
}
void checkInitialAndCleanedUpState()
@@ -108,6 +111,7 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.primitiveType(), Qt3DRender::QGeometryRenderer::Triangles);
QVERIFY(renderGeometryRenderer.geometryFactory().isNull());
QVERIFY(!renderGeometryRenderer.isEnabled());
+ QCOMPARE(renderGeometryRenderer.sortIndex(), -1.f);
// GIVEN
Qt3DRender::QGeometryRenderer geometryRenderer;
@@ -124,6 +128,7 @@ private Q_SLOTS:
geometryRenderer.setPrimitiveType(Qt3DRender::QGeometryRenderer::Patches);
geometryRenderer.setGeometry(&geometry);
geometryRenderer.setEnabled(true);
+ geometryRenderer.setSortIndex(42.f);
// WHEN
renderGeometryRenderer.setRenderer(&renderer);
@@ -143,6 +148,7 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.primitiveRestartEnabled(), false);
QCOMPARE(renderGeometryRenderer.primitiveType(), Qt3DRender::QGeometryRenderer::Triangles);
QVERIFY(!renderGeometryRenderer.isEnabled());
+ QCOMPARE(renderGeometryRenderer.sortIndex(), -1.f);
}
void checkPropertyChanges()
@@ -303,6 +309,14 @@ private Q_SLOTS:
// THEN
QCOMPARE(backEndRenderer.isEnabled(), true);
QVERIFY(!backEndRenderer.isDirty());
+
+ // WHEN
+ frontEndRenderer.setSortIndex(42.f);
+ backEndRenderer.syncFromFrontEnd(&frontEndRenderer, false);
+
+ // THEN
+ QCOMPARE(backEndRenderer.sortIndex(), 42.f);
+ QVERIFY(!backEndRenderer.isDirty());
}
void checkSetRendererDirtyOnInitialization()
diff --git a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
index f3560e353..8fd08b133 100644
--- a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
+++ b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
@@ -162,6 +162,16 @@ private Q_SLOTS:
QCOMPARE(arbiter.dirtyNodes().front(), geometryRenderer.data());
arbiter.clear();
+
+ // WHEN
+ geometryRenderer->setSortIndex(42.f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.dirtyNodes().size(), 1);
+ QCOMPARE(arbiter.dirtyNodes().front(), geometryRenderer.data());
+
+ arbiter.clear();
}
void checkGeometryBookkeeping()