summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-19 21:55:16 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-19 21:55:23 +0200
commitd51dad630e0afb6ddca19ee61dd1ddf424fb49c2 (patch)
tree1ca0630bfb8af983950621399dbd4d0863afa568 /src
parentc8dab9f129ba838988e2c0ae67071a0197e75045 (diff)
parent471ea347fde07cf5e48c586c47bf066220dc78c2 (diff)
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'src')
-rw-r--r--src/animation/backend/animationutils.cpp3
-rw-r--r--src/core/aspects/qaspectengine.cpp1
-rw-r--r--src/core/aspects/qaspectmanager.cpp9
-rw-r--r--src/core/aspects/qaspectmanager_p.h4
-rw-r--r--src/core/jobs/qthreadpooler.cpp2
-rw-r--r--src/core/jobs/task.cpp2
-rw-r--r--src/core/nodes/qentity.cpp8
-rw-r--r--src/core/nodes/qnode_p.h2
-rw-r--r--src/core/transforms/qjoint.cpp14
-rw-r--r--src/core/transforms/qtransform.cpp13
-rw-r--r--src/core/transforms/qtransform.h1
-rw-r--r--src/core/transforms/qtransform_p.h2
-rw-r--r--src/extras/defaults/qforwardrenderer.cpp2
-rw-r--r--src/extras/defaults/qforwardrenderer.h2
-rw-r--r--src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp1
-rw-r--r--src/quick3d/imports/render/qt3dquick3drenderplugin.cpp3
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2d.cpp2
-rw-r--r--src/render/backend/entity.cpp114
-rw-r--r--src/render/backend/entity_p.h4
-rw-r--r--src/render/backend/transform.cpp33
-rw-r--r--src/render/backend/transform_p.h3
-rw-r--r--src/render/frontend/qrenderaspect.cpp34
-rw-r--r--src/render/geometry/armature.cpp32
-rw-r--r--src/render/geometry/armature_p.h4
-rw-r--r--src/render/geometry/attribute.cpp114
-rw-r--r--src/render/geometry/attribute_p.h4
-rw-r--r--src/render/geometry/buffer.cpp86
-rw-r--r--src/render/geometry/buffer_p.h3
-rw-r--r--src/render/geometry/geometry.cpp56
-rw-r--r--src/render/geometry/geometry_p.h4
-rw-r--r--src/render/geometry/geometryrenderer.cpp122
-rw-r--r--src/render/geometry/geometryrenderer_p.h4
-rw-r--r--src/render/geometry/joint.cpp71
-rw-r--r--src/render/geometry/joint_p.h3
-rw-r--r--src/render/geometry/qattribute.cpp13
-rw-r--r--src/render/geometry/qbuffer.cpp16
-rw-r--r--src/render/geometry/qgeometry.cpp12
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp7
-rw-r--r--src/render/geometry/skeleton.cpp100
-rw-r--r--src/render/geometry/skeleton_p.h2
-rw-r--r--src/render/lights/environmentlight.cpp14
-rw-r--r--src/render/lights/environmentlight_p.h3
-rw-r--r--src/render/lights/light.cpp16
-rw-r--r--src/render/lights/light_p.h4
-rw-r--r--src/render/materialsystem/effect.cpp53
-rw-r--r--src/render/materialsystem/effect_p.h4
-rw-r--r--src/render/materialsystem/material.cpp59
-rw-r--r--src/render/materialsystem/material_p.h4
-rw-r--r--src/render/materialsystem/parameter.cpp47
-rw-r--r--src/render/materialsystem/parameter_p.h5
-rw-r--r--src/render/materialsystem/qeffect.cpp25
-rw-r--r--src/render/materialsystem/qgraphicsapifilter.cpp5
-rw-r--r--src/render/materialsystem/qgraphicsapifilter_p.h1
-rw-r--r--src/render/materialsystem/qmaterial.cpp12
-rw-r--r--src/render/materialsystem/qrenderpass.cpp42
-rw-r--r--src/render/materialsystem/qtechnique.cpp50
-rw-r--r--src/render/materialsystem/qtechnique.h3
-rw-r--r--src/render/materialsystem/renderpass.cpp69
-rw-r--r--src/render/materialsystem/renderpass_p.h4
-rw-r--r--src/render/materialsystem/technique.cpp90
-rw-r--r--src/render/materialsystem/technique_p.h4
-rw-r--r--src/render/picking/qpickevent.cpp8
-rw-r--r--src/render/picking/qpickevent.h4
-rw-r--r--src/render/renderers/opengl/renderer/commandthread.cpp2
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp20
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h2
-rw-r--r--src/render/renderstates/qdepthrange.cpp4
-rw-r--r--src/render/texture/qabstracttexture.cpp36
-rw-r--r--src/render/texture/qabstracttexture_p.h2
-rw-r--r--src/render/texture/qabstracttextureimage.cpp7
-rw-r--r--src/render/texture/qtexturedataupdate.cpp1
-rw-r--r--src/render/texture/texture.cpp122
-rw-r--r--src/render/texture/texture_p.h1
73 files changed, 691 insertions, 944 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index 92e614236..24c484dc2 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -453,6 +453,7 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
break;
}
} else {
+ // TODOSYNC remove once we've found a way to propagate animation changes
// Construct a property update change, set target, property and delivery options
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
@@ -469,6 +470,7 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
skeleton->sendLocalPoses();
if (isValidNormalizedTime(normalizedLocalTime)) {
+ // TODOSYNC remove once we've found a way to propagate animation changes
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("normalizedTime");
@@ -479,6 +481,7 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
// If it's the final frame, notify the frontend that we've stopped
if (finalFrame) {
+ // TODOSYNC remove once we've found a way to propagate animation changes
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("running");
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index 6d1a8ca30..426741a61 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -275,6 +275,7 @@ void QAspectEnginePrivate::initialize()
arbiter->setPostman(m_postman);
arbiter->setScene(m_scene);
m_initialized = true;
+ m_aspectManager->setPostConstructorInit(m_scene->postConstructorInit());
#if QT_CONFIG(qt3d_profile_jobs)
m_commandDebugger->setAspectEngine(q_func());
m_commandDebugger->initialize();
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index 6bca77a9e..a33f771e9 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -374,6 +374,11 @@ QServiceLocator *QAspectManager::serviceLocator() const
return m_serviceLocator.data();
}
+void QAspectManager::setPostConstructorInit(NodePostConstructorInit *postConstructorInit)
+{
+ m_postConstructorInit = postConstructorInit;
+}
+
/*!
\internal
\brief Drives the Qt3D simulation loop in the main thread
@@ -429,6 +434,10 @@ void QAspectManager::processFrame()
changeArbiterStats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
#endif
+ // Tell the NodePostConstructorInit to process any pending nodes which will add them to our list of
+ // tree changes
+ m_postConstructorInit->processNodes();
+
// Add and Remove Nodes
const QVector<NodeTreeChange> nodeTreeChanges = std::move(m_nodeTreeChanges);
for (const NodeTreeChange &change : nodeTreeChanges) {
diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h
index b39ad1f89..38ddbc55d 100644
--- a/src/core/aspects/qaspectmanager_p.h
+++ b/src/core/aspects/qaspectmanager_p.h
@@ -74,6 +74,7 @@ class QChangeArbiter;
class QAbstractAspect;
class QAbstractAspectJobManager;
class QServiceLocator;
+class NodePostConstructorInit;
struct NodeTreeChange;
class Q_3DCORE_PRIVATE_EXPORT QAspectManager : public QObject
@@ -105,6 +106,7 @@ public:
QAbstractAspectJobManager *jobManager() const;
QChangeArbiter *changeArbiter() const;
QServiceLocator *serviceLocator() const;
+ void setPostConstructorInit(NodePostConstructorInit *postConstructorInit);
private:
bool event(QEvent *event) override;
@@ -121,6 +123,8 @@ private:
bool m_simulationLoopRunning;
QAspectEngine::RunMode m_driveMode;
QVector<NodeTreeChange> m_nodeTreeChanges;
+ NodePostConstructorInit* m_postConstructorInit;
+
};
} // namespace Qt3DCore
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index 0e9af58dd..a9f4e7a31 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -183,7 +183,7 @@ int QThreadPooler::currentCount() const
{
// The caller have to set the mutex
- return m_taskCount.load();
+ return m_taskCount.loadRelaxed();
}
int QThreadPooler::maxThreadCount() const
diff --git a/src/core/jobs/task.cpp b/src/core/jobs/task.cpp
index 4291a4779..091aabfd6 100644
--- a/src/core/jobs/task.cpp
+++ b/src/core/jobs/task.cpp
@@ -118,7 +118,7 @@ void SyncTaskRunnable::run()
m_atomicCount->deref();
// Wait for the other worker threads to be done
- while (m_atomicCount->load() > 0)
+ while (m_atomicCount->loadRelaxed() > 0)
QThread::currentThread()->yieldCurrentThread();
if (m_pooler)
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp
index 546f1d670..0ff8c4646 100644
--- a/src/core/nodes/qentity.cpp
+++ b/src/core/nodes/qentity.cpp
@@ -295,13 +295,7 @@ void QEntity::onParentChanged(QObject *)
if (!d->m_hasBackendNode)
return;
- const auto parentID = parentEntity() ? parentEntity()->id() : Qt3DCore::QNodeId();
- auto parentChange = Qt3DCore::QPropertyUpdatedChangePtr::create(id());
- parentChange->setPropertyName("parentEntityUpdated");
- parentChange->setValue(QVariant::fromValue(parentID));
- const bool blocked = blockNotifications(false);
- notifyObservers(parentChange);
- blockNotifications(blocked);
+ d->update();
}
} // namespace Qt3DCore
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index 491059ff9..d8310731c 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -194,7 +194,7 @@ public:
void removeNode(QNode *node);
void addNode(QNode *node);
-private Q_SLOTS:
+public Q_SLOTS:
void processNodes();
private:
diff --git a/src/core/transforms/qjoint.cpp b/src/core/transforms/qjoint.cpp
index 017773ff6..553fbd654 100644
--- a/src/core/transforms/qjoint.cpp
+++ b/src/core/transforms/qjoint.cpp
@@ -352,11 +352,8 @@ void QJoint::addChildJoint(QJoint *joint)
// Ensures proper bookkeeping
d->registerDestructionHelper(joint, &QJoint::removeChildJoint, d->m_childJoints);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), joint);
- change->setPropertyName("childJoint");
- d->notifyObservers(change);
- }
+ if (d->m_changeArbiter != nullptr)
+ d->update();
}
}
@@ -369,11 +366,8 @@ void QJoint::removeChildJoint(QJoint *joint)
Q_D(QJoint);
if (d->m_childJoints.contains(joint)) {
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), joint);
- change->setPropertyName("childJoint");
- d->notifyObservers(change);
- }
+ if (d->m_changeArbiter != nullptr)
+ d->update();
d->m_childJoints.removeOne(joint);
diff --git a/src/core/transforms/qtransform.cpp b/src/core/transforms/qtransform.cpp
index bedf108f2..e5902f11f 100644
--- a/src/core/transforms/qtransform.cpp
+++ b/src/core/transforms/qtransform.cpp
@@ -239,12 +239,13 @@ QTransform::QTransform(QTransformPrivate &dd, QNode *parent)
*/
void QTransform::sceneChangeEvent(const QSceneChangePtr &change)
{
+ Q_D(QTransform);
switch (change->type()) {
case PropertyUpdated: {
Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
if (propertyChange->propertyName() == QByteArrayLiteral("worldMatrix")) {
const bool blocked = blockNotifications(true);
- setWorldMatrix(propertyChange->value().value<QMatrix4x4>());
+ d->setWorldMatrix(propertyChange->value().value<QMatrix4x4>());
blockNotifications(blocked);
}
break;
@@ -254,13 +255,13 @@ void QTransform::sceneChangeEvent(const QSceneChangePtr &change)
}
}
-void QTransform::setWorldMatrix(const QMatrix4x4 &worldMatrix)
+void QTransformPrivate::setWorldMatrix(const QMatrix4x4 &worldMatrix)
{
- Q_D(QTransform);
- if (d->m_worldMatrix == worldMatrix)
+ Q_Q(QTransform);
+ if (m_worldMatrix == worldMatrix)
return;
- d->m_worldMatrix = worldMatrix;
- emit worldMatrixChanged(worldMatrix);
+ m_worldMatrix = worldMatrix;
+ emit q->worldMatrixChanged(worldMatrix);
}
void QTransform::setMatrix(const QMatrix4x4 &m)
diff --git a/src/core/transforms/qtransform.h b/src/core/transforms/qtransform.h
index 527760df7..503ea4d4a 100644
--- a/src/core/transforms/qtransform.h
+++ b/src/core/transforms/qtransform.h
@@ -120,7 +120,6 @@ Q_SIGNALS:
protected:
explicit QTransform(QTransformPrivate &dd, QNode *parent = nullptr);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
- void setWorldMatrix(const QMatrix4x4 &worldMatrix);
private:
Q_DECLARE_PRIVATE(QTransform)
diff --git a/src/core/transforms/qtransform_p.h b/src/core/transforms/qtransform_p.h
index d44e5e157..028a9aba7 100644
--- a/src/core/transforms/qtransform_p.h
+++ b/src/core/transforms/qtransform_p.h
@@ -77,6 +77,8 @@ public:
mutable bool m_matrixDirty;
QMatrix4x4 m_worldMatrix;
+
+ void setWorldMatrix(const QMatrix4x4 &worldMatrix);
};
struct QTransformData
diff --git a/src/extras/defaults/qforwardrenderer.cpp b/src/extras/defaults/qforwardrenderer.cpp
index 22a471cec..dd3c872cc 100644
--- a/src/extras/defaults/qforwardrenderer.cpp
+++ b/src/extras/defaults/qforwardrenderer.cpp
@@ -239,11 +239,13 @@ QColor QForwardRenderer::clearColor() const
\qmlproperty color ForwardRenderer::clearBuffers
Holds the current buffers to be cleared. Default value is ColorDepthBuffer
+ \since 5.14
*/
/*!
\property QForwardRenderer::clearBuffers
Holds the current buffers to be cleared. Default value is ColorDepthBuffer
+ \since 5.14
*/
QClearBuffers::BufferType QForwardRenderer::clearBuffers() const
{
diff --git a/src/extras/defaults/qforwardrenderer.h b/src/extras/defaults/qforwardrenderer.h
index 6d01a0ded..0b53a094b 100644
--- a/src/extras/defaults/qforwardrenderer.h
+++ b/src/extras/defaults/qforwardrenderer.h
@@ -61,7 +61,7 @@ class Q_3DEXTRASSHARED_EXPORT QForwardRenderer : public Qt3DRender::QTechniqueFi
Q_PROPERTY(QObject *window READ surface WRITE setSurface NOTIFY surfaceChanged)
Q_PROPERTY(QRectF viewportRect READ viewportRect WRITE setViewportRect NOTIFY viewportRectChanged)
Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged)
- Q_PROPERTY(Qt3DRender::QClearBuffers::BufferType clearBuffers READ clearBuffers WRITE setClearBuffers NOTIFY clearBuffersChanged)
+ Q_PROPERTY(Qt3DRender::QClearBuffers::BufferType clearBuffers READ clearBuffers WRITE setClearBuffers NOTIFY clearBuffersChanged REVISION 14)
Q_PROPERTY(Qt3DCore::QEntity *camera READ camera WRITE setCamera NOTIFY cameraChanged)
Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize WRITE setExternalRenderTargetSize NOTIFY externalRenderTargetSizeChanged)
Q_PROPERTY(bool frustumCulling READ isFrustumCullingEnabled WRITE setFrustumCullingEnabled NOTIFY frustumCullingEnabledChanged)
diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
index 91ec85795..b675ec283 100644
--- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
+++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
@@ -87,6 +87,7 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
// Framegraphs
qmlRegisterType<Qt3DExtras::QForwardRenderer>(uri, 2, 0, "ForwardRenderer");
qmlRegisterType<Qt3DExtras::QForwardRenderer, 9>(uri, 2, 9, "ForwardRenderer");
+ qmlRegisterType<Qt3DExtras::QForwardRenderer, 14>(uri, 2, 14, "ForwardRenderer");
// Entities
qmlRegisterType<Qt3DExtras::QSkyboxEntity>(uri, 2, 0, "SkyboxEntity");
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
index ce19d35ed..e16314c8e 100644
--- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
+++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
@@ -239,6 +239,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DRender::QObjectPicker, 9>(uri, 2, 9, "ObjectPicker");
qmlRegisterType<Qt3DRender::QObjectPicker, 13>(uri, 2, 13, "ObjectPicker");
qmlRegisterUncreatableType<Qt3DRender::QPickEvent>(uri, 2, 0, "PickEvent", QStringLiteral("Events cannot be created"));
+ qmlRegisterUncreatableType<Qt3DRender::QPickEvent, 14>(uri, 2, 14, "PickEvent", QStringLiteral("Events cannot be created"));
qmlRegisterType<Qt3DRender::Render::Quick::Quick3DRayCaster>(uri, 2, 11, "RayCaster");
qmlRegisterType<Qt3DRender::Render::Quick::Quick3DScreenRayCaster>(uri, 2, 11, "ScreenRayCaster");
@@ -297,7 +298,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DRender::QBlendEquationArguments>(uri, 2, 0, "BlendEquationArguments");
qmlRegisterType<Qt3DRender::QBlendEquation>(uri, 2, 0, "BlendEquation");
qmlRegisterType<Qt3DRender::QAlphaTest>(uri, 2, 0, "AlphaTest");
- qmlRegisterType<Qt3DRender::QDepthRange>(uri, 2, 13, "DepthRange");
+ qmlRegisterType<Qt3DRender::QDepthRange>(uri, 2, 14, "DepthRange");
qmlRegisterType<Qt3DRender::QDepthTest>(uri, 2, 0, "DepthTest");
qmlRegisterType<Qt3DRender::QMultiSampleAntiAliasing>(uri, 2, 0, "MultiSampleAntiAliasing");
qmlRegisterType<Qt3DRender::QNoDepthMask>(uri, 2, 0, "NoDepthMask");
diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp
index 27ab7f010..562f0d2c7 100644
--- a/src/quick3d/quick3dscene2d/items/scene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp
@@ -443,7 +443,7 @@ void Scene2D::cleanup()
}
if (m_renderThread) {
renderThreadClientCount->fetchAndSubAcquire(1);
- if (renderThreadClientCount->load() == 0)
+ if (renderThreadClientCount->loadRelaxed() == 0)
renderThread->quit();
}
}
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index bf128b508..d8520a97e 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -145,44 +145,6 @@ void Entity::setHandle(HEntity handle)
m_handle = handle;
}
-void Entity::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<QNodeCreatedChange<Qt3DCore::QEntityData>>(change);
- const auto &data = typedChange->data;
-
- // Note this is *not* the parentId as that is the ID of the parent QNode, which is not
- // necessarily the same as the parent QEntity (which may be further up the tree).
- m_parentEntityId = data.parentEntityId;
- qCDebug(Render::RenderNodes) << "Creating Entity id =" << peerId() << "parentId =" << m_parentEntityId;
-
- // TODO: Store string id instead and only in debug mode
- //m_objectName = peer->objectName();
- m_worldTransform = m_nodeManagers->worldMatrixManager()->getOrAcquireHandle(peerId());
-
- // TODO: Suboptimal -> Maybe have a Hash<QComponent, QEntityList> instead
- m_transformComponent = QNodeId();
- m_materialComponent = QNodeId();
- m_cameraComponent = QNodeId();
- m_geometryRendererComponent = QNodeId();
- m_objectPickerComponent = QNodeId();
- m_boundingVolumeDebugComponent = QNodeId();
- m_computeComponent = QNodeId();
- m_layerComponents.clear();
- m_levelOfDetailComponents.clear();
- m_rayCasterComponents.clear();
- m_shaderDataComponents.clear();
- m_lightComponents.clear();
- m_environmentLightComponents.clear();
- m_localBoundingVolume = QSharedPointer<Sphere>::create(peerId());
- m_worldBoundingVolume = QSharedPointer<Sphere>::create(peerId());
- m_worldBoundingVolumeWithChildren = QSharedPointer<Sphere>::create(peerId());
-
- for (const auto &idAndType : qAsConst(data.componentIdsAndTypes))
- addComponent(idAndType);
-
- markDirty(AbstractRenderer::EntityHierarchyDirty);
-}
-
void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
switch (e->type()) {
@@ -192,7 +154,6 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const auto componentIdAndType = QNodeIdTypePair(change->componentId(), change->componentMetaObject());
addComponent(componentIdAndType);
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Added. Id =" << change->componentId();
- markDirty(AbstractRenderer::AllDirty);
break;
}
@@ -200,27 +161,6 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QComponentRemovedChangePtr change = qSharedPointerCast<QComponentRemovedChange>(e);
removeComponent(change->componentId());
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Removed. Id =" << change->componentId();
- markDirty(AbstractRenderer::AllDirty);
- break;
- }
-
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("enabled")) {
- // We only mark as dirty the renderer
- markDirty(AbstractRenderer::EntityEnabledDirty);
- // We let QBackendNode::sceneChangeEvent change the enabled property
- } else if (change->propertyName() == QByteArrayLiteral("parentEntityUpdated")) {
- auto newParent = change->value().value<Qt3DCore::QNodeId>();
- qCDebug(Render::RenderNodes) << "Setting parent for " << peerId() << ", new parentId =" << newParent;
- if (m_parentEntityId != newParent) {
- m_parentEntityId = newParent;
- // TODO: change to EventHierarchyDirty and update renderer to
- // ensure all jobs are run that depend on Entity hierarchy.
- markDirty(AbstractRenderer::AllDirty);
- }
- }
-
break;
}
@@ -230,6 +170,58 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Entity::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QEntity *node = qobject_cast<const Qt3DCore::QEntity *>(frontEnd);
+ if (!node)
+ return;
+
+ if (this->isEnabled() != node->isEnabled()) {
+ markDirty(AbstractRenderer::EntityEnabledDirty);
+ // We let QBackendNode::syncFromFrontEnd change the enabled property
+ }
+
+ const auto parentID = node->parentEntity() ? node->parentEntity()->id() : Qt3DCore::QNodeId();
+ if (m_parentEntityId != parentID) {
+ m_parentEntityId = parentID;
+ // TODO: change to EventHierarchyDirty and update renderer to
+ // ensure all jobs are run that depend on Entity hierarchy.
+ markDirty(AbstractRenderer::AllDirty);
+ }
+
+ if (firstTime) {
+ m_worldTransform = m_nodeManagers->worldMatrixManager()->getOrAcquireHandle(peerId());
+
+ // TODO: Suboptimal -> Maybe have a Hash<QComponent, QEntityList> instead
+ m_transformComponent = QNodeId();
+ m_materialComponent = QNodeId();
+ m_cameraComponent = QNodeId();
+ m_geometryRendererComponent = QNodeId();
+ m_objectPickerComponent = QNodeId();
+ m_boundingVolumeDebugComponent = QNodeId();
+ m_computeComponent = QNodeId();
+ m_layerComponents.clear();
+ m_levelOfDetailComponents.clear();
+ m_rayCasterComponents.clear();
+ m_shaderDataComponents.clear();
+ m_lightComponents.clear();
+ m_environmentLightComponents.clear();
+ m_localBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolumeWithChildren = QSharedPointer<Sphere>::create(peerId());
+
+ const QComponentVector &components = node->components();
+ for (QComponent *c : components) {
+ const auto idAndType = QNodeIdTypePair(c->id(), QNodePrivate::findStaticMetaObject(c->metaObject()));
+ addComponent(idAndType);
+ }
+
+ markDirty(AbstractRenderer::EntityHierarchyDirty);
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
void Entity::dump() const
{
static int depth = 0;
@@ -358,6 +350,7 @@ void Entity::addComponent(Qt3DCore::QNodeIdTypePair idAndType)
} else if (type->inherits(&QArmature::staticMetaObject)) {
m_armatureComponent = id;
}
+ markDirty(AbstractRenderer::AllDirty);
}
void Entity::removeComponent(Qt3DCore::QNodeId nodeId)
@@ -392,6 +385,7 @@ void Entity::removeComponent(Qt3DCore::QNodeId nodeId)
} else if (m_armatureComponent == nodeId) {
m_armatureComponent = QNodeId();
}
+ markDirty(AbstractRenderer::AllDirty);
}
bool Entity::isBoundingVolumeDirty() const
diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h
index b4c9541f2..493774feb 100644
--- a/src/render/backend/entity_p.h
+++ b/src/render/backend/entity_p.h
@@ -90,6 +90,7 @@ public:
void setParentHandle(HEntity parentHandle);
void setNodeManagers(NodeManagers *manager);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void dump() const;
@@ -178,10 +179,7 @@ public:
return containsComponentsOfType<T>() && containsComponentsOfType<Ts, Ts2...>();
}
-
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
NodeManagers *m_nodeManagers;
HEntity m_handle;
HEntity m_parentHandle;
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 390ed4f05..6659657fa 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -68,17 +68,6 @@ void Transform::cleanup()
QBackendNode::setEnabled(false);
}
-void Transform::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QTransformData>>(change);
- const auto &data = typedChange->data;
- m_rotation = data.rotation;
- m_scale = data.scale;
- m_translation = data.translation;
- updateMatrix();
- markDirty(AbstractRenderer::TransformDirty);
-}
-
Matrix4x4 Transform::transformMatrix() const
{
return m_transformMatrix;
@@ -99,6 +88,7 @@ QVector3D Transform::translation() const
return m_translation;
}
+// TODOSYNC remove once we've found a way to propagate animation changes
void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
// TODO: Flag the matrix as dirty and update all matrices batched in a job
@@ -120,6 +110,27 @@ void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Transform::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QTransform *transform = qobject_cast<const Qt3DCore::QTransform *>(frontEnd);
+ if (!transform)
+ return;
+
+ bool dirty = m_rotation != transform->rotation();
+ m_rotation = transform->rotation();
+ dirty |= m_scale != transform->scale3D();
+ m_scale = transform->scale3D();
+ dirty |= m_translation != transform->translation();
+ m_translation = transform->translation();
+
+ if (dirty || firstTime) {
+ updateMatrix();
+ markDirty(AbstractRenderer::TransformDirty);
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
void Transform::notifyWorldTransformChanged(const Matrix4x4 &worldMatrix)
{
auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
diff --git a/src/render/backend/transform_p.h b/src/render/backend/transform_p.h
index e3bcad317..50857ac94 100644
--- a/src/render/backend/transform_p.h
+++ b/src/render/backend/transform_p.h
@@ -77,12 +77,11 @@ public:
QVector3D translation() const;
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) final;
void notifyWorldTransformChanged(const Matrix4x4 &worldMatrix);
private:
void updateMatrix();
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Matrix4x4 m_transformMatrix;
QQuaternion m_rotation;
QVector3D m_scale;
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 35eff052b..f33af9ebd 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -252,8 +252,8 @@ void QRenderAspectPrivate::registerBackendTypes()
qRegisterMetaType<Qt3DRender::QViewport*>();
qRegisterMetaType<Qt3DCore::QJoint*>();
- q->registerBackendType<Qt3DCore::QEntity>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
- q->registerBackendType<Qt3DCore::QTransform>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer));
+ q->registerBackendType<Qt3DCore::QEntity, true>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<Qt3DCore::QTransform, true>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer));
q->registerBackendType<Qt3DRender::QCameraLens>(QSharedPointer<Render::CameraLensFunctor>::create(m_renderer, q));
q->registerBackendType<QLayer>(QSharedPointer<Render::NodeFunctor<Render::Layer, Render::LayerManager> >::create(m_renderer));
@@ -266,32 +266,32 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QRenderState>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer));
// Geometry + Compute
- q->registerBackendType<QAttribute>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer));
- q->registerBackendType<QBuffer>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager()));
+ q->registerBackendType<QAttribute, true>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer));
+ q->registerBackendType<QBuffer, true>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager()));
q->registerBackendType<QComputeCommand>(QSharedPointer<Render::NodeFunctor<Render::ComputeCommand, Render::ComputeCommandManager> >::create(m_renderer));
- q->registerBackendType<QGeometry>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer));
- q->registerBackendType<QGeometryRenderer>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager()));
- q->registerBackendType<Qt3DCore::QArmature>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer));
- q->registerBackendType<Qt3DCore::QAbstractSkeleton>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager(), m_nodeManagers->jointManager()));
- q->registerBackendType<Qt3DCore::QJoint>(QSharedPointer<Render::JointFunctor>::create(m_renderer, m_nodeManagers->jointManager(), m_nodeManagers->skeletonManager()));
+ q->registerBackendType<QGeometry, true>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer));
+ q->registerBackendType<QGeometryRenderer, true>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager()));
+ q->registerBackendType<Qt3DCore::QArmature, true>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer));
+ q->registerBackendType<Qt3DCore::QAbstractSkeleton, true>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager(), m_nodeManagers->jointManager()));
+ q->registerBackendType<Qt3DCore::QJoint, true>(QSharedPointer<Render::JointFunctor>::create(m_renderer, m_nodeManagers->jointManager(), m_nodeManagers->skeletonManager()));
// Textures
- q->registerBackendType<QAbstractTexture>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager()));
+ q->registerBackendType<QAbstractTexture, true>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager()));
q->registerBackendType<QAbstractTextureImage>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer,
m_nodeManagers->textureImageManager()));
// Material system
- q->registerBackendType<QEffect>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer));
+ q->registerBackendType<QEffect, true>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer));
q->registerBackendType<QFilterKey>(QSharedPointer<Render::NodeFunctor<Render::FilterKey, Render::FilterKeyManager> >::create(m_renderer));
- q->registerBackendType<QAbstractLight>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers));
- q->registerBackendType<QEnvironmentLight>(QSharedPointer<Render::NodeFunctor<Render::EnvironmentLight, Render::EnvironmentLightManager> >::create(m_renderer));
- q->registerBackendType<QMaterial>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer));
- q->registerBackendType<QParameter>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer));
- q->registerBackendType<QRenderPass>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer));
+ q->registerBackendType<QAbstractLight, true>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QEnvironmentLight, true>(QSharedPointer<Render::NodeFunctor<Render::EnvironmentLight, Render::EnvironmentLightManager> >::create(m_renderer));
+ q->registerBackendType<QMaterial, true>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer));
+ q->registerBackendType<QParameter, true>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer));
+ q->registerBackendType<QRenderPass, true>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer));
q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer));
q->registerBackendType<QShaderProgramBuilder>(QSharedPointer<Render::NodeFunctor<Render::ShaderBuilder, Render::ShaderBuilderManager> >::create(m_renderer));
- q->registerBackendType<QTechnique>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QTechnique, true>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderImage>(QSharedPointer<Render::NodeFunctor<Render::ShaderImage, Render::ShaderImageManager>>::create(m_renderer));
// Framegraph
diff --git a/src/render/geometry/armature.cpp b/src/render/geometry/armature.cpp
index 15a26c9ec..cfa2e572a 100644
--- a/src/render/geometry/armature.cpp
+++ b/src/render/geometry/armature.cpp
@@ -36,6 +36,8 @@
#include "armature_p.h"
+#include <Qt3DCore/qarmature.h>
+#include <Qt3DCore/qabstractskeleton.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qarmature_p.h>
@@ -52,32 +54,20 @@ Armature::Armature()
{
}
-void Armature::cleanup()
+void Armature::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- m_skeletonId = Qt3DCore::QNodeId();
- setEnabled(false);
-}
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QArmature *node = qobject_cast<const QArmature *>(frontEnd);
+ if (!node)
+ return;
-void Armature::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<QNodeCreatedChange<QArmatureData>>(change);
- m_skeletonId = typedChange->data.skeletonId;
+ m_skeletonId = node->skeleton() ? node->skeleton()->id() : QNodeId{};
}
-void Armature::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Armature::cleanup()
{
- switch (e->type()) {
- case Qt3DCore::PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("skeleton"))
- m_skeletonId = change->value().value<QNodeId>();
- break;
- }
-
- default:
- break;
- }
- QBackendNode::sceneChangeEvent(e);
+ m_skeletonId = Qt3DCore::QNodeId();
+ setEnabled(false);
}
} // namespace Render
diff --git a/src/render/geometry/armature_p.h b/src/render/geometry/armature_p.h
index 3e6e52a3f..39baa4a79 100644
--- a/src/render/geometry/armature_p.h
+++ b/src/render/geometry/armature_p.h
@@ -63,7 +63,7 @@ class Q_AUTOTEST_EXPORT Armature : public BackendNode
public:
Armature();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void cleanup();
Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; }
@@ -73,8 +73,6 @@ public:
const UniformValue &skinningPaletteUniform() const { return m_skinningPaletteUniform; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_skeletonId;
UniformValue m_skinningPaletteUniform;
};
diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp
index bc6b27851..f241a85e5 100644
--- a/src/render/geometry/attribute.cpp
+++ b/src/render/geometry/attribute.cpp
@@ -83,78 +83,54 @@ void Attribute::cleanup()
m_nameId = 0;
}
-void Attribute::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Attribute::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QAttributeData>>(change);
- const auto &data = typedChange->data;
- m_bufferId = data.bufferId;
- m_name = data.name;
- m_nameId = StringToInt::lookupId(m_name);
- m_vertexBaseType = data.vertexBaseType;
- m_vertexSize = data.vertexSize;
- m_count = data.count;
- m_byteStride = data.byteStride;
- m_byteOffset = data.byteOffset;
- m_divisor = data.divisor;
- m_attributeType = data.attributeType;
- m_attributeDirty = true;
-}
-
-/*!
- \fn Qt3DRender::QAttribute::dataSizeChanged(uint vertexSize)
-
- The signal is emitted with \a vertexSize when the dataSize changes.
-
-*/
-/*!
- \fn Qt3DRender::QAttribute::dataTypeChanged(Qt3DRender::QAttribute::VertexBaseType vertexBaseType)
-
- The signal is emitted with \a vertexBaseType when the dataType changed.
-*/
-void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
-
- if (propertyName == QByteArrayLiteral("name")) {
- m_name = propertyChange->value().toString();
- m_nameId = StringToInt::lookupId(m_name);
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexBaseType")) {
- m_vertexBaseType = static_cast<QAttribute::VertexBaseType>(propertyChange->value().value<int>());
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexSize")) {
- m_vertexSize = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("count")) {
- m_count = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("byteStride")) {
- m_byteStride = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("byteOffset")) {
- m_byteOffset = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("divisor")) {
- m_divisor = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("attributeType")) {
- m_attributeType = static_cast<QAttribute::AttributeType>(propertyChange->value().value<int>());
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("buffer")) {
- m_bufferId = propertyChange->value().value<QNodeId>();
- m_attributeDirty = true;
- }
- markDirty(AbstractRenderer::AllDirty);
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAttribute *node = qobject_cast<const QAttribute *>(frontEnd);
+ if (!node)
+ return;
+
+ m_attributeDirty = firstTime;
+ if (m_name != node->name()) {
+ m_name = node->name();
+ m_nameId = StringToInt::lookupId(m_name);
+ m_attributeDirty = true;
}
-
- default:
- break;
+ if (m_vertexBaseType != node->vertexBaseType()) {
+ m_vertexBaseType = node->vertexBaseType();
+ m_attributeDirty = true;
}
- BackendNode::sceneChangeEvent(e);
+ if (m_vertexSize != node->vertexSize()) {
+ m_vertexSize = node->vertexSize();
+ m_attributeDirty = true;
+ }
+ if (m_count != node->count()) {
+ m_count = node->count();
+ m_attributeDirty = true;
+ }
+ if (m_byteStride != node->byteStride()) {
+ m_byteStride = node->byteStride();
+ m_attributeDirty = true;
+ }
+ if (m_byteOffset != node->byteOffset()) {
+ m_byteOffset = node->byteOffset();
+ m_attributeDirty = true;
+ }
+ if (m_divisor != node->divisor()) {
+ m_divisor = node->divisor();
+ m_attributeDirty = true;
+ }
+ if (m_attributeType != node->attributeType()) {
+ m_attributeType = node->attributeType();
+ m_attributeDirty = true;
+ }
+ const auto bufferId = node->buffer() ? node->buffer()->id() : QNodeId{};
+ if (bufferId != m_bufferId) {
+ m_bufferId = bufferId;
+ m_attributeDirty = true;
+ }
+
+ markDirty(AbstractRenderer::AllDirty);
}
void Attribute::unsetDirty()
diff --git a/src/render/geometry/attribute_p.h b/src/render/geometry/attribute_p.h
index e01537605..4b47146e1 100644
--- a/src/render/geometry/attribute_p.h
+++ b/src/render/geometry/attribute_p.h
@@ -68,7 +68,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline Qt3DCore::QNodeId bufferId() const { return m_bufferId; }
inline QString name() const { return m_name; }
@@ -84,8 +84,6 @@ public:
void unsetDirty();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_bufferId;
QString m_name;
int m_nameId;
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index d60f89c7d..998db3640 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -113,28 +113,6 @@ void Buffer::updateDataFromGPUToCPU(QByteArray data)
notifyObservers(e);
}
-void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBufferData>>(change);
- const auto &data = typedChange->data;
- m_data = data.data;
- m_usage = data.usage;
- m_syncData = data.syncData;
- m_access = data.access;
- m_bufferDirty = true;
-
- if (!m_data.isEmpty())
- forceDataUpload();
-
- m_functor = data.functor;
- Q_ASSERT(m_manager);
- if (m_functor)
- m_manager->addDirtyBuffer(peerId());
-
- m_manager->addBufferReference(peerId());
- markDirty(AbstractRenderer::BuffersDirty);
-}
-
void Buffer::forceDataUpload()
{
// We push back an update with offset = -1
@@ -145,40 +123,50 @@ void Buffer::forceDataUpload()
m_bufferUpdates.push_back(updateNewData);
}
-void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Buffer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
- if (propertyName == QByteArrayLiteral("data")) {
- QByteArray newData = propertyChange->value().toByteArray();
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QBuffer *node = qobject_cast<const QBuffer *>(frontEnd);
+ if (!node)
+ return;
+
+ if (firstTime && m_manager != nullptr)
+ m_manager->addBufferReference(peerId());
+
+ m_syncData = node->isSyncData();
+ m_access = node->accessType();
+ if (m_usage != node->usage()) {
+ m_usage = node->usage();
+ m_bufferDirty = true;
+ }
+ {
+ QBufferDataGeneratorPtr newGenerator = node->dataGenerator();
+ bool dirty = (newGenerator && m_functor && !(*newGenerator == *m_functor)) ||
+ (newGenerator.isNull() && !m_functor.isNull()) ||
+ (!newGenerator.isNull() && m_functor.isNull());
+ m_bufferDirty |= dirty;
+ m_functor = newGenerator;
+ if (m_functor && m_manager != nullptr)
+ m_manager->addDirtyBuffer(peerId());
+ }
+ {
+ QVariant v = node->property("QT3D_updateData");
+ if (v.isValid()) {
+ Qt3DRender::QBufferUpdate updateData = v.value<Qt3DRender::QBufferUpdate>();
+ m_data.replace(updateData.offset, updateData.data.size(), updateData.data);
+ m_bufferUpdates.push_back(updateData);
+ m_bufferDirty = true;
+ const_cast<QBuffer *>(node)->setProperty("QT3D_updateData", {});
+ } else {
+ QByteArray newData = node->data();
bool dirty = m_data != newData;
m_bufferDirty |= dirty;
m_data = newData;
- if (dirty)
+ if (dirty && !m_data.isEmpty())
forceDataUpload();
- } else if (propertyName == QByteArrayLiteral("updateData")) {
- Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>();
- m_data.replace(updateData.offset, updateData.data.size(), updateData.data);
- m_bufferUpdates.push_back(updateData);
- m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("usage")) {
- m_usage = static_cast<QBuffer::UsageType>(propertyChange->value().value<int>());
- m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("accessType")) {
- m_access = static_cast<QBuffer::AccessType>(propertyChange->value().value<int>());
- } else if (propertyName == QByteArrayLiteral("dataGenerator")) {
- QBufferDataGeneratorPtr newGenerator = propertyChange->value().value<QBufferDataGeneratorPtr>();
- m_bufferDirty |= !(newGenerator && m_functor && *newGenerator == *m_functor);
- m_functor = newGenerator;
- if (m_functor && m_manager != nullptr)
- m_manager->addDirtyBuffer(peerId());
- } else if (propertyName == QByteArrayLiteral("syncData")) {
- m_syncData = propertyChange->value().toBool();
}
- markDirty(AbstractRenderer::BuffersDirty);
}
- BackendNode::sceneChangeEvent(e);
+ markDirty(AbstractRenderer::BuffersDirty);
}
// Called by Renderer once the buffer has been uploaded to OpenGL
diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h
index 9a171599d..a3f52d1b3 100644
--- a/src/render/geometry/buffer_p.h
+++ b/src/render/geometry/buffer_p.h
@@ -73,7 +73,7 @@ public:
~Buffer();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void setManager(BufferManager *manager);
void executeFunctor();
@@ -88,7 +88,6 @@ public:
void unsetDirty();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void forceDataUpload();
QBuffer::UsageType m_usage;
diff --git a/src/render/geometry/geometry.cpp b/src/render/geometry/geometry.cpp
index 4ee02a74d..cb401df5b 100644
--- a/src/render/geometry/geometry.cpp
+++ b/src/render/geometry/geometry.cpp
@@ -45,6 +45,8 @@
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -76,51 +78,29 @@ void Geometry::cleanup()
m_shouldNotifyMaxExtentChanged = false;
}
-void Geometry::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QGeometryData>>(change);
- const auto &data = typedChange->data;
- m_attributes = data.attributeIds;
- m_boundingPositionAttribute = data.boundingVolumePositionAttributeId;
- m_geometryDirty = true;
- markDirty(AbstractRenderer::GeometryDirty);
-}
-
-void Geometry::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Geometry::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("attribute")) {
- m_attributes.push_back(change->addedNodeId());
- m_geometryDirty = true;
- }
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("attribute")) {
- m_attributes.removeOne(change->removedNodeId());
- m_geometryDirty = true;
- }
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QGeometry *node = qobject_cast<const QGeometry *>(frontEnd);
+ if (!node)
+ return;
+
+ m_geometryDirty |= firstTime;
+
+ QNodeIdVector attribs = qIdsForNodes(node->attributes());
+ std::sort(std::begin(attribs), std::end(attribs));
+ if (m_attributes != attribs) {
+ m_attributes = attribs;
+ m_geometryDirty = true;
}
- case PropertyUpdated: {
+ if ((node->boundingVolumePositionAttribute() && node->boundingVolumePositionAttribute()->id() != m_boundingPositionAttribute) ||
// Note: doesn't set dirtyness as this parameter changing doesn't need a new VAO update.
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("boundingVolumePositionAttribute")) {
- m_boundingPositionAttribute = change->value().value<QNodeId>();
- break;
- }
+ (!node->boundingVolumePositionAttribute() && !m_boundingPositionAttribute.isNull())) {
+ m_boundingPositionAttribute = node->boundingVolumePositionAttribute() ? node->boundingVolumePositionAttribute()->id() : QNodeId{};
}
- default:
- break;
- }
markDirty(AbstractRenderer::GeometryDirty);
- BackendNode::sceneChangeEvent(e);
}
void Geometry::unsetDirty()
diff --git a/src/render/geometry/geometry_p.h b/src/render/geometry/geometry_p.h
index e66524787..429a577b0 100644
--- a/src/render/geometry/geometry_p.h
+++ b/src/render/geometry/geometry_p.h
@@ -68,7 +68,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline QVector<Qt3DCore::QNodeId> attributes() const { return m_attributes; }
inline bool isDirty() const { return m_geometryDirty; }
@@ -82,8 +82,6 @@ public:
void notifyExtentChanged();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DCore::QNodeId> m_attributes;
bool m_geometryDirty;
Qt3DCore::QNodeId m_boundingPositionAttribute;
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index ea059c6ee..b5c741659 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -105,95 +105,47 @@ void GeometryRenderer::setManager(GeometryRendererManager *manager)
m_manager = manager;
}
-void GeometryRenderer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void GeometryRenderer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QGeometryRendererData>>(change);
- const auto &data = typedChange->data;
- m_geometryId = data.geometryId;
- m_instanceCount = data.instanceCount;
- m_vertexCount = data.vertexCount;
- m_indexOffset = data.indexOffset;
- m_firstInstance = data.firstInstance;
- m_firstVertex = data.firstVertex;
- m_indexBufferByteOffset = data.indexBufferByteOffset;
- m_restartIndexValue = data.restartIndexValue;
- m_verticesPerPatch = data.verticesPerPatch;
- m_primitiveRestartEnabled = data.primitiveRestart;
- m_primitiveType = data.primitiveType;
-
- Q_ASSERT(m_manager);
- m_geometryFactory = data.geometryFactory;
- if (m_geometryFactory)
- m_manager->addDirtyGeometryRenderer(peerId());
-
- m_dirty = true;
- markDirty(AbstractRenderer::GeometryDirty);
-}
-
-void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
-
- if (propertyName == QByteArrayLiteral("instanceCount")) {
- m_instanceCount = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexCount")) {
- m_vertexCount = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("indexOffset")) {
- m_indexOffset = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("firstInstance")) {
- m_firstInstance = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("firstVertex")) {
- m_firstVertex = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("indexBufferByteOffset")) {
- m_indexBufferByteOffset = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("restartIndexValue")) {
- m_restartIndexValue = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("verticesPerPatch")) {
- m_verticesPerPatch = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("primitiveRestartEnabled")) {
- m_primitiveRestartEnabled = propertyChange->value().toBool();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("primitiveType")) {
- m_primitiveType = static_cast<QGeometryRenderer::PrimitiveType>(propertyChange->value().value<int>());
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("geometryFactory")) {
- QGeometryFactoryPtr newFunctor = propertyChange->value().value<QGeometryFactoryPtr>();
- const bool functorDirty = ((m_geometryFactory && !newFunctor)
- || (!m_geometryFactory && newFunctor)
- || (m_geometryFactory && newFunctor && !(*newFunctor == *m_geometryFactory)));
- m_dirty |= functorDirty;
- if (functorDirty) {
- m_geometryFactory = newFunctor;
- if (m_geometryFactory && m_manager != nullptr)
- m_manager->addDirtyGeometryRenderer(peerId());
- }
- } else if (propertyName == QByteArrayLiteral("geometry")) {
- m_geometryId = propertyChange->value().value<Qt3DCore::QNodeId>();
- m_dirty = true;
- }
- break;
- }
-
- default:
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QGeometryRenderer *node = qobject_cast<const QGeometryRenderer *>(frontEnd);
+ if (!node)
+ return;
+
+ m_dirty |= m_instanceCount != node->instanceCount();
+ m_instanceCount = node->instanceCount();
+ m_dirty |= m_vertexCount != node->vertexCount();
+ m_vertexCount = node->vertexCount();
+ m_dirty |= m_indexOffset != node->indexOffset();
+ m_indexOffset = node->indexOffset();
+ m_dirty |= m_firstInstance != node->firstInstance();
+ m_firstInstance = node->firstInstance();
+ m_dirty |= m_firstVertex != node->firstVertex();
+ m_firstVertex = node->firstVertex();
+ m_dirty |= m_indexBufferByteOffset != node->indexBufferByteOffset();
+ m_indexBufferByteOffset = node->indexBufferByteOffset();
+ m_dirty |= m_restartIndexValue != node->restartIndexValue();
+ m_restartIndexValue = node->restartIndexValue();
+ m_dirty |= m_verticesPerPatch != node->verticesPerPatch();
+ m_verticesPerPatch = node->verticesPerPatch();
+ m_dirty |= m_primitiveRestartEnabled != node->primitiveRestartEnabled();
+ m_primitiveRestartEnabled = node->primitiveRestartEnabled();
+ m_dirty |= m_primitiveType != node->primitiveType();
+ m_primitiveType = node->primitiveType();
+ m_dirty |= (node->geometry() && m_geometryId != node->geometry()->id()) || (!node->geometry() && !m_geometryId.isNull());
+ m_geometryId = node->geometry() ? node->geometry()->id() : Qt3DCore::QNodeId();
+ QGeometryFactoryPtr newFunctor = node->geometryFactory();
+ const bool functorDirty = ((m_geometryFactory && !newFunctor)
+ || (!m_geometryFactory && newFunctor)
+ || (m_geometryFactory && newFunctor && !(*newFunctor == *m_geometryFactory)));
+ if (functorDirty) {
+ m_dirty = true;
+ m_geometryFactory = newFunctor;
+ if (m_geometryFactory && m_manager != nullptr)
+ m_manager->addDirtyGeometryRenderer(peerId());
}
markDirty(AbstractRenderer::GeometryDirty);
-
- BackendNode::sceneChangeEvent(e);
-
- // Add to dirty list in manager
}
void GeometryRenderer::executeFunctor()
diff --git a/src/render/geometry/geometryrenderer_p.h b/src/render/geometry/geometryrenderer_p.h
index 57d1ca0be..da538a00d 100644
--- a/src/render/geometry/geometryrenderer_p.h
+++ b/src/render/geometry/geometryrenderer_p.h
@@ -74,7 +74,7 @@ public:
void cleanup();
void setManager(GeometryRendererManager *manager);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void executeFunctor();
inline Qt3DCore::QNodeId geometryId() const { return m_geometryId; }
@@ -98,8 +98,6 @@ public:
QVector<RayCasting::QBoundingVolume *> triangleData() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_geometryId;
int m_instanceCount;
int m_vertexCount;
diff --git a/src/render/geometry/joint.cpp b/src/render/geometry/joint.cpp
index c770564f9..86d583f51 100644
--- a/src/render/geometry/joint.cpp
+++ b/src/render/geometry/joint.cpp
@@ -39,11 +39,14 @@
#include "joint_p.h"
#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DCore/QJoint>
#include <Qt3DCore/private/qjoint_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -69,21 +72,7 @@ void Joint::cleanup()
setEnabled(false);
}
-void Joint::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- Q_ASSERT(m_jointManager);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QJointData>>(change);
- const auto &data = typedChange->data;
- m_inverseBindMatrix = data.inverseBindMatrix;
- m_localPose.rotation = data.rotation;
- m_localPose.scale = data.scale;
- m_localPose.translation = data.translation;
- m_childJointIds = data.childJointIds;
- m_name = data.name;
- markDirty(AbstractRenderer::JointDirty);
- m_jointManager->addDirtyJoint(peerId());
-}
-
+// TODOSYNC remove once animation changes don't use messages anymore
void Joint::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
if (e->type() == PropertyUpdated) {
@@ -123,10 +112,60 @@ void Joint::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (removedChange->propertyName() == QByteArrayLiteral("childJoint"))
m_childJointIds.removeOne(removedChange->removedNodeId());
}
-
BackendNode::sceneChangeEvent(e);
}
+void Joint::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QJoint *joint = qobject_cast<const Qt3DCore::QJoint *>(frontEnd);
+ if (!joint)
+ return;
+
+ if (m_localPose.scale != joint->scale()) {
+ m_localPose.scale = joint->scale();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_localPose.rotation != joint->rotation()) {
+ m_localPose.rotation = joint->rotation();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_localPose.translation != joint->translation()) {
+ m_localPose.translation = joint->translation();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_inverseBindMatrix != joint->inverseBindMatrix()) {
+ // Setting the inverse bind matrix should be a rare operation. Usually it is
+ // set once and then remains constant for the duration of the skeleton. So just
+ // trigger a rebuild of the skeleton's SkeletonData which will include obtaining
+ // the inverse bind matrix.
+ m_inverseBindMatrix = joint->inverseBindMatrix();
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_owningSkeleton);
+ }
+ if (m_name != joint->name()) {
+ // Joint name doesn't affect anything in the render aspect so no need
+ // to mark anything as dirty.
+ m_name = joint->name();
+
+ // TODO: Notify other aspects (animation) about the name change.
+ }
+
+ Qt3DCore::QNodeIdVector childIds = qIdsForNodes(joint->childJoints());
+ std::sort(std::begin(childIds), std::end(childIds));
+ if (m_childJointIds != childIds) {
+ m_childJointIds = childIds;
+ }
+
+ if (firstTime) {
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
JointFunctor::JointFunctor(AbstractRenderer *renderer,
JointManager *jointManager,
diff --git a/src/render/geometry/joint_p.h b/src/render/geometry/joint_p.h
index e144ac489..d0530ac04 100644
--- a/src/render/geometry/joint_p.h
+++ b/src/render/geometry/joint_p.h
@@ -70,6 +70,7 @@ public:
void cleanup();
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::Sqt localPose() const { return m_localPose; }
QMatrix4x4 inverseBindMatrix() const { return m_inverseBindMatrix; }
@@ -90,8 +91,6 @@ public:
SkeletonManager *skeletonManager() const { return m_skeletonManager; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QMatrix4x4 m_inverseBindMatrix;
Qt3DCore::Sqt m_localPose;
QVector<Qt3DCore::QNodeId> m_childJointIds;
diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp
index ca467fda9..a28d0baa6 100644
--- a/src/render/geometry/qattribute.cpp
+++ b/src/render/geometry/qattribute.cpp
@@ -505,6 +505,19 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAttribute::createNodeCreationChange() const
return creationChange;
}
+
+/*!
+\fn Qt3DRender::QAttribute::dataSizeChanged(uint vertexSize)
+
+The signal is emitted with \a vertexSize when the dataSize changes.
+*/
+/*!
+\fn Qt3DRender::QAttribute::dataTypeChanged(Qt3DRender::QAttribute::VertexBaseType vertexBaseType)
+
+The signal is emitted with \a vertexBaseType when the dataType changed.
+*/
+
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index e0574a4c5..f27005f2b 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -329,7 +329,7 @@ void QBuffer::setData(const QByteArray &bytes)
Q_D(QBuffer);
if (bytes != d->m_data) {
d->m_data = bytes;
- Qt3DCore::QNodePrivate::get(this)->notifyPropertyChange("data", QVariant::fromValue(d->m_data));
+ Qt3DCore::QNodePrivate::get(this)->update();
emit dataChanged(bytes);
}
}
@@ -351,11 +351,8 @@ void QBuffer::updateData(int offset, const QByteArray &bytes)
QBufferUpdate updateData;
updateData.offset = offset;
updateData.data = bytes;
-
- auto e = QPropertyUpdatedChangePtr::create(id());
- e->setPropertyName("updateData");
- e->setValue(QVariant::fromValue(updateData));
- notifyObservers(e);
+ setProperty("QT3D_updateData", QVariant::fromValue(updateData));
+ d->update();
}
/*!
@@ -409,12 +406,7 @@ void QBuffer::setDataGenerator(const QBufferDataGeneratorPtr &functor)
if (functor && d->m_functor && *functor == *d->m_functor)
return;
d->m_functor = functor;
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("dataGenerator");
- change->setValue(QVariant::fromValue(d->m_functor));
- d->notifyObservers(change);
- }
+ d->update();
}
/*!
diff --git a/src/render/geometry/qgeometry.cpp b/src/render/geometry/qgeometry.cpp
index ec80e2657..47fad4302 100644
--- a/src/render/geometry/qgeometry.cpp
+++ b/src/render/geometry/qgeometry.cpp
@@ -196,11 +196,7 @@ void QGeometry::addAttribute(QAttribute *attribute)
if (!attribute->parent())
attribute->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), attribute);
- change->setPropertyName("attribute");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -212,14 +208,10 @@ void QGeometry::removeAttribute(QAttribute *attribute)
{
Q_ASSERT(attribute);
Q_D(QGeometry);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), attribute);
- change->setPropertyName("attribute");
- d->notifyObservers(change);
- }
d->m_attributes.removeOne(attribute);
// Remove bookkeeping connection
d->unregisterDestructionHelper(attribute);
+ d->update();
}
void QGeometry::setBoundingVolumePositionAttribute(QAttribute *boundingVolumePositionAttribute)
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index 6bff3462f..ddea873a7 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -480,12 +480,7 @@ void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory)
if (factory && d->m_geometryFactory && *factory == *d->m_geometryFactory)
return;
d->m_geometryFactory = factory;
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("geometryFactory");
- change->setValue(QVariant::fromValue(d->m_geometryFactory));
- d->notifyObservers(change);
- }
+ d->update();
}
/*!
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index 615b76c88..d4af1fe3c 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -80,39 +80,68 @@ void Skeleton::cleanup()
setEnabled(false);
}
-void Skeleton::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Skeleton::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- Q_ASSERT(m_skeletonManager);
- m_skeletonHandle = m_skeletonManager->lookupHandle(peerId());
-
- const auto skeletonCreatedChange = qSharedPointerCast<QSkeletonCreatedChangeBase>(change);
- switch (skeletonCreatedChange->type()) {
- case QSkeletonCreatedChangeBase::SkeletonLoader: {
- const auto loaderTypedChange = qSharedPointerCast<QSkeletonCreatedChange<QSkeletonLoaderData>>(change);
- const auto &data = loaderTypedChange->data;
- m_dataType = File;
- m_source = data.source;
- m_createJoints = data.createJoints;
- if (!m_source.isEmpty()) {
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractSkeleton *node = qobject_cast<const QAbstractSkeleton *>(frontEnd);
+ if (!node)
+ return;
+ const QSkeleton *skeletonNode = qobject_cast<const QSkeleton *>(frontEnd);
+ const QSkeletonLoader *loaderNode = qobject_cast<const QSkeletonLoader *>(frontEnd);
+
+ if (firstTime) {
+ m_skeletonHandle = m_skeletonManager->lookupHandle(peerId());
+
+ if (skeletonNode) {
+ m_dataType = Data;
+ m_rootJointId = skeletonNode->rootJoint()->id();
+ if (!m_rootJointId.isNull()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
+ }
+
+ if (loaderNode) {
+ m_dataType = File;
+ m_source = loaderNode->source();
+ if (!m_source.isEmpty()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
}
- break;
}
- case QSkeletonCreatedChangeBase::Skeleton:
- const auto typedChange = qSharedPointerCast<QSkeletonCreatedChange<QSkeletonData>>(change);
- const auto &data = typedChange->data;
- m_dataType = Data;
- m_rootJointId = data.rootJointId;
- if (!m_rootJointId.isNull()) {
+ if (loaderNode) {
+ if (loaderNode->source() != m_source) {
+ m_source = loaderNode->source();
markDirty(AbstractRenderer::SkeletonDataDirty);
m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
}
- break;
+ m_createJoints = loaderNode->isCreateJointsEnabled();
+
+ if ((loaderNode->rootJoint() && loaderNode->rootJoint()->id() != m_rootJointId) ||
+ (!loaderNode->rootJoint() && !m_rootJointId.isNull())) {
+ m_rootJointId = loaderNode->rootJoint() ? loaderNode->rootJoint()->id() : Qt3DCore::QNodeId{};
+
+ // If using a QSkeletonLoader to create frontend QJoints, when those joints are
+ // set on the skeleton, we end up here. In order to allow the subsequent call
+ // to loadSkeleton(), see below, to build the internal data from the frontend
+ // joints rather than from the source url again, we need to change the data type
+ // to Data.
+ m_dataType = Data;
+
+ // If the joint changes, we need to rebuild our internal SkeletonData and
+ // the relationships between joints and skeleton. Mark the skeleton data as
+ // dirty so that we get a loadSkeletonJob executed to process this skeleton.
+ if (!m_rootJointId.isNull()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
+ }
}
}
+// TODOSYNC remove once animation aspect no longer requires messages
void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
switch (e->type()) {
@@ -123,31 +152,6 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
// need to do is copy them into place. The existing jobs will then update
// the skinning matrix palette.
m_skeletonData.localPoses = change->value().value<QVector<Qt3DCore::Sqt>>();
- } else if (change->propertyName() == QByteArrayLiteral("source")) {
- Q_ASSERT(m_dataType == File);
- const auto source = change->value().toUrl();
- if (source != m_source) {
- m_source = source;
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
- }
- } else if (change->propertyName() == QByteArrayLiteral("createJointsEnabled")) {
- m_createJoints = change->value().toBool();
- } else if (change->propertyName() == QByteArrayLiteral("rootJoint")) {
- m_rootJointId = change->value().value<QNodeId>();
-
- // If using a QSkeletonLoader to create frontend QJoints, when those joints are
- // set on the skeleton, we end up here. In order to allow the subsequent call
- // to loadSkeleton(), see below, to build the internal data from the frontend
- // joints rather than from the source url again, we need to change the data type
- // to Data.
- m_dataType = Data;
-
- // If the joint changes, we need to rebuild our internal SkeletonData and
- // the relationships between joints and skeleton. Mark the skeleton data as
- // dirty so that we get a loadSkeletonJob executed to process this skeleton.
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
}
break;
diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h
index 4a14e5c1c..d71b404e5 100644
--- a/src/render/geometry/skeleton_p.h
+++ b/src/render/geometry/skeleton_p.h
@@ -85,6 +85,7 @@ public:
void cleanup();
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void setStatus(Qt3DCore::QSkeletonLoader::Status status);
Qt3DCore::QSkeletonLoader::Status status() const { return m_status; }
@@ -120,7 +121,6 @@ public:
#endif
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void loadSkeletonFromUrl();
void loadSkeletonFromData();
Qt3DCore::QJoint *createFrontendJoints(const SkeletonData &skeletonData) const;
diff --git a/src/render/lights/environmentlight.cpp b/src/render/lights/environmentlight.cpp
index d4245fb6e..20364fdfa 100644
--- a/src/render/lights/environmentlight.cpp
+++ b/src/render/lights/environmentlight.cpp
@@ -53,11 +53,17 @@ QNodeId EnvironmentLight::shaderData() const
return m_shaderDataId;
}
-void EnvironmentLight::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
+void EnvironmentLight::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEnvironmentLightData>>(change);
- const auto &data = typedChange->data;
- m_shaderDataId = data.shaderDataId;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QEnvironmentLight *node = qobject_cast<const QEnvironmentLight *>(frontEnd);
+ if (!node)
+ return;
+
+ if (firstTime) {
+ QEnvironmentLightPrivate *d = static_cast<QEnvironmentLightPrivate *>(QEnvironmentLightPrivate::get(const_cast<Qt3DCore::QNode *>(frontEnd)));
+ m_shaderDataId = d->m_shaderData ? d->m_shaderData->id() : QNodeId{};
+ }
}
} // namespace Render
diff --git a/src/render/lights/environmentlight_p.h b/src/render/lights/environmentlight_p.h
index 00d49d298..92f6ce100 100644
--- a/src/render/lights/environmentlight_p.h
+++ b/src/render/lights/environmentlight_p.h
@@ -63,10 +63,9 @@ class Q_AUTOTEST_EXPORT EnvironmentLight : public BackendNode
{
public:
Qt3DCore::QNodeId shaderData() const;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_shaderDataId;
};
diff --git a/src/render/lights/light.cpp b/src/render/lights/light.cpp
index e8474b728..30d71082b 100644
--- a/src/render/lights/light.cpp
+++ b/src/render/lights/light.cpp
@@ -58,14 +58,18 @@ QNodeId Light::shaderData() const
return m_shaderDataId;
}
-void Light::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
+void Light::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QAbstractLightData>>(change);
- const auto &data = typedChange->data;
- m_shaderDataId = data.shaderDataId;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractLight *node = qobject_cast<const QAbstractLight *>(frontEnd);
+ if (!node)
+ return;
- Q_ASSERT(m_renderer);
- BackendNode::markDirty(AbstractRenderer::LightsDirty);
+ if (firstTime) {
+ QAbstractLightPrivate *d = static_cast<QAbstractLightPrivate *>(QAbstractLightPrivate::get(const_cast<Qt3DCore::QNode *>(frontEnd)));
+ m_shaderDataId = d->m_shaderData ? d->m_shaderData->id() : QNodeId{};
+ BackendNode::markDirty(AbstractRenderer::LightsDirty);
+ }
}
RenderLightFunctor::RenderLightFunctor(AbstractRenderer *renderer, NodeManagers *managers)
diff --git a/src/render/lights/light_p.h b/src/render/lights/light_p.h
index 8ecc87585..5f5f8140e 100644
--- a/src/render/lights/light_p.h
+++ b/src/render/lights/light_p.h
@@ -66,9 +66,9 @@ class Q_AUTOTEST_EXPORT Light : public BackendNode
public:
Qt3DCore::QNodeId shaderData() const;
-private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+private:
Qt3DCore::QNodeId m_shaderDataId;
};
diff --git a/src/render/materialsystem/effect.cpp b/src/render/materialsystem/effect.cpp
index 29d05ed01..76036bd1f 100644
--- a/src/render/materialsystem/effect.cpp
+++ b/src/render/materialsystem/effect.cpp
@@ -48,6 +48,7 @@
#include <Qt3DCore/qpropertynoderemovedchange.h>
#include <QVariant>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -73,41 +74,25 @@ void Effect::cleanup()
m_techniques.clear();
}
-void Effect::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Effect::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEffectData>>(change);
- const auto &data = typedChange->data;
- m_techniques = data.techniqueIds;
- m_parameterPack.setParameters(data.parameterIds);
-}
-
-void Effect::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("technique"))
- appendRenderTechnique(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("technique"))
- m_techniques.removeOne(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
-
- default:
- break;
- }
-
- markDirty(AbstractRenderer::AllDirty);
- BackendNode::sceneChangeEvent(e);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QEffect *node = qobject_cast<const QEffect *>(frontEnd);
+ if (!node)
+ return;
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
+
+ auto techniques = qIdsForNodes(node->techniques());
+ std::sort(std::begin(techniques), std::end(techniques));
+ if (m_techniques != techniques)
+ m_techniques = techniques;
+
+ if (!firstTime)
+ markDirty(AbstractRenderer::AllDirty);
}
void Effect::appendRenderTechnique(Qt3DCore::QNodeId technique)
diff --git a/src/render/materialsystem/effect_p.h b/src/render/materialsystem/effect_p.h
index 87ff4a803..e81be2b8d 100644
--- a/src/render/materialsystem/effect_p.h
+++ b/src/render/materialsystem/effect_p.h
@@ -70,15 +70,13 @@ public:
~Effect();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void appendRenderTechnique(Qt3DCore::QNodeId t);
QVector<Qt3DCore::QNodeId> techniques() const;
QVector<Qt3DCore::QNodeId> parameters() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DCore::QNodeId> m_techniques;
ParameterPack m_parameterPack;
};
diff --git a/src/render/materialsystem/material.cpp b/src/render/materialsystem/material.cpp
index a69ff8a13..07764c207 100644
--- a/src/render/materialsystem/material.cpp
+++ b/src/render/materialsystem/material.cpp
@@ -73,47 +73,26 @@ void Material::cleanup()
m_parameterPack.clear();
}
-void Material::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Material::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QMaterialData>>(change);
- const auto &data = typedChange->data;
- m_effectUuid = data.effectId;
- m_parameterPack.setParameters(data.parameterIds);
-
- markDirty(AbstractRenderer::MaterialDirty);
-}
-
-void Material::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
-
- switch (e->type()) {
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("effect"))
- m_effectUuid = change->value().value<QNodeId>();
- break;
- }
-
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
-
- default:
- break;
- }
- markDirty(AbstractRenderer::AllDirty);
-
- BackendNode::sceneChangeEvent(e);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QMaterial *node = qobject_cast<const QMaterial *>(frontEnd);
+ if (!node)
+ return;
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
+
+ const auto effectId = node->effect() ? node->effect()->id() : QNodeId{};
+ if (effectId != m_effectUuid)
+ m_effectUuid = effectId;
+
+ if (firstTime)
+ markDirty(AbstractRenderer::MaterialDirty);
+ else
+ markDirty(AbstractRenderer::AllDirty);
}
QVector<Qt3DCore::QNodeId> Material::parameters() const
diff --git a/src/render/materialsystem/material_p.h b/src/render/materialsystem/material_p.h
index 3b55dc657..7a02c6691 100644
--- a/src/render/materialsystem/material_p.h
+++ b/src/render/materialsystem/material_p.h
@@ -79,14 +79,12 @@ public:
~Material();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QVector<Qt3DCore::QNodeId> parameters() const;
Qt3DCore::QNodeId effect() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
ParameterPack m_parameterPack;
Qt3DCore::QNodeId m_effectUuid;
};
diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp
index 86ca418aa..d32e60a2d 100644
--- a/src/render/materialsystem/parameter.cpp
+++ b/src/render/materialsystem/parameter.cpp
@@ -70,34 +70,33 @@ void Parameter::cleanup()
m_uniformValue = UniformValue();
}
-void Parameter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Parameter::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QParameterData>>(change);
- const auto &data = typedChange->data;
- m_name = data.name;
- m_nameId = StringToInt::lookupId(m_name);
- m_uniformValue = UniformValue::fromVariant(data.backendValue);
- markDirty(AbstractRenderer::ParameterDirty);
-}
+ const QParameter *node = qobject_cast<const QParameter *>(frontEnd);
+ if (!node)
+ return;
-void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
-
- if (e->type() == PropertyUpdated) {
- if (propertyChange->propertyName() == QByteArrayLiteral("name")) {
- m_name = propertyChange->value().toString();
- m_nameId = StringToInt::lookupId(m_name);
- markDirty(AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("value")) {
- m_uniformValue = UniformValue::fromVariant(propertyChange->value());
- markDirty(AbstractRenderer::ParameterDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) {
- markDirty(AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
- }
+ AbstractRenderer::BackendNodeDirtySet dirty = firstTime ? AbstractRenderer::ParameterDirty : static_cast<AbstractRenderer::BackendNodeDirtyFlag>(0);
+ if (node->isEnabled() != isEnabled())
+ dirty |= (AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
+
+ if (node->name() != m_name) {
+ m_name = node->name();
+ m_nameId = StringToInt::lookupId(m_name);
+ dirty |= (AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
}
- BackendNode::sceneChangeEvent(e);
+ QParameterPrivate* d = static_cast<QParameterPrivate *>(QParameterPrivate::get(const_cast<QParameter *>(node)));
+ if (d->m_backendValue != m_backendValue) {
+ m_backendValue = d->m_backendValue;
+ m_uniformValue = UniformValue::fromVariant(m_backendValue);
+ dirty |= (AbstractRenderer::ParameterDirty);
+ }
+
+ if (dirty)
+ markDirty(dirty);
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
}
QString Parameter::name() const
diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h
index 4ab04bc8e..9deaa11f3 100644
--- a/src/render/materialsystem/parameter_p.h
+++ b/src/render/materialsystem/parameter_p.h
@@ -71,16 +71,15 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QString name() const;
int nameId() const Q_DECL_NOTHROW { return m_nameId; }
const UniformValue &uniformValue() const { return m_uniformValue; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QString m_name;
+ QVariant m_backendValue;
UniformValue m_uniformValue;
int m_nameId;
};
diff --git a/src/render/materialsystem/qeffect.cpp b/src/render/materialsystem/qeffect.cpp
index b611657c4..35ac662fb 100644
--- a/src/render/materialsystem/qeffect.cpp
+++ b/src/render/materialsystem/qeffect.cpp
@@ -192,11 +192,7 @@ void QEffect::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -207,14 +203,10 @@ void QEffect::removeParameter(QParameter *parameter)
{
Q_D(QEffect);
- if (parameter && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
+ d->update();
}
/*!
@@ -246,11 +238,7 @@ void QEffect::addTechnique(QTechnique *t)
if (!t->parent())
t->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), t);
- change->setPropertyName("technique");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -260,11 +248,8 @@ void QEffect::addTechnique(QTechnique *t)
void QEffect::removeTechnique(QTechnique *t)
{
Q_D(QEffect);
- if (t && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), t);
- change->setPropertyName("technique");
- d->notifyObservers(change);
- }
+ if (t)
+ d->update();
d->m_techniques.removeOne(t);
// Remove bookkeeping connection
d->unregisterDestructionHelper(t);
diff --git a/src/render/materialsystem/qgraphicsapifilter.cpp b/src/render/materialsystem/qgraphicsapifilter.cpp
index 70f329172..9b5557930 100644
--- a/src/render/materialsystem/qgraphicsapifilter.cpp
+++ b/src/render/materialsystem/qgraphicsapifilter.cpp
@@ -107,6 +107,11 @@ QGraphicsApiFilterPrivate *QGraphicsApiFilterPrivate::get(QGraphicsApiFilter *q)
return q->d_func();
}
+const QGraphicsApiFilterPrivate *QGraphicsApiFilterPrivate::get(const QGraphicsApiFilter *q)
+{
+ return q->d_func();
+}
+
/*!
\class Qt3DRender::QGraphicsApiFilter
\inmodule Qt3DRender
diff --git a/src/render/materialsystem/qgraphicsapifilter_p.h b/src/render/materialsystem/qgraphicsapifilter_p.h
index 3961d4f93..435451c27 100644
--- a/src/render/materialsystem/qgraphicsapifilter_p.h
+++ b/src/render/materialsystem/qgraphicsapifilter_p.h
@@ -84,6 +84,7 @@ public:
}
static QGraphicsApiFilterPrivate *get(QGraphicsApiFilter *q);
+ static const QGraphicsApiFilterPrivate *get(const QGraphicsApiFilter *q);
Q_DECLARE_PUBLIC(QGraphicsApiFilter)
GraphicsApiFilterData m_data;
diff --git a/src/render/materialsystem/qmaterial.cpp b/src/render/materialsystem/qmaterial.cpp
index c6913441e..db523a700 100644
--- a/src/render/materialsystem/qmaterial.cpp
+++ b/src/render/materialsystem/qmaterial.cpp
@@ -275,11 +275,7 @@ void QMaterial::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -290,11 +286,7 @@ void QMaterial::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QMaterial);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
}
diff --git a/src/render/materialsystem/qrenderpass.cpp b/src/render/materialsystem/qrenderpass.cpp
index 111bb7b5f..d0821c49c 100644
--- a/src/render/materialsystem/qrenderpass.cpp
+++ b/src/render/materialsystem/qrenderpass.cpp
@@ -231,12 +231,6 @@ void QRenderPass::setShaderProgram(QShaderProgram *shaderProgram)
Q_D(QRenderPass);
if (d->m_shader != shaderProgram) {
- if (d->m_shader != nullptr && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), d->m_shader);
- change->setPropertyName("shaderProgram");
- d->notifyObservers(change);
- }
-
if (d->m_shader)
d->unregisterDestructionHelper(d->m_shader);
@@ -283,11 +277,7 @@ void QRenderPass::addFilterKey(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -298,11 +288,7 @@ void QRenderPass::removeFilterKey(QFilterKey *filterKey)
{
Q_ASSERT(filterKey);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
d->m_filterKeyList.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -339,11 +325,7 @@ void QRenderPass::addRenderState(QRenderState *state)
if (!state->parent())
state->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -354,11 +336,7 @@ void QRenderPass::removeRenderState(QRenderState *state)
{
Q_ASSERT(state);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
d->m_renderStates.removeOne(state);
// Remove bookkeeping connection
d->unregisterDestructionHelper(state);
@@ -394,11 +372,7 @@ void QRenderPass::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -409,11 +383,7 @@ void QRenderPass::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
diff --git a/src/render/materialsystem/qtechnique.cpp b/src/render/materialsystem/qtechnique.cpp
index b668eb25f..dadeb98bd 100644
--- a/src/render/materialsystem/qtechnique.cpp
+++ b/src/render/materialsystem/qtechnique.cpp
@@ -234,12 +234,7 @@ QTechnique::QTechnique(QTechniquePrivate &dd, QNode *parent)
/*! \internal */
void QTechniquePrivate::_q_graphicsApiFilterChanged()
{
- if (m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(m_id);
- change->setPropertyName("graphicsApiFilterData");
- change->setValue(QVariant::fromValue(QGraphicsApiFilterPrivate::get(const_cast<QGraphicsApiFilter *>(&m_graphicsApiFilter))->m_data));
- notifyObservers(change);
- }
+ update();
}
/*!
@@ -262,11 +257,7 @@ void QTechnique::addFilterKey(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -277,11 +268,7 @@ void QTechnique::removeFilterKey(QFilterKey *filterKey)
{
Q_ASSERT(filterKey);
Q_D(QTechnique);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
d->m_filterKeys.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -317,11 +304,7 @@ void QTechnique::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -332,11 +315,7 @@ void QTechnique::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QTechnique);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
@@ -362,11 +341,7 @@ void QTechnique::addRenderPass(QRenderPass *pass)
if (!pass->parent())
pass->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), pass);
- change->setPropertyName("pass");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -377,11 +352,7 @@ void QTechnique::removeRenderPass(QRenderPass *pass)
{
Q_ASSERT(pass);
Q_D(QTechnique);
- if (d->m_changeArbiter) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), pass);
- change->setPropertyName("pass");
- d->notifyObservers(change);
- }
+ d->update();
d->m_renderPasses.removeOne(pass);
// Remove bookkeeping connection
d->unregisterDestructionHelper(pass);
@@ -405,12 +376,19 @@ QVector<QParameter *> QTechnique::parameters() const
return d->m_parameters;
}
+// TODO Qt 6 -> Remove
QGraphicsApiFilter *QTechnique::graphicsApiFilter()
{
Q_D(QTechnique);
return &d->m_graphicsApiFilter;
}
+const QGraphicsApiFilter *QTechnique::graphicsApiFilter() const
+{
+ Q_D(const QTechnique);
+ return &d->m_graphicsApiFilter;
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QTechnique::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QTechniqueData>::create(this);
diff --git a/src/render/materialsystem/qtechnique.h b/src/render/materialsystem/qtechnique.h
index 7711cd67f..f0c857c2b 100644
--- a/src/render/materialsystem/qtechnique.h
+++ b/src/render/materialsystem/qtechnique.h
@@ -76,7 +76,8 @@ public:
void removeRenderPass(QRenderPass *pass);
QVector<QRenderPass *> renderPasses() const;
- QGraphicsApiFilter *graphicsApiFilter();
+ Q_DECL_DEPRECATED QGraphicsApiFilter *graphicsApiFilter();
+ const QGraphicsApiFilter *graphicsApiFilter() const;
protected:
explicit QTechnique(QTechniquePrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/render/materialsystem/renderpass.cpp b/src/render/materialsystem/renderpass.cpp
index e0fadddd9..aaeca3bb4 100644
--- a/src/render/materialsystem/renderpass.cpp
+++ b/src/render/materialsystem/renderpass.cpp
@@ -52,6 +52,8 @@
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -77,58 +79,33 @@ void RenderPass::cleanup()
m_shaderUuid = Qt3DCore::QNodeId();
}
-void RenderPass::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderPassData>>(change);
- const auto &data = typedChange->data;
- m_filterKeyList = data.filterKeyIds;
- m_parameterPack.setParameters(data.parameterIds);
- for (const auto &renderStateId : qAsConst(data.renderStateIds))
- addRenderState(renderStateId);
- m_shaderUuid = data.shaderId;
-}
-
-void RenderPass::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void RenderPass::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("filterKeys"))
- appendFilterKey(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = change->addedNodeId();
- else if (change->propertyName() == QByteArrayLiteral("renderState"))
- addRenderState(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QRenderPass *node = qobject_cast<const QRenderPass *>(frontEnd);
+ if (!node)
+ return;
+
+ if ((node->shaderProgram() && node->shaderProgram()->id() != m_shaderUuid) ||
+ (!node->shaderProgram() && !m_shaderUuid.isNull())) {
+ m_shaderUuid = node->shaderProgram() ? node->shaderProgram()->id() : QNodeId{};
}
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = change->value().value<Qt3DCore::QNodeId>();
- break;
- }
+ auto filterList = qIdsForNodes(node->filterKeys());
+ std::sort(std::begin(filterList), std::end(filterList));
+ if (m_filterKeyList != filterList)
+ m_filterKeyList = filterList;
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("filterKeys"))
- removeFilterKey(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = QNodeId();
- else if (change->propertyName() == QByteArrayLiteral("renderState"))
- removeRenderState(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
- default:
- break;
- }
+ auto renderStates = qIdsForNodes(node->renderStates());
+ std::sort(std::begin(renderStates), std::end(renderStates));
+ if (m_renderStates != renderStates)
+ m_renderStates = renderStates;
- BackendNode::sceneChangeEvent(e);
markDirty(AbstractRenderer::AllDirty);
}
diff --git a/src/render/materialsystem/renderpass_p.h b/src/render/materialsystem/renderpass_p.h
index 1ca02b1ad..314386ad1 100644
--- a/src/render/materialsystem/renderpass_p.h
+++ b/src/render/materialsystem/renderpass_p.h
@@ -79,7 +79,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::QNodeId shaderProgram() const;
QVector<Qt3DCore::QNodeId> filterKeys() const;
@@ -95,8 +95,6 @@ private:
void addRenderState(Qt3DCore::QNodeId renderStateId);
void removeRenderState(Qt3DCore::QNodeId renderStateId);
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_shaderUuid;
QVector<Qt3DCore::QNodeId> m_filterKeyList;
ParameterPack m_parameterPack;
diff --git a/src/render/materialsystem/technique.cpp b/src/render/materialsystem/technique.cpp
index 42430883e..d4199b7e3 100644
--- a/src/render/materialsystem/technique.cpp
+++ b/src/render/materialsystem/technique.cpp
@@ -85,72 +85,48 @@ void Technique::cleanup()
m_isCompatibleWithRenderer = false;
}
-void Technique::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Technique::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QTechniqueData>>(change);
- const QTechniqueData &data = typedChange->data;
-
- m_graphicsApiFilterData = data.graphicsApiFilterData;
- m_filterKeyList = data.filterKeyIds;
- m_parameterPack.setParameters(data.parameterIds);
- m_renderPasses = data.renderPassIds;
- m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
- markDirty(AbstractRenderer::TechniquesDirty);
-}
+ const QTechnique *node = qobject_cast<const QTechnique *>(frontEnd);
-void Technique::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("enabled")) {
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("graphicsApiFilterData")) {
- GraphicsApiFilterData filterData = change->value().value<GraphicsApiFilterData>();
- m_graphicsApiFilterData = filterData;
- // Notify the manager that our graphicsApiFilterData has changed
- // and that we therefore need to be check for compatibility again
- m_isCompatibleWithRenderer = false;
- m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ if (!node)
+ return;
+
+ bool dirty = isEnabled() != frontEnd->isEnabled();
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ auto renderPasses = qIdsForNodes(node->renderPasses());
+ std::sort(std::begin(renderPasses), std::end(renderPasses));
+ if (m_renderPasses != renderPasses) {
+ m_renderPasses = renderPasses;
+ dirty = true;
}
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("pass")) {
- appendRenderPass(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.appendParameter(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("filterKeys")) {
- appendFilterKey(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters) {
+ m_parameterPack.setParameters(parameters);
+ dirty = true;
}
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("pass")) {
- removeRenderPass(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.removeParameter(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("filterKeys")) {
- removeFilterKey(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ auto filterKeys = qIdsForNodes(node->filterKeys());
+ std::sort(std::begin(filterKeys), std::end(filterKeys));
+ if (m_filterKeyList != filterKeys) {
+ m_filterKeyList = filterKeys;
+ dirty = true;
+ }
+
+ auto graphicsApiFilterData = QGraphicsApiFilterPrivate::get(node->graphicsApiFilter())->m_data;
+ if (m_graphicsApiFilterData != graphicsApiFilterData) {
+ m_graphicsApiFilterData = graphicsApiFilterData;
+ m_isCompatibleWithRenderer = false;
+ dirty = true;
}
- default:
- break;
+ if (dirty) {
+ m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
+ markDirty(AbstractRenderer::TechniquesDirty);
}
- BackendNode::sceneChangeEvent(e);
}
QVector<Qt3DCore::QNodeId> Technique::parameters() const
diff --git a/src/render/materialsystem/technique_p.h b/src/render/materialsystem/technique_p.h
index d885c1b87..1d0d0a9dd 100644
--- a/src/render/materialsystem/technique_p.h
+++ b/src/render/materialsystem/technique_p.h
@@ -80,7 +80,8 @@ public:
~Technique();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+
QVector<Qt3DCore::QNodeId> parameters() const;
void appendRenderPass(Qt3DCore::QNodeId renderPassId);
@@ -102,7 +103,6 @@ public:
NodeManagers *nodeManager() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
GraphicsApiFilterData m_graphicsApiFilterData;
ParameterPack m_parameterPack;
diff --git a/src/render/picking/qpickevent.cpp b/src/render/picking/qpickevent.cpp
index a18c6ead8..ae5748082 100644
--- a/src/render/picking/qpickevent.cpp
+++ b/src/render/picking/qpickevent.cpp
@@ -309,14 +309,14 @@ int QPickEvent::modifiers() const
* The viewport in which this event originated. A null value means the event originated from a frame graph branch without a Viewport.
* If a frame graph branch has a Viewport inside a Viewport the property will contain the leaf viewport.
*
- * \since 5.13
+ * \since 5.14
*/
/*!
* \property Qt3DRender::QPickEvent::viewport
* The viewport in which this event originated. A null value means the event originated from a frame graph branch without a QViewport.
* If a frame graph branch has a Viewport inside a Viewport the property will contain the leaf viewport.
*
- * \since 5.13
+ * \since 5.14
*/
QViewport *QPickEvent::viewport() const
{
@@ -332,7 +332,7 @@ QViewport *QPickEvent::viewport() const
* If the object picker is not attached to a leaf node in the scene graph,
* this is useful to find which child entity was actually picked.
*
- * \since 5.13
+ * \since 5.14
*/
/*!
* \property Qt3DRender::QPickEvent::entity
@@ -341,7 +341,7 @@ QViewport *QPickEvent::viewport() const
* If the object picker is not attached to a leaf node in the scene graph,
* this is useful to find which child entity was actually picked.
*
- * \since 5.13
+ * \since 5.14
*/
Qt3DCore::QEntity *QPickEvent::entity() const
{
diff --git a/src/render/picking/qpickevent.h b/src/render/picking/qpickevent.h
index 21d072ffe..854008aaf 100644
--- a/src/render/picking/qpickevent.h
+++ b/src/render/picking/qpickevent.h
@@ -70,8 +70,8 @@ class Q_3DRENDERSHARED_EXPORT QPickEvent : public QObject
Q_PROPERTY(Qt3DRender::QPickEvent::Buttons button READ button CONSTANT)
Q_PROPERTY(int buttons READ buttons CONSTANT)
Q_PROPERTY(int modifiers READ modifiers CONSTANT)
- Q_PROPERTY(Qt3DRender::QViewport *viewport READ viewport CONSTANT)
- Q_PROPERTY(Qt3DCore::QEntity *entity READ entity CONSTANT)
+ Q_PROPERTY(Qt3DRender::QViewport *viewport READ viewport CONSTANT REVISION 14)
+ Q_PROPERTY(Qt3DCore::QEntity *entity READ entity CONSTANT REVISION 14)
public:
enum Buttons {
LeftButton = Qt::LeftButton,
diff --git a/src/render/renderers/opengl/renderer/commandthread.cpp b/src/render/renderers/opengl/renderer/commandthread.cpp
index dcaacadcc..a518d3b68 100644
--- a/src/render/renderers/opengl/renderer/commandthread.cpp
+++ b/src/render/renderers/opengl/renderer/commandthread.cpp
@@ -176,7 +176,7 @@ void CommandThread::run()
m_commandRequestedSemaphore.acquire();
// Are we still running?
- if (!m_running.load()) {
+ if (!m_running.loadRelaxed()) {
m_graphicsContext->doneCurrent();
// to prevent executeCommand being locked
m_commandExecutionSemaphore.release();
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index e0d1f598f..845a4d8be 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -448,7 +448,7 @@ void Renderer::shutdown()
QMutexLocker lock(&m_hasBeenInitializedMutex);
qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown";
- m_running.store(0);
+ m_running.storeRelaxed(0);
// We delete any renderqueue that we may not have had time to render
// before the surface was destroyed
@@ -619,7 +619,7 @@ void Renderer::render()
// One scene description
// One framegraph description
- while (m_running.load() > 0) {
+ while (m_running.loadRelaxed() > 0) {
doRender();
// TO DO: Restore windows exposed detection
// Probably needs to happens some place else though
@@ -789,7 +789,7 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder
const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder);
locker.unlock(); // We're done protecting the queue at this point
if (isQueueComplete) {
- if (m_renderThread && m_running.load())
+ if (m_renderThread && m_running.loadRelaxed())
Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0);
m_submitRenderViewsSemaphore.release(1);
}
@@ -798,7 +798,7 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder
bool Renderer::canRender() const
{
// Make sure that we've not been told to terminate
- if (m_renderThread && !m_running.load()) {
+ if (m_renderThread && !m_running.loadRelaxed()) {
qCDebug(Rendering) << "RenderThread termination requested whilst waiting";
return false;
}
@@ -817,7 +817,7 @@ bool Renderer::isReadyToSubmit()
m_submitRenderViewsSemaphore.acquire(1);
// Check if shutdown has been requested
- if (m_running.load() == 0)
+ if (m_running.loadRelaxed() == 0)
return false;
// The semaphore should only
@@ -1424,7 +1424,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
const int renderViewsCount = renderViews.size();
quint64 frameElapsed = queueElapsed;
- m_lastFrameCorrect.store(1); // everything fine until now.....
+ m_lastFrameCorrect.storeRelaxed(1); // everything fine until now.....
qCDebug(Memory) << Q_FUNC_INFO << "rendering frame ";
@@ -1457,7 +1457,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// to use when surface is null. Or if we should instead expose an
// offscreensurface to Qt3D.
if (!surface || !surfaceLock.isSurfaceValid()) {
- m_lastFrameCorrect.store(0);
+ m_lastFrameCorrect.storeRelaxed(0);
continue;
}
@@ -1477,7 +1477,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// next RenderView. We won't get the full frame but we may get something
if (!m_submissionContext->beginDrawing(surface)) {
qWarning() << "Failed to make OpenGL context current on surface";
- m_lastFrameCorrect.store(0);
+ m_lastFrameCorrect.storeRelaxed(0);
continue;
}
@@ -1578,7 +1578,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// Execute the render commands
if (!executeCommandsSubmission(renderView))
- m_lastFrameCorrect.store(0); // something went wrong; make sure to render the next frame!
+ m_lastFrameCorrect.storeRelaxed(0); // something went wrong; make sure to render the next frame!
// executeCommandsSubmission takes care of restoring the stateset to the value
// of gc->currentContext() at the moment it was called (either
@@ -1681,7 +1681,7 @@ bool Renderer::shouldRender()
|| m_renderThread == nullptr // <==> we use Scene3D
|| m_dirtyBits.marked != 0
|| m_dirtyBits.remaining != 0
- || !m_lastFrameCorrect.load());
+ || !m_lastFrameCorrect.loadRelaxed());
}
void Renderer::skipNextFrame()
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index 6286f1bce..0f911236a 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -185,7 +185,7 @@ public:
void doRender(bool swapBuffers = true) override;
void cleanGraphicsResources() override;
- bool isRunning() const override { return m_running.load(); }
+ bool isRunning() const override { return m_running.loadRelaxed(); }
void setSceneRoot(Entity *sgRoot) override;
Entity *sceneRoot() const override { return m_renderSceneRoot; }
diff --git a/src/render/renderstates/qdepthrange.cpp b/src/render/renderstates/qdepthrange.cpp
index 58b8b744a..ec5bbce9f 100644
--- a/src/render/renderstates/qdepthrange.cpp
+++ b/src/render/renderstates/qdepthrange.cpp
@@ -48,7 +48,7 @@ namespace Qt3DRender {
/*!
\class Qt3DRender::QDepthRange
\inmodule Qt3DRender
- \since 5.13
+ \since 5.14
\ingroup renderstates
\brief Enables remapping depth values written into the depth buffer.
@@ -65,7 +65,7 @@ namespace Qt3DRender {
\inherits RenderState
\inqmlmodule Qt3D.Render
\ingroup renderstates
- \since 5.13
+ \since 5.14
\brief Enables remapping depth values written into the depth buffer.
By default, OpenGL writes scene depth information into the depth buffer in
diff --git a/src/render/texture/qabstracttexture.cpp b/src/render/texture/qabstracttexture.cpp
index 399314f24..229d773ad 100644
--- a/src/render/texture/qabstracttexture.cpp
+++ b/src/render/texture/qabstracttexture.cpp
@@ -81,10 +81,7 @@ void QAbstractTexturePrivate::setDataFunctor(const QTextureGeneratorPtr &generat
{
if (generator != m_dataFunctor) {
m_dataFunctor = generator;
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id);
- change->setPropertyName("generator");
- change->setValue(QVariant::fromValue(generator));
- notifyObservers(change);
+ update();
}
}
@@ -811,24 +808,15 @@ void QAbstractTexture::setWrapMode(const QTextureWrapMode &wrapMode)
Q_D(QAbstractTexture);
if (d->m_wrapMode.x() != wrapMode.x()) {
d->m_wrapMode.setX(wrapMode.x());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeX");
- e->setValue(static_cast<int>(d->m_wrapMode.x()));
- d->notifyObservers(e);
+ d->update();
}
if (d->m_wrapMode.y() != wrapMode.y()) {
d->m_wrapMode.setY(wrapMode.y());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeY");
- e->setValue(static_cast<int>(d->m_wrapMode.y()));
- d->notifyObservers(e);
+ d->update();
}
if (d->m_wrapMode.z() != wrapMode.z()) {
d->m_wrapMode.setZ(wrapMode.z());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeZ");
- e->setValue(static_cast<int>(d->m_wrapMode.z()));
- d->notifyObservers(e);
+ d->update();
}
}
@@ -983,16 +971,8 @@ void QAbstractTexture::updateData(const QTextureDataUpdate &update)
{
Q_D(QAbstractTexture);
- // Send update to backend if we have the changeArbiter
- if (d->m_changeArbiter != nullptr) {
- auto e = QPropertyUpdatedChangePtr::create(id());
- e->setPropertyName("updateData");
- e->setValue(QVariant::fromValue(update));
- notifyObservers(e);
- } else {
- // If we have no arbiter (no backend), record the update as part of the creation changes
- d->m_initialDataUpdates.push_back(update);
- }
+ d->m_pendingDataUpdates.push_back(update);
+ d->update();
}
Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange() const
@@ -1019,8 +999,8 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange()
data.samples = d->m_samples;
data.dataFunctor = d->m_dataFunctor;
data.sharedTextureId = d->m_sharedTextureId;
- data.initialDataUpdates = d->m_initialDataUpdates;
- return creationChange;
+ data.initialDataUpdates = d->m_pendingDataUpdates;
+ return std::move(creationChange);
}
/*!
diff --git a/src/render/texture/qabstracttexture_p.h b/src/render/texture/qabstracttexture_p.h
index 072bd8159..573eac8c7 100644
--- a/src/render/texture/qabstracttexture_p.h
+++ b/src/render/texture/qabstracttexture_p.h
@@ -96,7 +96,7 @@ public :
QTextureGeneratorPtr dataFunctor() const;
void setDataFunctor(const QTextureGeneratorPtr &generator);
- QVector<QTextureDataUpdate> m_initialDataUpdates;
+ QVector<QTextureDataUpdate> m_pendingDataUpdates;
private:
QTextureGeneratorPtr m_dataFunctor;
diff --git a/src/render/texture/qabstracttextureimage.cpp b/src/render/texture/qabstracttextureimage.cpp
index a95e1fffd..42f8eb747 100644
--- a/src/render/texture/qabstracttextureimage.cpp
+++ b/src/render/texture/qabstracttextureimage.cpp
@@ -255,12 +255,7 @@ void QAbstractTextureImage::setFace(QAbstractTexture::CubeMapFace face)
void QAbstractTextureImage::notifyDataGeneratorChanged()
{
Q_D(QAbstractTextureImage);
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("dataGenerator");
- change->setValue(QVariant::fromValue(dataGenerator()));
- d->notifyObservers(change);
- }
+ d->update();
}
/*! \internal */
diff --git a/src/render/texture/qtexturedataupdate.cpp b/src/render/texture/qtexturedataupdate.cpp
index f196a6b7b..e3d5220f0 100644
--- a/src/render/texture/qtexturedataupdate.cpp
+++ b/src/render/texture/qtexturedataupdate.cpp
@@ -68,6 +68,7 @@ static bool operator==(const QTextureDataUpdatePrivate &lhs, const QTextureDataU
as well as the eventual layer, mipLevel and face.
\sa QAbstractTexture
+ \since 5.14
*/
QTextureDataUpdate::QTextureDataUpdate()
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index c7a739724..53216d27d 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -61,6 +61,7 @@ Texture::Texture()
// We need backend -> frontend notifications to update the status of the texture
: BackendNode(ReadWrite)
, m_dirty(DirtyImageGenerators|DirtyProperties|DirtyParameters|DirtyDataGenerator)
+ , m_sharedTextureId(-1)
{
}
@@ -130,67 +131,6 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
DirtyFlags dirty;
switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("width")) {
- m_properties.width = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("height")) {
- m_properties.height = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("depth")) {
- m_properties.depth = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("format")) {
- m_properties.format = static_cast<QAbstractTexture::TextureFormat>(propertyChange->value().toInt());
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("target")) {
- m_properties.target = static_cast<QAbstractTexture::Target>(propertyChange->value().toInt());
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("mipmaps")) {
- m_properties.generateMipMaps = propertyChange->value().toBool();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("minificationFilter")) {
- m_parameters.minificationFilter = static_cast<QAbstractTexture::Filter>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("magnificationFilter")) {
- m_parameters.magnificationFilter = static_cast<QAbstractTexture::Filter>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeX")) {
- m_parameters.wrapModeX = static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeY")) {
- m_parameters.wrapModeY = static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeZ")) {
- m_parameters.wrapModeZ =static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("maximumAnisotropy")) {
- m_parameters.maximumAnisotropy = propertyChange->value().toFloat();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("comparisonFunction")) {
- m_parameters.comparisonFunction = propertyChange->value().value<QAbstractTexture::ComparisonFunction>();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("comparisonMode")) {
- m_parameters.comparisonMode = propertyChange->value().value<QAbstractTexture::ComparisonMode>();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("layers")) {
- m_properties.layers = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("samples")) {
- m_properties.samples = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("generator")) {
- setDataGenerator(propertyChange->value().value<QTextureGeneratorPtr>());
- } else if (propertyChange->propertyName() == QByteArrayLiteral("textureId")) {
- m_sharedTextureId = propertyChange->value().toInt();
- dirty = DirtySharedTextureId;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("updateData")) {
- Qt3DRender::QTextureDataUpdate updateData = propertyChange->value().value<Qt3DRender::QTextureDataUpdate>();
- addTextureDataUpdate(updateData);
- }
- break;
- }
case PropertyValueAdded: {
const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
@@ -217,6 +157,62 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Texture::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractTexture *node = qobject_cast<const QAbstractTexture *>(frontEnd);
+ if (!node)
+ return;
+
+ TextureProperties p = m_properties;
+ p.width = node->width();
+ p.height = node->height();
+ p.depth = node->depth();
+ p.format = node->format();
+ p.target = node->target();
+ p.generateMipMaps = node->generateMipMaps();
+ p.layers = node->layers();
+ p.samples = node->samples();
+ if (p != m_properties) {
+ m_properties = p;
+ addDirtyFlag(DirtyProperties);
+ }
+
+ TextureParameters q = m_parameters;
+ q.magnificationFilter = node->magnificationFilter();
+ q.minificationFilter = node->minificationFilter();
+ q.wrapModeX = const_cast<QAbstractTexture *>(node)->wrapMode()->x();
+ q.wrapModeY = const_cast<QAbstractTexture *>(node)->wrapMode()->y();
+ q.wrapModeZ = const_cast<QAbstractTexture *>(node)->wrapMode()->z();
+ q.maximumAnisotropy = node->maximumAnisotropy();
+ q.comparisonFunction = node->comparisonFunction();
+ q.comparisonMode = node->comparisonMode();
+ if (q != m_parameters) {
+ m_parameters = q;
+ addDirtyFlag(DirtyParameters);
+ }
+
+ auto newGenerator = node->dataGenerator();
+ if (newGenerator != m_dataFunctor) {
+ setDataGenerator(newGenerator);
+ }
+
+ QAbstractTexturePrivate *dnode = dynamic_cast<QAbstractTexturePrivate *>(QAbstractTexturePrivate::get(const_cast<QAbstractTexture *>(node)));
+ if (dnode) {
+ for (const QTextureDataUpdate &pendingUpdate : dnode->m_pendingDataUpdates)
+ addTextureDataUpdate(pendingUpdate);
+ dnode->m_pendingDataUpdates.clear();
+
+ for (const auto imgNode : dnode->m_textureImages)
+ addTextureImage(imgNode->id());
+ }
+
+ if (dnode->m_sharedTextureId != m_sharedTextureId) {
+ m_sharedTextureId = dnode->m_sharedTextureId;
+ addDirtyFlag(DirtySharedTextureId);
+ }
+}
+
// Called by sceneChangeEvent or TextureDownloadRequest (both in AspectThread context)
void Texture::setDataGenerator(const QTextureGeneratorPtr &generator)
{
@@ -308,7 +304,7 @@ void Texture::updatePropertiesAndNotify(const TextureUpdateInfo &updateInfo)
bool Texture::isValid(TextureImageManager *manager) const
{
- for (const QNodeId id : m_textureImageIds) {
+ for (const QNodeId &id : m_textureImageIds) {
TextureImage *img = manager->lookupResource(id);
if (img == nullptr)
return false;
@@ -340,7 +336,7 @@ void Texture::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chan
m_dataFunctor = data.dataFunctor;
m_sharedTextureId = data.sharedTextureId;
- for (const QNodeId imgId : data.textureImageIds)
+ for (const QNodeId &imgId : data.textureImageIds)
addTextureImage(imgId);
const QVector<QTextureDataUpdate> initialDataUpdates = data.initialDataUpdates;
diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h
index 28580c92a..967b2a44a 100644
--- a/src/render/texture/texture_p.h
+++ b/src/render/texture/texture_p.h
@@ -164,6 +164,7 @@ public:
QVector<QTextureDataUpdate> takePendingTextureDataUpdates() { return std::move(m_pendingTextureDataUpdates); }
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline const TextureProperties& properties() const { return m_properties; }
inline const TextureParameters& parameters() const { return m_parameters; }