diff options
author | Mike Krus <mike.krus@kdab.com> | 2020-11-18 12:29:48 +0000 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2020-11-20 14:58:17 +0000 |
commit | c6aec09f4f6030fa11b9ba911e4c0df2fe7485b2 (patch) | |
tree | 3f2fbc49f76264fefaa8ceccbeacbde1b7ddaae7 | |
parent | b0dbd67d7b95cb4c74a502e04b68e3b3f9dc8e6b (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.cpp | 4 | ||||
-rw-r--r-- | src/plugins/renderers/rhi/renderer/renderview.cpp | 4 | ||||
-rw-r--r-- | src/render/geometry/geometryrenderer.cpp | 4 | ||||
-rw-r--r-- | src/render/geometry/geometryrenderer_p.h | 2 | ||||
-rw-r--r-- | src/render/geometry/qgeometryrenderer.cpp | 65 | ||||
-rw-r--r-- | src/render/geometry/qgeometryrenderer.h | 6 | ||||
-rw-r--r-- | src/render/geometry/qgeometryrenderer_p.h | 1 | ||||
-rw-r--r-- | tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp | 14 | ||||
-rw-r--r-- | tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp | 10 |
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() |