diff options
-rw-r--r-- | src/gui/util/qshadergraph.cpp | 40 | ||||
-rw-r--r-- | src/gui/util/qshadergraph_p.h | 2 | ||||
-rw-r--r-- | tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp | 117 |
3 files changed, 151 insertions, 8 deletions
diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp index 5379e6ed7a..828c709a12 100644 --- a/src/gui/util/qshadergraph.cpp +++ b/src/gui/util/qshadergraph.cpp @@ -172,20 +172,46 @@ QVector<QShaderGraph::Edge> QShaderGraph::edges() const Q_DECL_NOTHROW return m_edges; } -QVector<QShaderGraph::Statement> QShaderGraph::createStatements() const +QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringList &enabledLayers) const { - const auto idHash = [this] { + const auto intersectsEnabledLayers = [enabledLayers] (const QStringList &layers) { + return layers.isEmpty() + || std::any_of(layers.cbegin(), layers.cend(), + [enabledLayers] (const QString &s) { return enabledLayers.contains(s); }); + }; + + const auto enabledNodes = [this, intersectsEnabledLayers] { + auto res = QVector<QShaderNode>(); + std::copy_if(m_nodes.cbegin(), m_nodes.cend(), + std::back_inserter(res), + [intersectsEnabledLayers] (const QShaderNode &node) { + return intersectsEnabledLayers(node.layers()); + }); + return res; + }(); + + const auto enabledEdges = [this, intersectsEnabledLayers] { + auto res = QVector<Edge>(); + std::copy_if(m_edges.cbegin(), m_edges.cend(), + std::back_inserter(res), + [intersectsEnabledLayers] (const Edge &edge) { + return intersectsEnabledLayers(edge.layers); + }); + return res; + }(); + + const auto idHash = [enabledNodes] { auto nextVarId = 0; auto res = QHash<QUuid, Statement>(); - for (const auto &node : qAsConst(m_nodes)) + for (const auto &node : enabledNodes) res.insert(node.uuid(), nodeToStatement(node, nextVarId)); return res; }(); auto result = QVector<Statement>(); - auto currentEdges = m_edges; - auto currentUuids = [this] { - const auto inputs = copyOutputNodes(m_nodes); + auto currentEdges = enabledEdges; + auto currentUuids = [enabledNodes] { + const auto inputs = copyOutputNodes(enabledNodes); auto res = QVector<QUuid>(); std::transform(inputs.cbegin(), inputs.cend(), std::back_inserter(res), @@ -201,7 +227,7 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements() const // input nodes while (!currentUuids.isEmpty()) { const auto uuid = currentUuids.takeFirst(); - result.append(completeStatement(idHash, m_edges, uuid)); + result.append(completeStatement(idHash, enabledEdges, uuid)); const auto outgoing = outgoingEdges(currentEdges, uuid); for (const auto &outgoingEdge : outgoing) { diff --git a/src/gui/util/qshadergraph_p.h b/src/gui/util/qshadergraph_p.h index ced6b1430b..756e1b2da2 100644 --- a/src/gui/util/qshadergraph_p.h +++ b/src/gui/util/qshadergraph_p.h @@ -89,7 +89,7 @@ public: Q_GUI_EXPORT void removeEdge(const Edge &edge); Q_GUI_EXPORT QVector<Edge> edges() const Q_DECL_NOTHROW; - Q_GUI_EXPORT QVector<Statement> createStatements() const; + Q_GUI_EXPORT QVector<Statement> createStatements(const QStringList &enabledLayers = QStringList()) const; private: QVector<QShaderNode> m_nodes; diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index 25b45f7fa6..ce2d38c24f 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -113,6 +113,7 @@ private slots: void shouldHandleUnboundPortsDuringGraphSerialization(); void shouldSurviveCyclesDuringGraphSerialization(); void shouldDealWithEdgesJumpingOverLayers(); + void shouldGenerateDifferentStatementsDependingOnActiveLayers(); }; void tst_QShaderGraph::shouldHaveEdgeDefaultState() @@ -657,6 +658,122 @@ void tst_QShaderGraph::shouldDealWithEdgesJumpingOverLayers() QCOMPARE(statements, expected); } +void tst_QShaderGraph::shouldGenerateDifferentStatementsDependingOnActiveLayers() +{ + // GIVEN + const auto texCoord = createNode({ + createPort(QShaderNodePort::Output, "texCoord") + }, { + "diffuseTexture", + "normalTexture" + }); + const auto diffuseUniform = createNode({ + createPort(QShaderNodePort::Output, "color") + }, {"diffuseUniform"}); + const auto diffuseTexture = createNode({ + createPort(QShaderNodePort::Input, "coord"), + createPort(QShaderNodePort::Output, "color") + }, {"diffuseTexture"}); + const auto normalUniform = createNode({ + createPort(QShaderNodePort::Output, "normal") + }, {"normalUniform"}); + const auto normalTexture = createNode({ + createPort(QShaderNodePort::Input, "coord"), + createPort(QShaderNodePort::Output, "normal") + }, {"normalTexture"}); + const auto lightFunction = createNode({ + createPort(QShaderNodePort::Input, "color"), + createPort(QShaderNodePort::Input, "normal"), + createPort(QShaderNodePort::Output, "output") + }); + const auto fragColor = createNode({ + createPort(QShaderNodePort::Input, "fragColor") + }); + + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(texCoord); + res.addNode(diffuseUniform); + res.addNode(diffuseTexture); + res.addNode(normalUniform); + res.addNode(normalTexture); + res.addNode(lightFunction); + res.addNode(fragColor); + + res.addEdge(createEdge(diffuseUniform.uuid(), "color", lightFunction.uuid(), "color", {"diffuseUniform"})); + res.addEdge(createEdge(texCoord.uuid(), "texCoord", diffuseTexture.uuid(), "coord", {"diffuseTexture"})); + res.addEdge(createEdge(diffuseTexture.uuid(), "color", lightFunction.uuid(), "color", {"diffuseTexture"})); + + res.addEdge(createEdge(normalUniform.uuid(), "normal", lightFunction.uuid(), "normal", {"normalUniform"})); + res.addEdge(createEdge(texCoord.uuid(), "texCoord", normalTexture.uuid(), "coord", {"normalTexture"})); + res.addEdge(createEdge(normalTexture.uuid(), "normal", lightFunction.uuid(), "normal", {"normalTexture"})); + + res.addEdge(createEdge(lightFunction.uuid(), "output", fragColor.uuid(), "fragColor")); + + return res; + }(); + + { + // WHEN + const auto statements = graph.createStatements({"diffuseUniform", "normalUniform"}); + + // THEN + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(normalUniform, {}, {1}) + << createStatement(diffuseUniform, {}, {0}) + << createStatement(lightFunction, {0, 1}, {2}) + << createStatement(fragColor, {2}, {}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); + } + + { + // WHEN + const auto statements = graph.createStatements({"diffuseUniform", "normalTexture"}); + + // THEN + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(texCoord, {}, {0}) + << createStatement(normalTexture, {0}, {2}) + << createStatement(diffuseUniform, {}, {1}) + << createStatement(lightFunction, {1, 2}, {3}) + << createStatement(fragColor, {3}, {}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); + } + + { + // WHEN + const auto statements = graph.createStatements({"diffuseTexture", "normalUniform"}); + + // THEN + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(texCoord, {}, {0}) + << createStatement(normalUniform, {}, {2}) + << createStatement(diffuseTexture, {0}, {1}) + << createStatement(lightFunction, {1, 2}, {3}) + << createStatement(fragColor, {3}, {}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); + } + + { + // WHEN + const auto statements = graph.createStatements({"diffuseTexture", "normalTexture"}); + + // THEN + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(texCoord, {}, {0}) + << createStatement(normalTexture, {0}, {2}) + << createStatement(diffuseTexture, {0}, {1}) + << createStatement(lightFunction, {1, 2}, {3}) + << createStatement(fragColor, {3}, {}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); + } +} + QTEST_MAIN(tst_QShaderGraph) #include "tst_qshadergraph.moc" |