summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Ottens <kevin.ottens@kdab.com>2017-02-23 13:53:23 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-02-24 16:58:51 +0000
commit12111fd494d927bb75a8a41e3771ff6983119274 (patch)
tree6590daea24184e851502beb0e94dbe76e2cca640
parent92a2759a8cf7a77958a788216f1bee762789ca59 (diff)
QShaderData: fix texture support in properties
There was only code dealing with sub-shader data but nothing allowing to check if a property was a texture, this is now properly handled. Change-Id: I48984727eff975e9f3e2c21c5185b336efc963fd Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/quick3d/quick3drender/items/quick3dshaderdata.cpp8
-rw-r--r--src/render/backend/renderview.cpp2
-rw-r--r--src/render/jobs/renderviewjobutils.cpp19
-rw-r--r--src/render/jobs/renderviewjobutils_p.h2
-rw-r--r--src/render/materialsystem/qshaderdata_p.h6
-rw-r--r--tests/auto/render/renderviewutils/tst_renderviewutils.cpp156
6 files changed, 179 insertions, 14 deletions
diff --git a/src/quick3d/quick3drender/items/quick3dshaderdata.cpp b/src/quick3d/quick3drender/items/quick3dshaderdata.cpp
index dbf351695..1287f1603 100644
--- a/src/quick3d/quick3drender/items/quick3dshaderdata.cpp
+++ b/src/quick3d/quick3drender/items/quick3dshaderdata.cpp
@@ -84,11 +84,9 @@ public:
}
}
return innerValues;
- } else if (v.userType() == quick3DShaderDataTypeId) {
- Qt3DCore::QNodeId id;
- QShaderData *shaderData = v.value<Quick3DShaderData *>();
- if (shaderData)
- id = shaderData->id();
+ } else if (v.canConvert<Qt3DCore::QNode*>()) {
+ const auto node = v.value<Qt3DCore::QNode *>();
+ const auto id = Qt3DCore::qIdForNode(node);
return QVariant::fromValue(id);
}
return v;
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index c7d2c7864..bd184594f 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -361,6 +361,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
// is only accessed from the same thread
UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
builder->shaderDataManager = m_manager->shaderDataManager();
+ builder->textureManager = m_manager->textureManager();
m_localData.setLocalData(builder);
QVector<RenderCommand *> commands;
@@ -479,6 +480,7 @@ QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<En
// is only accessed from the same thread
UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
builder->shaderDataManager = m_manager->shaderDataManager();
+ builder->textureManager = m_manager->textureManager();
m_localData.setLocalData(builder);
// If the RenderView contains only a ComputeDispatch then it cares about
diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp
index f75ea3f0c..500fcc56a 100644
--- a/src/render/jobs/renderviewjobutils.cpp
+++ b/src/render/jobs/renderviewjobutils.cpp
@@ -416,6 +416,7 @@ const int qNodeIdTypeId = qMetaTypeId<QNodeId>();
UniformBlockValueBuilder::UniformBlockValueBuilder()
: updatedPropertiesOnly(false)
, shaderDataManager(nullptr)
+ , textureManager(nullptr)
{
}
@@ -432,11 +433,16 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
if (list.at(0).userType() == qNodeIdTypeId) { // Array of struct qmlPropertyName[i].structMember
for (int i = 0; i < list.size(); ++i) {
if (list.at(i).userType() == qNodeIdTypeId) {
- ShaderData *subShaderData = shaderDataManager->lookupResource(list.at(i).value<QNodeId>());
- if (subShaderData)
+ const auto nodeId = value.value<QNodeId>();
+ ShaderData *subShaderData = shaderDataManager->lookupResource(nodeId);
+ if (subShaderData) {
buildActiveUniformNameValueMapStructHelper(subShaderData,
blockName + QLatin1Char('.') + qmlPropertyName + blockArray.arg(i),
QLatin1String(""));
+ } else if (textureManager->contains(nodeId)) {
+ const auto varId = StringToInt::lookupId(blockName + QLatin1Char('.') + qmlPropertyName + blockArray.arg(i));
+ activeUniformNamesToValue.insert(varId, value);
+ }
}
}
} else { // Array of scalar/vec qmlPropertyName[0]
@@ -447,11 +453,16 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
}
}
} else if (value.userType() == qNodeIdTypeId) { // Struct qmlPropertyName.structMember
- ShaderData *rSubShaderData = shaderDataManager->lookupResource(value.value<QNodeId>());
- if (rSubShaderData)
+ const auto nodeId = value.value<QNodeId>();
+ ShaderData *rSubShaderData = shaderDataManager->lookupResource(nodeId);
+ if (rSubShaderData) {
buildActiveUniformNameValueMapStructHelper(rSubShaderData,
blockName,
qmlPropertyName);
+ } else if (textureManager->contains(nodeId)) {
+ const auto varId = StringToInt::lookupId(blockName + QLatin1Char('.') + qmlPropertyName);
+ activeUniformNamesToValue.insert(varId, value);
+ }
} else { // Scalar / Vec
QString varName = blockName + QLatin1Char('.') + qmlPropertyName;
if (uniforms.contains(varName)) {
diff --git a/src/render/jobs/renderviewjobutils_p.h b/src/render/jobs/renderviewjobutils_p.h
index bc042a582..c1d37b28a 100644
--- a/src/render/jobs/renderviewjobutils_p.h
+++ b/src/render/jobs/renderviewjobutils_p.h
@@ -83,6 +83,7 @@ class NodeManagers;
class ShaderDataManager;
struct ShaderUniform;
class ShaderData;
+class TextureManager;
class RenderStateManager;
class RenderStateCollection;
@@ -169,6 +170,7 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
QHash<QString, ShaderUniform> uniforms;
UniformBlockValueBuilderHash activeUniformNamesToValue;
ShaderDataManager *shaderDataManager;
+ TextureManager *textureManager;
QMatrix4x4 viewMatrix;
};
diff --git a/src/render/materialsystem/qshaderdata_p.h b/src/render/materialsystem/qshaderdata_p.h
index bfa139890..53e3caefd 100644
--- a/src/render/materialsystem/qshaderdata_p.h
+++ b/src/render/materialsystem/qshaderdata_p.h
@@ -70,10 +70,10 @@ class QShaderDataPropertyReader: public PropertyReaderInterface
{
QVariant readProperty(const QVariant &v) Q_DECL_OVERRIDE
{
- QShaderData *shaderData = nullptr;
+ const auto node = v.value<Qt3DCore::QNode *>();
- if (v.userType() == qShaderDataTypeId && (shaderData = v.value<QShaderData *>()) != nullptr) {
- return QVariant::fromValue(shaderData->id());
+ if (node) {
+ return QVariant::fromValue(node->id());
} else if (v.userType() == qVectorShaderDataTypeId) {
QVariantList vlist;
const auto data_ = v.value<QVector<QShaderData *> >();
diff --git a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
index e4681a257..c38b2795e 100644
--- a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
+++ b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
@@ -43,6 +43,8 @@ class tst_RenderViewUtils : public Qt3DCore::QBackendNodeTester
private Q_SLOTS:
void topLevelScalarValueNoUniforms();
void topLevelScalarValue();
+ void topLevelTextureValueNoUniforms();
+ void topLevelTextureValue();
void topLevelArrayValue();
void topLevelStructValue_data();
void topLevelStructValue();
@@ -66,6 +68,15 @@ private:
// Init the backend element
simulateInitialization(frontend, backend);
}
+
+ void initBackendTexture(Qt3DRender::QAbstractTexture *frontend,
+ Qt3DRender::Render::TextureManager *manager)
+ {
+ // Create backend element for frontend one
+ Qt3DRender::Render::Texture *backend = manager->getOrCreateResource(frontend->id());
+ // Init the backend element
+ simulateInitialization(frontend, backend);
+ }
};
class ScalarShaderData : public Qt3DRender::QShaderData
@@ -109,6 +120,47 @@ private:
float m_scalar;
};
+class TextureShaderData : public Qt3DRender::QShaderData
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DRender::QAbstractTexture* texture READ texture WRITE setTexture NOTIFY textureChanged)
+
+public:
+ TextureShaderData()
+ : Qt3DRender::QShaderData()
+ , m_texture(nullptr)
+ {
+ }
+
+ void setTexture(Qt3DRender::QAbstractTexture *texture)
+ {
+ if (texture != m_texture) {
+ m_texture = texture;
+ emit textureChanged();
+ }
+ }
+
+ Qt3DRender::QAbstractTexture *texture() const
+ {
+ return m_texture;
+ }
+
+ QHash<QString, Qt3DRender::Render::ShaderUniform> buildUniformMap(const QString &blockName)
+ {
+ QHash<QString, Qt3DRender::Render::ShaderUniform> uniforms;
+
+ uniforms.insert(blockName + QStringLiteral(".texture"), Qt3DRender::Render::ShaderUniform());
+
+ return uniforms;
+ }
+
+Q_SIGNALS:
+ void textureChanged();
+
+private:
+ Qt3DRender::QAbstractTexture *m_texture;
+};
+
class ArrayShaderData : public Qt3DRender::QShaderData
{
@@ -294,6 +346,7 @@ void tst_RenderViewUtils::topLevelScalarValueNoUniforms()
// GIVEN
QScopedPointer<ScalarShaderData> shaderData(new ScalarShaderData());
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
// WHEN
shaderData->setScalar(883.0f);
@@ -306,6 +359,7 @@ void tst_RenderViewUtils::topLevelScalarValueNoUniforms()
// WHEB
Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
blockBuilder.updatedPropertiesOnly = false;
// build name-value map
blockBuilder.buildActiveUniformNameValueMapStructHelper(backendShaderData, QStringLiteral(""));
@@ -320,6 +374,7 @@ void tst_RenderViewUtils::topLevelScalarValue()
// GIVEN
QScopedPointer<ScalarShaderData> shaderData(new ScalarShaderData());
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
// WHEN
shaderData->setScalar(883.0f);
@@ -332,6 +387,7 @@ void tst_RenderViewUtils::topLevelScalarValue()
// WHEN
Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
blockBuilder.updatedPropertiesOnly = false;
blockBuilder.uniforms = shaderData->buildUniformMap(QStringLiteral("MyBlock"));
// build name-value map
@@ -353,11 +409,83 @@ void tst_RenderViewUtils::topLevelScalarValue()
}
}
+void tst_RenderViewUtils::topLevelTextureValueNoUniforms()
+{
+ // GIVEN
+ QScopedPointer<TextureShaderData> shaderData(new TextureShaderData);
+ QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager);
+ QScopedPointer<Qt3DRender::QAbstractTexture> texture(new Qt3DRender::QTexture2D);
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
+
+ // WHEN
+ shaderData->setTexture(texture.data());
+ initBackendShaderData(shaderData.data(), manager.data());
+
+ // THEN
+ Qt3DRender::Render::ShaderData *backendShaderData = manager->lookupResource(shaderData->id());
+ QVERIFY(backendShaderData != nullptr);
+
+ // WHEB
+ Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
+ blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
+ blockBuilder.updatedPropertiesOnly = false;
+ // build name-value map
+ blockBuilder.buildActiveUniformNameValueMapStructHelper(backendShaderData, QStringLiteral(""));
+
+ // THEN
+ // activeUniformNamesToValue should be empty as blockBuilder.uniforms is
+ QVERIFY(blockBuilder.activeUniformNamesToValue.isEmpty());
+}
+
+void tst_RenderViewUtils::topLevelTextureValue()
+{
+ // GIVEN
+ QScopedPointer<TextureShaderData> shaderData(new TextureShaderData);
+ QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager);
+ QScopedPointer<Qt3DRender::QAbstractTexture> texture(new Qt3DRender::QTexture2D);
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
+
+ // WHEN
+ initBackendTexture(texture.data(), textureManager.data());
+ shaderData->setTexture(texture.data());
+ initBackendShaderData(shaderData.data(), manager.data());
+
+ // THEN
+ Qt3DRender::Render::ShaderData *backendShaderData = manager->lookupResource(shaderData->id());
+ QVERIFY(backendShaderData != nullptr);
+
+ // WHEN
+ Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
+ blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
+ blockBuilder.updatedPropertiesOnly = false;
+ blockBuilder.uniforms = shaderData->buildUniformMap(QStringLiteral("MyBlock"));
+ // build name-value map
+ blockBuilder.buildActiveUniformNameValueMapStructHelper(backendShaderData, QStringLiteral("MyBlock"));
+
+ // THEN
+ QVERIFY(blockBuilder.uniforms.count() == 1);
+ QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), 1);
+
+ // WHEN
+ Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator it = blockBuilder.activeUniformNamesToValue.begin();
+ const Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator end = blockBuilder.activeUniformNamesToValue.end();
+
+ while (it != end) {
+ // THEN
+ QVERIFY(blockBuilder.uniforms.contains(Qt3DRender::Render::StringToInt::lookupString(it.key())));
+ QCOMPARE(it.value(), QVariant::fromValue(shaderData->texture()->id()));
+ ++it;
+ }
+}
+
void tst_RenderViewUtils::topLevelArrayValue()
{
// GIVEN
QScopedPointer<ArrayShaderData> shaderData(new ArrayShaderData());
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
// WHEN
QVariantList arrayValues = QVariantList() << 454 << 350 << 383 << 427 << 552;
@@ -371,6 +499,7 @@ void tst_RenderViewUtils::topLevelArrayValue()
// WHEN
Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
blockBuilder.updatedPropertiesOnly = false;
blockBuilder.uniforms = shaderData->buildUniformMap(QStringLiteral("MyBlock"));
// build name-value map
@@ -430,6 +559,7 @@ void tst_RenderViewUtils::topLevelStructValue()
QFETCH(StructShaderData *, shaderData);
QFETCH(QString, blockName);
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
// WHEN
initBackendShaderData(shaderData, manager.data());
@@ -441,6 +571,7 @@ void tst_RenderViewUtils::topLevelStructValue()
// WHEN
Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
blockBuilder.updatedPropertiesOnly = false;
blockBuilder.uniforms = shaderData->buildUniformMap(blockName);
const QHash<QString, QVariant> expectedValues = shaderData->buildUniformMapValues(blockName);
@@ -468,10 +599,14 @@ void tst_RenderViewUtils::topLevelDynamicProperties()
// GIVEN
QScopedPointer<Qt3DRender::QShaderData> shaderData(new Qt3DRender::QShaderData());
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
+ QScopedPointer<Qt3DRender::QAbstractTexture> texture(new Qt3DRender::QTexture2D);
+ QScopedPointer<Qt3DRender::Render::TextureManager> textureManager(new Qt3DRender::Render::TextureManager());
// WHEN
+ initBackendTexture(texture.data(), textureManager.data());
shaderData->setProperty("scalar", 883.0f);
shaderData->setProperty("array", QVariantList() << 454 << 350 << 383 << 427 << 552);
+ shaderData->setProperty("texture", QVariant::fromValue(texture.data()));
initBackendShaderData(shaderData.data(), manager.data());
// THEN
@@ -481,20 +616,24 @@ void tst_RenderViewUtils::topLevelDynamicProperties()
// WHEN
Qt3DRender::Render::UniformBlockValueBuilder blockBuilder;
blockBuilder.shaderDataManager = manager.data();
+ blockBuilder.textureManager = textureManager.data();
blockBuilder.updatedPropertiesOnly = false;
blockBuilder.uniforms.insert(QStringLiteral("MyBlock.scalar"), Qt3DRender::Render::ShaderUniform());
blockBuilder.uniforms.insert(QStringLiteral("MyBlock.array[0]"), Qt3DRender::Render::ShaderUniform());
+ blockBuilder.uniforms.insert(QStringLiteral("MyBlock.texture"), Qt3DRender::Render::ShaderUniform());
// build name-value map
blockBuilder.buildActiveUniformNameValueMapStructHelper(backendShaderData, QStringLiteral("MyBlock"));
// THEN
- QVERIFY(blockBuilder.uniforms.count() == 2);
- QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), 2);
+ QVERIFY(blockBuilder.uniforms.count() == 3);
+ QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), 3);
QCOMPARE(blockBuilder.activeUniformNamesToValue.value(Qt3DRender::Render::StringToInt::lookupId("MyBlock.scalar")),
shaderData->property("scalar"));
QCOMPARE(blockBuilder.activeUniformNamesToValue.value(Qt3DRender::Render::StringToInt::lookupId("MyBlock.array[0]")),
shaderData->property("array"));
+ QCOMPARE(blockBuilder.activeUniformNamesToValue.value(Qt3DRender::Render::StringToInt::lookupId("MyBlock.texture")),
+ QVariant::fromValue(texture->id()));
}
void tst_RenderViewUtils::transformedProperties()
@@ -558,6 +697,19 @@ void tst_RenderViewUtils::shouldNotifyDynamicPropertyChanges()
QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
QCOMPARE(change->propertyName(), QByteArrayLiteral("scalar"));
QCOMPARE(change->value().toFloat(), 883.0f);
+
+ arbiter.events.clear();
+
+ // WHEN
+ QScopedPointer<Qt3DRender::QAbstractTexture> texture(new Qt3DRender::QTexture2D);
+ shaderData->setProperty("texture", QVariant::fromValue(texture.data()));
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().dynamicCast<Qt3DCore::QDynamicPropertyUpdatedChange>();
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->propertyName(), QByteArrayLiteral("texture"));
+ QCOMPARE(change->value(), QVariant::fromValue(texture->id()));
}
QTEST_MAIN(tst_RenderViewUtils)