summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-10-10 12:20:00 +0200
committerPaul Lemire <paul.lemire@kdab.com>2018-12-14 13:26:57 +0000
commitd403604d74780b6bf2a7dee235942a2c9a9305d2 (patch)
treec943f63d6327d0a9451f8c1fb924dc0bd1d7b055
parente3fbebe61111dfe670ffe19c96e313157df7331f (diff)
QShaderProgramBuilder: add properties to access generated shader code
Change-Id: Ib4d448198b2f53850ff0c9b1f2ff4d2d905eea26 Reviewed-by: Mike Krus <mike.krus@kdab.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/quick3d/imports/render/qt3dquick3drenderplugin.cpp1
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder.cpp155
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder.h19
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder_p.h6
-rw-r--r--src/render/materialsystem/shaderbuilder.cpp33
-rw-r--r--tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp92
-rw-r--r--tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp79
7 files changed, 382 insertions, 3 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
index 4c8e2c0ca..d57c8c01f 100644
--- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
+++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
@@ -180,6 +180,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DRender::QShaderProgram>(uri, 2, 0, "ShaderProgram");
qmlRegisterType<Qt3DRender::QShaderProgram, 9>(uri, 2, 9, "ShaderProgram");
qmlRegisterType<Qt3DRender::QShaderProgramBuilder>(uri, 2, 10, "ShaderProgramBuilder");
+ qmlRegisterType<Qt3DRender::QShaderProgramBuilder>(uri, 2, 13, "ShaderProgramBuilder");
qmlRegisterUncreatableType<Qt3DRender::QShaderData>(uri, 2, 0, "QShaderData", "Quick3D should instantiate Quick3DShaderData only");
qmlRegisterType<Qt3DRender::Render::Quick::Quick3DShaderDataArray>(uri, 2, 0, "ShaderDataArray");
qmlRegisterType<Qt3DRender::Render::Quick::Quick3DShaderData>(uri, 2, 0, "ShaderData");
diff --git a/src/render/materialsystem/qshaderprogrambuilder.cpp b/src/render/materialsystem/qshaderprogrambuilder.cpp
index 9318f96af..84dd33372 100644
--- a/src/render/materialsystem/qshaderprogrambuilder.cpp
+++ b/src/render/materialsystem/qshaderprogrambuilder.cpp
@@ -94,6 +94,53 @@ QShaderProgramBuilder::QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Q
{
}
+void QShaderProgramBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
+{
+ Q_D(QShaderProgramBuilder);
+ if (change->type() == Qt3DCore::PropertyUpdated) {
+ const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
+ if (e->propertyName() == QByteArrayLiteral("generatedShaderCode")) {
+ const bool blocked = blockNotifications(true);
+ const QPair<int, QByteArray> data = e->value().value<QPair<int, QByteArray>>();
+
+ switch (data.first) {
+ case QShaderProgram::Vertex: {
+ d->m_vertexShaderCode = data.second;
+ emit vertexShaderCodeChanged(d->m_vertexShaderCode);
+ break;
+ }
+ case QShaderProgram::Fragment:{
+ d->m_fragmentShaderCode = data.second;
+ emit fragmentShaderCodeChanged(d->m_fragmentShaderCode);
+ break;
+ }
+ case QShaderProgram::Geometry: {
+ d->m_geometryShaderCode = data.second;
+ emit geometryShaderCodeChanged(d->m_geometryShaderCode);
+ break;
+ }
+ case QShaderProgram::Compute: {
+ d->m_computeShaderCode = data.second;
+ emit computeShaderCodeChanged(d->m_computeShaderCode);
+ break;
+ }
+ case QShaderProgram::TessellationControl: {
+ d->m_tessControlShaderCode = data.second;
+ emit tessellationControlShaderCodeChanged(d->m_tessControlShaderCode);
+ break;
+ }
+ case QShaderProgram::TessellationEvaluation: {
+ d->m_tessEvalShaderCode = data.second;
+ emit tessellationEvaluationShaderCodeChanged(d->m_tessEvalShaderCode);
+ break;
+ }
+ }
+
+ blockNotifications(blocked);
+ }
+ }
+}
+
/*!
\qmlproperty string ShaderProgramBuilder::shaderProgram
@@ -311,6 +358,114 @@ QUrl QShaderProgramBuilder::computeShaderGraph() const
return d->m_computeShaderGraph;
}
+/*!
+ \qmlproperty string ShaderProgramBuilder:vertexShaderCode
+
+ Holds the generated vertex shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:vertexShaderCode
+
+ Holds the generate vertex shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::vertexShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_vertexShaderCode;
+}
+
+/*!
+ \qmlproperty string ShaderProgramBuilder:tessellationControlShaderCode
+
+ Holds the generated tessellation control shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:tessellationControlShaderCode
+
+ Holds the generate tessellation control shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::tessellationControlShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_tessControlShaderCode;
+}
+
+/*!
+ \qmlproperty string ShaderProgramBuilder:tessellationEvaluationShaderCode
+
+ Holds the generated tessellation evaluation shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:tessellationEvaluationShaderCode
+
+ Holds the generate tessellation evaluation shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::tessellationEvaluationShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_tessEvalShaderCode;
+}
+
+/*!
+ \qmlproperty string ShaderProgramBuilder:geometryShaderCode
+
+ Holds the generated geometry shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:geometryShaderCode
+
+ Holds the generate geometry shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::geometryShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_geometryShaderCode;
+}
+
+/*!
+ \qmlproperty string ShaderProgramBuilder::fragmentShaderCode
+
+ Holds the generated fragment shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:fragmentShaderCode
+
+ Holds the generate fragment shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::fragmentShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_fragmentShaderCode;
+}
+
+/*!
+ \qmlproperty string ShaderProgramBuilder::computeShaderCode
+
+ Holds the generated compute shader code
+ \since 2.13
+*/
+/*!
+ \property QShaderProgram:Builder:computeShaderCode
+
+ Holds the generate compute shader code.
+ \since 5.13
+*/
+QByteArray QShaderProgramBuilder::computeShaderCode() const
+{
+ Q_D(const QShaderProgramBuilder);
+ return d->m_computeShaderCode;
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QShaderProgramBuilder::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QShaderProgramBuilderData>::create(this);
diff --git a/src/render/materialsystem/qshaderprogrambuilder.h b/src/render/materialsystem/qshaderprogrambuilder.h
index fbbf7c752..532aa7d73 100644
--- a/src/render/materialsystem/qshaderprogrambuilder.h
+++ b/src/render/materialsystem/qshaderprogrambuilder.h
@@ -63,6 +63,12 @@ class QT3DRENDERSHARED_EXPORT QShaderProgramBuilder : public Qt3DCore::QNode
Q_PROPERTY(QUrl geometryShaderGraph READ geometryShaderGraph WRITE setGeometryShaderGraph NOTIFY geometryShaderGraphChanged)
Q_PROPERTY(QUrl fragmentShaderGraph READ fragmentShaderGraph WRITE setFragmentShaderGraph NOTIFY fragmentShaderGraphChanged)
Q_PROPERTY(QUrl computeShaderGraph READ computeShaderGraph WRITE setComputeShaderGraph NOTIFY computeShaderGraphChanged)
+ Q_PROPERTY(QByteArray vertexShaderCode READ vertexShaderCode NOTIFY vertexShaderCodeChanged REVISION 13)
+ Q_PROPERTY(QByteArray tessellationControlShaderCode READ tessellationControlShaderCode NOTIFY tessellationControlShaderCodeChanged REVISION 13)
+ Q_PROPERTY(QByteArray tessellationEvaluationShaderCode READ tessellationEvaluationShaderCode NOTIFY tessellationEvaluationShaderCodeChanged REVISION 13)
+ Q_PROPERTY(QByteArray geometryShaderCode READ geometryShaderCode NOTIFY geometryShaderCodeChanged REVISION 13)
+ Q_PROPERTY(QByteArray fragmentShaderCode READ fragmentShaderCode NOTIFY fragmentShaderCodeChanged REVISION 13)
+ Q_PROPERTY(QByteArray computeShaderCode READ computeShaderCode NOTIFY computeShaderCodeChanged REVISION 13)
public:
explicit QShaderProgramBuilder(Qt3DCore::QNode *parent = nullptr);
@@ -76,6 +82,12 @@ public:
QUrl geometryShaderGraph() const;
QUrl fragmentShaderGraph() const;
QUrl computeShaderGraph() const;
+ QByteArray vertexShaderCode() const;
+ QByteArray tessellationControlShaderCode() const;
+ QByteArray tessellationEvaluationShaderCode() const;
+ QByteArray geometryShaderCode() const;
+ QByteArray fragmentShaderCode() const;
+ QByteArray computeShaderCode() const;
public Q_SLOTS:
void setShaderProgram(Qt3DRender::QShaderProgram *program);
@@ -96,9 +108,16 @@ Q_SIGNALS:
void geometryShaderGraphChanged(const QUrl &geometryShaderGraph);
void fragmentShaderGraphChanged(const QUrl &fragmentShaderGraph);
void computeShaderGraphChanged(const QUrl &computeShaderGraph);
+ void vertexShaderCodeChanged(const QByteArray &vertexShaderCode);
+ void tessellationControlShaderCodeChanged(const QByteArray &tessellationControlShaderCode);
+ void tessellationEvaluationShaderCodeChanged(const QByteArray &tessellationEvaluationShaderCode);
+ void geometryShaderCodeChanged(const QByteArray &geometryShaderCode);
+ void fragmentShaderCodeChanged(const QByteArray &fragmentShaderCode);
+ void computeShaderCodeChanged(const QByteArray &computeShaderCode);
protected:
explicit QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QShaderProgramBuilder)
diff --git a/src/render/materialsystem/qshaderprogrambuilder_p.h b/src/render/materialsystem/qshaderprogrambuilder_p.h
index e1b470229..2ac765a1d 100644
--- a/src/render/materialsystem/qshaderprogrambuilder_p.h
+++ b/src/render/materialsystem/qshaderprogrambuilder_p.h
@@ -74,6 +74,12 @@ public:
QUrl m_geometryShaderGraph;
QUrl m_fragmentShaderGraph;
QUrl m_computeShaderGraph;
+ QByteArray m_vertexShaderCode;
+ QByteArray m_tessControlShaderCode;
+ QByteArray m_tessEvalShaderCode;
+ QByteArray m_geometryShaderCode;
+ QByteArray m_fragmentShaderCode;
+ QByteArray m_computeShaderCode;
};
struct QShaderProgramBuilderData
diff --git a/src/render/materialsystem/shaderbuilder.cpp b/src/render/materialsystem/shaderbuilder.cpp
index 283866d68..e0683332f 100644
--- a/src/render/materialsystem/shaderbuilder.cpp
+++ b/src/render/materialsystem/shaderbuilder.cpp
@@ -40,6 +40,7 @@
#include "shaderbuilder_p.h"
#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
+#include <Qt3DRender/qshaderprogram.h>
#include <Qt3DRender/private/qurlhelper_p.h>
#include <QtGui/private/qshaderformat_p.h>
@@ -111,6 +112,31 @@ using namespace Qt3DCore;
namespace Qt3DRender {
namespace Render {
+
+namespace {
+
+QShaderProgram::ShaderType toQShaderProgramType(ShaderBuilder::ShaderType type)
+{
+ switch (type) {
+ case ShaderBuilder::ShaderType::Vertex:
+ return QShaderProgram::Vertex;
+ case ShaderBuilder::ShaderType::TessellationControl:
+ return QShaderProgram::TessellationControl;
+ case ShaderBuilder::ShaderType::TessellationEvaluation:
+ return QShaderProgram::TessellationEvaluation;
+ case ShaderBuilder::ShaderType::Geometry:
+ return QShaderProgram::Geometry;
+ case ShaderBuilder::ShaderType::Fragment:
+ return QShaderProgram::Fragment;
+ case ShaderBuilder::ShaderType::Compute:
+ return QShaderProgram::Compute;
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
+} // anonymous
+
QString ShaderBuilder::getPrototypesFile()
{
return qt3dGlobalShaderPrototypes->prototypesFile();
@@ -284,6 +310,13 @@ void ShaderBuilder::generateCode(ShaderBuilder::ShaderType type)
const auto code = generator.createShaderCode(m_enabledLayers);
m_codes.insert(type, deincludify(code, graphPath + QStringLiteral(".glsl")));
m_dirtyTypes.remove(type);
+
+ // Send notification to the frontend
+ Qt3DCore::QPropertyUpdatedChangePtr propertyChange = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
+ propertyChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
+ propertyChange->setPropertyName("generatedShaderCode");
+ propertyChange->setValue(QVariant::fromValue(qMakePair(int(toQShaderProgramType(type)), m_codes.value(type))));
+ notifyObservers(propertyChange);
}
void ShaderBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
index 93bee22cc..021a3d6c1 100644
--- a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
+++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
@@ -38,12 +38,12 @@
#include <Qt3DCore/qnodecreatedchange.h>
#include "testpostmanarbiter.h"
-class tst_QShaderProgramBuilder : public QObject
+class tst_QShaderProgramBuilder : public Qt3DRender::QShaderProgramBuilder
{
Q_OBJECT
public:
tst_QShaderProgramBuilder()
- : QObject()
+ : Qt3DRender::QShaderProgramBuilder()
{
qRegisterMetaType<Qt3DRender::QShaderProgram*>("Qt3DRender::QShaderProgram*");
}
@@ -63,6 +63,12 @@ private Q_SLOTS:
QCOMPARE(builder.geometryShaderGraph(), QUrl());
QCOMPARE(builder.fragmentShaderGraph(), QUrl());
QCOMPARE(builder.computeShaderGraph(), QUrl());
+ QCOMPARE(builder.vertexShaderCode(), QByteArray());
+ QCOMPARE(builder.fragmentShaderCode(), QByteArray());
+ QCOMPARE(builder.computeShaderCode(), QByteArray());
+ QCOMPARE(builder.geometryShaderCode(), QByteArray());
+ QCOMPARE(builder.tessellationEvaluationShaderCode(), QByteArray());
+ QCOMPARE(builder.tessellationControlShaderCode(), QByteArray());
}
void checkPropertyChanges()
@@ -592,8 +598,90 @@ private Q_SLOTS:
// THEN
QCOMPARE(arbiter.events.size(), 0);
}
+ }
+
+ void checkGeneratedCodePropertyUpdates()
+ {
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(vertexShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Vertex), QByteArrayLiteral("vertex"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(vertexShaderCode(), QByteArrayLiteral("vertex"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(fragmentShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Fragment), QByteArrayLiteral("fragment"))));
+ sceneChangeEvent(valueChange);
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(fragmentShaderCode(), QByteArrayLiteral("fragment"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(geometryShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Geometry), QByteArrayLiteral("geometry"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(geometryShaderCode(), QByteArrayLiteral("geometry"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(computeShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Compute), QByteArrayLiteral("compute"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(computeShaderCode(), QByteArrayLiteral("compute"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(tessellationControlShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationControl), QByteArrayLiteral("control"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(tessellationControlShaderCode(), QByteArrayLiteral("control"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(tessellationEvaluationShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationEvaluation), QByteArrayLiteral("eval"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(tessellationEvaluationShaderCode(), QByteArrayLiteral("eval"));
+ }
}
+
};
QTEST_MAIN(tst_QShaderProgramBuilder)
diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
index 6557acb6c..007bfac7c 100644
--- a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
+++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
@@ -28,12 +28,15 @@
#include <QtTest/QTest>
#include <qbackendnodetester.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DRender/private/shaderbuilder_p.h>
#include <Qt3DRender/qshaderprogram.h>
#include <Qt3DRender/qshaderprogrambuilder.h>
#include "testrenderer.h"
+#include "testpostmanarbiter.h"
Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderBuilder::ShaderType)
+Q_DECLARE_METATYPE(Qt3DRender::QShaderProgram::ShaderType)
class tst_ShaderBuilder : public Qt3DCore::QBackendNodeTester
{
@@ -539,7 +542,81 @@ private slots:
// THEN
QCOMPARE(backend.shaderGraph(type), graphUrl);
QVERIFY(!backend.isShaderCodeDirty(type));
-// QCOMPARE(backend.shaderCode(type), es2Code);
+ QCOMPARE(backend.shaderCode(type), es2Code);
+ }
+
+ void checkCodeUpdatedNotification_data()
+ {
+ QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type");
+ QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("notificationType");
+
+ QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex << Qt3DRender::QShaderProgram::Vertex;
+ QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl << Qt3DRender::QShaderProgram::TessellationControl;
+ QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation << Qt3DRender::QShaderProgram::TessellationEvaluation;
+ QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry << Qt3DRender::QShaderProgram::Geometry;
+ QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment << Qt3DRender::QShaderProgram::Fragment;
+ QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute << Qt3DRender::QShaderProgram::Compute;
+ }
+
+
+ void checkCodeUpdatedNotification()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json");
+ QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty());
+ QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type);
+ QFETCH(Qt3DRender::QShaderProgram::ShaderType, notificationType);
+
+ const auto gl3Api = []{
+ auto api = Qt3DRender::GraphicsApiFilterData();
+ api.m_api = Qt3DRender::QGraphicsApiFilter::OpenGL;
+ api.m_profile = Qt3DRender::QGraphicsApiFilter::CoreProfile;
+ api.m_major = 3;
+ api.m_minor = 2;
+ return api;
+ }();
+
+ const auto readCode = [](const QString &suffix) -> QString {
+ const auto filePath = QStringLiteral(":/output.") + suffix;
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly | QFile::Text))
+ qFatal("File open failed: %s", qPrintable(filePath));
+ return file.readAll();
+ };
+
+ const auto gl3Code = readCode("gl3");
+
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestArbiter arbiter;
+ Qt3DCore::QBackendNodePrivate::get(&backend)->setArbiter(&arbiter);
+
+
+ // WHEN
+ const auto graphUrl = QUrl::fromEncoded("qrc:/input.json");
+ backend.setShaderGraph(type, graphUrl);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+
+ // WHEN
+ backend.setGraphicsApi(gl3Api);
+ backend.generateCode(type);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ QCOMPARE(backend.shaderCode(type), gl3Code);
+
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(arbiter.events.count(), 1);
+ QCOMPARE(change->propertyName(), "generatedShaderCode");
+ const QPair<int, QByteArray> value = change->value().value<QPair<int, QByteArray>>();
+ QCOMPARE(value.first, int(notificationType));
+ QCOMPARE(value.second, gl3Code);
+
+ arbiter.events.clear();
}
};