From 86b1866c9bcb40cf6a03bc7d810e58a5e815c193 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 18 Dec 2018 10:46:05 +0100 Subject: QEnvironmentLight: add uniforms for envmaps size This makes future ES2 PBR implementation possible as textureSize() is not available on ES2 Change-Id: Ibf2b36240778a3f30f4316a67819f9052e46bdf1 Reviewed-by: Sean Harmer Reviewed-by: Kevin Ottens --- src/render/lights/qenvironmentlight.cpp | 50 +++++++++-- src/render/lights/qenvironmentlight.h | 2 + src/render/lights/qenvironmentlight_p.h | 3 + .../qenvironmentlight/tst_qenvironmentlight.cpp | 98 ++++++++++++++++++++++ 4 files changed, 147 insertions(+), 6 deletions(-) diff --git a/src/render/lights/qenvironmentlight.cpp b/src/render/lights/qenvironmentlight.cpp index c81f43479..866905fb6 100644 --- a/src/render/lights/qenvironmentlight.cpp +++ b/src/render/lights/qenvironmentlight.cpp @@ -40,6 +40,7 @@ #include "qenvironmentlight.h" #include "qenvironmentlight_p.h" #include "qabstracttexture.h" +#include QT_BEGIN_NAMESPACE @@ -65,6 +66,23 @@ QEnvironmentLightPrivate::~QEnvironmentLightPrivate() { } +void QEnvironmentLightPrivate::_q_updateEnvMapsSize() +{ + QVector3D irradianceSize; + if (m_irradiance != nullptr) + irradianceSize = QVector3D(m_irradiance->width(), + m_irradiance->height(), + m_irradiance->depth()); + m_shaderData->setProperty("irradianceSize", QVariant::fromValue(irradianceSize)); + + QVector3D specularSize; + if (m_specular != nullptr) + specularSize = QVector3D(m_specular->width(), + m_specular->height(), + m_specular->depth()); + m_shaderData->setProperty("specularSize", QVariant::fromValue(specularSize)); +} + Qt3DCore::QNodeCreatedChangeBasePtr QEnvironmentLight::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr::create(this); @@ -148,17 +166,26 @@ void QEnvironmentLight::setIrradiance(QAbstractTexture *i) if (irradiance() == i) return; - if (irradiance()) - d->unregisterDestructionHelper(irradiance()); + if (irradiance()) { + d->unregisterDestructionHelper(d->m_irradiance); + QObject::disconnect(d->m_irradiance, SIGNAL(widthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::disconnect(d->m_irradiance, SIGNAL(heightChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::disconnect(d->m_irradiance, SIGNAL(depthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + } if (i && !i->parent()) i->setParent(this); d->m_irradiance = i; d->m_shaderData->setProperty("irradiance", QVariant::fromValue(i)); + d->_q_updateEnvMapsSize(); - if (i) + if (i) { d->registerDestructionHelper(i, &QEnvironmentLight::setIrradiance, i); + QObject::connect(d->m_irradiance, SIGNAL(widthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::connect(d->m_irradiance, SIGNAL(heightChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::connect(d->m_irradiance, SIGNAL(depthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + } emit irradianceChanged(i); } @@ -169,17 +196,26 @@ void QEnvironmentLight::setSpecular(QAbstractTexture *s) if (specular() == s) return; - if (specular()) - d->unregisterDestructionHelper(specular()); + if (specular()) { + d->unregisterDestructionHelper(d->m_specular); + QObject::disconnect(d->m_specular, SIGNAL(widthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::disconnect(d->m_specular, SIGNAL(heightChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::disconnect(d->m_specular, SIGNAL(depthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + } if (s && !s->parent()) s->setParent(this); d->m_specular = s; d->m_shaderData->setProperty("specular", QVariant::fromValue(s)); + d->_q_updateEnvMapsSize(); - if (s) + if (s) { d->registerDestructionHelper(s, &QEnvironmentLight::setSpecular, s); + QObject::connect(d->m_specular, SIGNAL(widthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::connect(d->m_specular, SIGNAL(heightChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + QObject::connect(d->m_specular, SIGNAL(depthChanged(int)), this, SLOT(_q_updateEnvMapsSize())); + } emit specularChanged(s); } @@ -187,3 +223,5 @@ void QEnvironmentLight::setSpecular(QAbstractTexture *s) } // namespace Qt3DRender QT_END_NAMESPACE + +#include "moc_qenvironmentlight.cpp" diff --git a/src/render/lights/qenvironmentlight.h b/src/render/lights/qenvironmentlight.h index c3d180233..995768d3c 100644 --- a/src/render/lights/qenvironmentlight.h +++ b/src/render/lights/qenvironmentlight.h @@ -77,6 +77,8 @@ Q_SIGNALS: private: Q_DECLARE_PRIVATE(QEnvironmentLight) Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; + + Q_PRIVATE_SLOT(d_func(), void _q_updateEnvMapsSize()) }; } // namespace Qt3DRender diff --git a/src/render/lights/qenvironmentlight_p.h b/src/render/lights/qenvironmentlight_p.h index 02358dafc..f4fa97b5a 100644 --- a/src/render/lights/qenvironmentlight_p.h +++ b/src/render/lights/qenvironmentlight_p.h @@ -72,6 +72,9 @@ public: QShaderData *m_shaderData; QAbstractTexture *m_irradiance; QAbstractTexture *m_specular; + +private: + void _q_updateEnvMapsSize(); }; struct QEnvironmentLightData diff --git a/tests/auto/render/qenvironmentlight/tst_qenvironmentlight.cpp b/tests/auto/render/qenvironmentlight/tst_qenvironmentlight.cpp index 76b3603c9..97375b647 100644 --- a/tests/auto/render/qenvironmentlight/tst_qenvironmentlight.cpp +++ b/tests/auto/render/qenvironmentlight/tst_qenvironmentlight.cpp @@ -168,6 +168,55 @@ private Q_SLOTS: QCOMPARE(spy.count(), 1); QCOMPARE(spy.takeFirst().first().value(), nullptr); } + { + auto texture = new Qt3DRender::QTexture2D(&light); + QSignalSpy spy(&light, &Qt3DRender::QEnvironmentLight::irradianceChanged); + + // WHEN + light.setIrradiance(texture); + + // THEN + QCOMPARE(light.irradiance(), texture); + QCOMPARE(shaderData->property("irradiance").value(), texture); + QCOMPARE(shaderData->property("irradianceSize").value(), + QVector3D(texture->width(), texture->height(), texture->depth())); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().first().value(), texture); + + // WHEN + texture->setWidth(883); + + // THEN + QCOMPARE(shaderData->property("irradianceSize").value(), + QVector3D(883.0f, texture->height(), texture->depth())); + + // WHEN + texture->setHeight(1340); + + // THEN + QCOMPARE(shaderData->property("irradianceSize").value(), + QVector3D(883.0f, 1340.0f, texture->depth())); + + // WHEN + texture->setDepth(1584); + + // THEN + QCOMPARE(shaderData->property("irradianceSize").value(), + QVector3D(883.0f, 1340.0f, 1584.0f)); + + // WHEN + delete texture; + + // THEN + QCOMPARE(light.irradiance(), nullptr); + QCOMPARE(shaderData->property("irradiance").value(), nullptr); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().first().value(), nullptr); + + // THEN + QCOMPARE(shaderData->property("irradianceSize").value(), + QVector3D()); + } { auto texture = new Qt3DRender::QTexture2D(&light); QSignalSpy spy(&light, &Qt3DRender::QEnvironmentLight::specularChanged); @@ -242,6 +291,55 @@ private Q_SLOTS: QCOMPARE(spy.count(), 1); QCOMPARE(spy.takeFirst().first().value(), nullptr); } + { + auto texture = new Qt3DRender::QTexture2D(&light); + QSignalSpy spy(&light, &Qt3DRender::QEnvironmentLight::specularChanged); + + // WHEN + light.setSpecular(texture); + + // THEN + QCOMPARE(light.specular(), texture); + QCOMPARE(shaderData->property("specular").value(), texture); + QCOMPARE(shaderData->property("specularSize").value(), + QVector3D(texture->width(), texture->height(), texture->depth())); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().first().value(), texture); + + // WHEN + texture->setWidth(883); + + // THEN + QCOMPARE(shaderData->property("specularSize").value(), + QVector3D(883.0f, texture->height(), texture->depth())); + + // WHEN + texture->setHeight(1340); + + // THEN + QCOMPARE(shaderData->property("specularSize").value(), + QVector3D(883.0f, 1340.0f, texture->depth())); + + // WHEN + texture->setDepth(1584); + + // THEN + QCOMPARE(shaderData->property("specularSize").value(), + QVector3D(883.0f, 1340.0f, 1584.0f)); + + // WHEN + delete texture; + + // THEN + QCOMPARE(light.specular(), nullptr); + QCOMPARE(shaderData->property("specular").value(), nullptr); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().first().value(), nullptr); + + // THEN + QCOMPARE(shaderData->property("specularSize").value(), + QVector3D()); + } } void checkCreationData() -- cgit v1.2.3