Extend the parameter support in QShaderGraphLoader for richer types

In particular, go through QMetaType/QMetaEnum to deal with enums.

Change-Id: I2e847ba328eb46609b86b3dfd6c4dbf532d78b7d
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
bb10
Kevin Ottens 2017-07-12 14:03:08 +02:00 committed by Sean Harmer
parent 50775424be
commit dd04551504
2 changed files with 53 additions and 14 deletions

View File

@ -44,6 +44,7 @@
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qmetaobject.h>
QT_BEGIN_NAMESPACE
@ -157,7 +158,30 @@ void QShaderGraphLoader::load()
if (parametersValue.isObject()) {
const auto parametersObject = parametersValue.toObject();
for (const auto &parameterName : parametersObject.keys()) {
node.setParameter(parameterName, parametersObject.value(parameterName).toVariant());
const auto parameterValue = parametersObject.value(parameterName);
if (parameterValue.isObject()) {
const auto parameterObject = parameterValue.toObject();
const auto type = parameterObject.value(QStringLiteral("type")).toString();
const auto typeId = QMetaType::type(type.toUtf8());
const auto value = parameterObject.value(QStringLiteral("value")).toString();
auto variant = QVariant(value);
if (QMetaType::typeFlags(typeId) & QMetaType::IsEnumeration) {
const auto metaObject = QMetaType::metaObjectForType(typeId);
const auto className = metaObject->className();
const auto enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
const auto metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
const auto enumValue = metaEnum.keyToValue(value.toUtf8());
variant = QVariant(enumValue);
variant.convert(typeId);
} else {
variant.convert(typeId);
}
node.setParameter(parameterName, variant);
} else {
node.setParameter(parameterName, parameterValue.toVariant());
}
}
}

View File

@ -32,6 +32,7 @@
#include <QtCore/qbuffer.h>
#include <QtGui/private/qshadergraphloader_p.h>
#include <QtGui/private/qshaderlanguage_p.h>
using QBufferPointer = QSharedPointer<QBuffer>;
Q_DECLARE_METATYPE(QBufferPointer);
@ -98,10 +99,12 @@ namespace
});
worldPosition.setUuid(QUuid("{00000000-0000-0000-0000-000000000001}"));
worldPosition.setParameter("name", "worldPosition");
worldPosition.addRule(openGLES2, QShaderNode::Rule("highp vec3 $value = $name;",
QByteArrayList() << "varying highp vec3 $name;"));
worldPosition.addRule(openGL3, QShaderNode::Rule("vec3 $value = $name;",
QByteArrayList() << "in vec3 $name;"));
worldPosition.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(QShaderLanguage::Input));
worldPosition.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(QShaderLanguage::Vec3));
worldPosition.addRule(openGLES2, QShaderNode::Rule("highp $type $value = $name;",
QByteArrayList() << "$qualifier highp $type $name;"));
worldPosition.addRule(openGL3, QShaderNode::Rule("$type $value = $name;",
QByteArrayList() << "$qualifier $type $name;"));
auto texture = createNode({
createPort(QShaderNodePort::Output, "texture")
@ -126,10 +129,12 @@ namespace
});
lightIntensity.setUuid(QUuid("{00000000-0000-0000-0000-000000000004}"));
lightIntensity.setParameter("name", "defaultName");
lightIntensity.addRule(openGLES2, QShaderNode::Rule("highp vec3 $value = $name;",
QByteArrayList() << "varying highp vec3 $name;"));
lightIntensity.addRule(openGL3, QShaderNode::Rule("vec3 $value = $name;",
QByteArrayList() << "in vec3 $name;"));
lightIntensity.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(QShaderLanguage::Uniform));
lightIntensity.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(QShaderLanguage::Float));
lightIntensity.addRule(openGLES2, QShaderNode::Rule("highp $type $value = $name;",
QByteArrayList() << "$qualifier highp $type $name;"));
lightIntensity.addRule(openGL3, QShaderNode::Rule("$type $value = $name;",
QByteArrayList() << "$qualifier $type $name;"));
auto exposure = createNode({
createPort(QShaderNodePort::Output, "exposure")
@ -377,7 +382,15 @@ void tst_QShaderGraphLoader::shouldLoadFromJsonStream_data()
" \"uuid\": \"{00000000-0000-0000-0000-000000000001}\","
" \"type\": \"inputValue\","
" \"parameters\": {"
" \"name\": \"worldPosition\""
" \"name\": \"worldPosition\","
" \"qualifier\": {"
" \"type\": \"QShaderLanguage::StorageQualifier\","
" \"value\": \"QShaderLanguage::Input\""
" },"
" \"type\": {"
" \"type\": \"QShaderLanguage::VariableType\","
" \"value\": \"QShaderLanguage::Vec3\""
" }"
" }"
" },"
" {"
@ -475,10 +488,12 @@ void tst_QShaderGraphLoader::shouldLoadFromJsonStream_data()
createPort(QShaderNodePort::Output, "value")
});
inputValue.setParameter("name", "defaultName");
inputValue.addRule(openGLES2, QShaderNode::Rule("highp vec3 $value = $name;",
QByteArrayList() << "varying highp vec3 $name;"));
inputValue.addRule(openGL3, QShaderNode::Rule("vec3 $value = $name;",
QByteArrayList() << "in vec3 $name;"));
inputValue.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(QShaderLanguage::Uniform));
inputValue.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(QShaderLanguage::Float));
inputValue.addRule(openGLES2, QShaderNode::Rule("highp $type $value = $name;",
QByteArrayList() << "$qualifier highp $type $name;"));
inputValue.addRule(openGL3, QShaderNode::Rule("$type $value = $name;",
QByteArrayList() << "$qualifier $type $name;"));
protos.insert("inputValue", inputValue);
auto texture = createNode({