2023-08-17 18:38:40 +03:00
|
|
|
// Copyright (C) 2023 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
|
|
|
|
|
|
#include "uniform.h"
|
2023-09-15 15:36:15 +03:00
|
|
|
#include <qmldesignerplugin.h>
|
2023-08-17 18:38:40 +03:00
|
|
|
|
2023-08-24 15:21:52 +03:00
|
|
|
|
2023-08-21 15:26:32 +03:00
|
|
|
#include <QColor>
|
2023-08-17 18:38:40 +03:00
|
|
|
#include <QJsonObject>
|
2023-08-21 15:26:32 +03:00
|
|
|
#include <QVector2D>
|
2023-08-17 18:38:40 +03:00
|
|
|
|
2023-09-15 15:36:15 +03:00
|
|
|
namespace EffectMaker {
|
2023-08-17 18:38:40 +03:00
|
|
|
|
2023-08-18 15:39:40 +03:00
|
|
|
Uniform::Uniform(const QJsonObject &propObj)
|
|
|
|
|
{
|
2023-08-21 15:26:32 +03:00
|
|
|
QString value, defaultValue, minValue, maxValue;
|
2023-08-18 15:39:40 +03:00
|
|
|
|
|
|
|
|
m_name = propObj.value("name").toString();
|
|
|
|
|
m_description = propObj.value("description").toString();
|
2023-08-28 13:30:36 +03:00
|
|
|
m_type = Uniform::typeFromString(propObj.value("type").toString());
|
2023-08-18 15:39:40 +03:00
|
|
|
defaultValue = propObj.value("defaultValue").toString();
|
|
|
|
|
|
2023-09-05 18:03:05 +03:00
|
|
|
m_displayName = propObj.value("displayName").toString();
|
|
|
|
|
if (m_displayName.isEmpty())
|
|
|
|
|
m_displayName = m_name;
|
|
|
|
|
|
2023-08-18 15:39:40 +03:00
|
|
|
if (m_type == Type::Sampler) {
|
|
|
|
|
if (!defaultValue.isEmpty())
|
|
|
|
|
defaultValue = getResourcePath(defaultValue);
|
|
|
|
|
if (propObj.contains("enableMipmap"))
|
|
|
|
|
m_enableMipmap = getBoolValue(propObj.value("enableMipmap"), false);
|
|
|
|
|
// Update the mipmap property
|
|
|
|
|
QString mipmapProperty = mipmapPropertyName(m_name);
|
|
|
|
|
}
|
|
|
|
|
if (propObj.contains("value")) {
|
|
|
|
|
value = propObj.value("value").toString();
|
|
|
|
|
if (m_type == Type::Sampler && !value.isEmpty())
|
|
|
|
|
value = getResourcePath(value);
|
|
|
|
|
} else {
|
|
|
|
|
// QEN files don't store the current value, so with those use default value
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
}
|
2023-08-21 15:26:32 +03:00
|
|
|
minValue = propObj.value("minValue").toString();
|
|
|
|
|
maxValue = propObj.value("maxValue").toString();
|
|
|
|
|
|
|
|
|
|
setValueData(value, defaultValue, minValue, maxValue);
|
2023-08-24 15:21:52 +03:00
|
|
|
|
2023-09-15 15:36:15 +03:00
|
|
|
m_backendValue = new QmlDesigner::PropertyEditorValue(this);
|
2023-08-24 15:21:52 +03:00
|
|
|
m_backendValue->setValue(value);
|
2023-08-17 18:38:40 +03:00
|
|
|
}
|
|
|
|
|
|
2023-08-28 13:30:36 +03:00
|
|
|
Uniform::Type Uniform::type() const
|
2023-08-18 11:47:16 +03:00
|
|
|
{
|
2023-08-28 13:30:36 +03:00
|
|
|
return m_type;
|
|
|
|
|
}
|
2023-08-22 17:05:28 +03:00
|
|
|
|
2023-08-28 13:30:36 +03:00
|
|
|
// String representation of the type for qml
|
|
|
|
|
QString Uniform::typeName() const
|
|
|
|
|
{
|
|
|
|
|
return Uniform::stringFromType(m_type);
|
2023-08-18 11:47:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant Uniform::value() const
|
|
|
|
|
{
|
|
|
|
|
return m_value;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-24 15:21:52 +03:00
|
|
|
QVariant Uniform::backendValue() const
|
|
|
|
|
{
|
|
|
|
|
return QVariant::fromValue(m_backendValue);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 11:47:16 +03:00
|
|
|
void Uniform::setValue(const QVariant &newValue)
|
|
|
|
|
{
|
2023-08-21 22:18:16 +03:00
|
|
|
if (m_value != newValue) {
|
|
|
|
|
m_value = newValue;
|
|
|
|
|
emit uniformValueChanged();
|
|
|
|
|
}
|
2023-08-18 11:47:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant Uniform::defaultValue() const
|
|
|
|
|
{
|
|
|
|
|
return m_defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant Uniform::minValue() const
|
|
|
|
|
{
|
|
|
|
|
return m_minValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant Uniform::maxValue() const
|
|
|
|
|
{
|
|
|
|
|
return m_maxValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Uniform::name() const
|
|
|
|
|
{
|
|
|
|
|
return m_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Uniform::description() const
|
|
|
|
|
{
|
|
|
|
|
return m_description;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Uniform::customValue() const
|
|
|
|
|
{
|
|
|
|
|
return m_customValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Uniform::setCustomValue(const QString &newCustomValue)
|
|
|
|
|
{
|
|
|
|
|
m_customValue = newCustomValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Uniform::useCustomValue() const
|
|
|
|
|
{
|
|
|
|
|
return m_useCustomValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Uniform::enabled() const
|
|
|
|
|
{
|
|
|
|
|
return m_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Uniform::setEnabled(bool newEnabled)
|
|
|
|
|
{
|
|
|
|
|
m_enabled = newEnabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Uniform::enableMipmap() const
|
|
|
|
|
{
|
|
|
|
|
return m_enableMipmap;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 15:39:40 +03:00
|
|
|
// Returns name for image mipmap property.
|
|
|
|
|
// e.g. "myImage" -> "myImageMipmap".
|
|
|
|
|
QString Uniform::mipmapPropertyName(const QString &name) const
|
|
|
|
|
{
|
|
|
|
|
QString simplifiedName = name.simplified();
|
|
|
|
|
simplifiedName = simplifiedName.remove(' ');
|
|
|
|
|
simplifiedName += "Mipmap";
|
|
|
|
|
return simplifiedName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns the boolean value of QJsonValue. It can be either boolean
|
|
|
|
|
// (true, false) or string ("true", "false"). Returns the defaultValue
|
|
|
|
|
// if QJsonValue is undefined, empty, or some other type.
|
|
|
|
|
bool Uniform::getBoolValue(const QJsonValue &jsonValue, bool defaultValue)
|
|
|
|
|
{
|
|
|
|
|
if (jsonValue.isBool())
|
|
|
|
|
return jsonValue.toBool();
|
|
|
|
|
|
|
|
|
|
if (jsonValue.isString())
|
|
|
|
|
return jsonValue.toString().toLower() == "true";
|
|
|
|
|
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns the path for a shader resource
|
|
|
|
|
// Used with sampler types
|
|
|
|
|
QString Uniform::getResourcePath(const QString &value) const
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(value)
|
|
|
|
|
//TODO
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-21 15:26:32 +03:00
|
|
|
// Validation and setting values
|
|
|
|
|
void Uniform::setValueData(const QString &value, const QString &defaultValue,
|
|
|
|
|
const QString &minValue, const QString &maxValue)
|
|
|
|
|
{
|
2023-08-28 13:30:36 +03:00
|
|
|
m_value = value.isEmpty() ? getInitializedVariant(false) : valueStringToVariant(value);
|
|
|
|
|
m_defaultValue = defaultValue.isEmpty() ? getInitializedVariant(false)
|
|
|
|
|
: valueStringToVariant(defaultValue);
|
|
|
|
|
m_minValue = minValue.isEmpty() ? getInitializedVariant(false) : valueStringToVariant(minValue);
|
|
|
|
|
m_maxValue = maxValue.isEmpty() ? getInitializedVariant(true) : valueStringToVariant(maxValue);
|
2023-08-21 15:26:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize the value variant with correct type
|
2023-08-28 13:30:36 +03:00
|
|
|
QVariant Uniform::getInitializedVariant(bool maxValue)
|
2023-08-21 15:26:32 +03:00
|
|
|
{
|
2023-08-28 13:30:36 +03:00
|
|
|
switch (m_type) {
|
2023-08-21 15:26:32 +03:00
|
|
|
case Uniform::Type::Bool:
|
|
|
|
|
return maxValue ? true : false;
|
|
|
|
|
case Uniform::Type::Int:
|
|
|
|
|
return maxValue ? 100 : 0;
|
|
|
|
|
case Uniform::Type::Float:
|
|
|
|
|
return maxValue ? 1.0 : 0.0;
|
|
|
|
|
case Uniform::Type::Vec2:
|
|
|
|
|
return maxValue ? QVector2D(1.0, 1.0) : QVector2D(0.0, 0.0);
|
|
|
|
|
case Uniform::Type::Vec3:
|
|
|
|
|
return maxValue ? QVector3D(1.0, 1.0, 1.0) : QVector3D(0.0, 0.0, 0.0);
|
|
|
|
|
case Uniform::Type::Vec4:
|
|
|
|
|
return maxValue ? QVector4D(1.0, 1.0, 1.0, 1.0) : QVector4D(0.0, 0.0, 0.0, 0.0);
|
|
|
|
|
case Uniform::Type::Color:
|
|
|
|
|
return maxValue ? QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f) : QColor::fromRgbF(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
|
default:
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-28 13:30:36 +03:00
|
|
|
QVariant Uniform::valueStringToVariant(const QString &value)
|
2023-08-21 15:26:32 +03:00
|
|
|
{
|
|
|
|
|
QVariant variant;
|
2023-08-28 13:30:36 +03:00
|
|
|
switch (m_type) {
|
2023-08-21 15:26:32 +03:00
|
|
|
case Type::Bool:
|
|
|
|
|
variant = (value == "true");
|
|
|
|
|
break;
|
|
|
|
|
case Type::Int:
|
|
|
|
|
case Type::Float:
|
|
|
|
|
variant = value;
|
|
|
|
|
break;
|
|
|
|
|
case Type::Vec2: {
|
|
|
|
|
QStringList list = value.split(QLatin1Char(','));
|
|
|
|
|
if (list.size() >= 2)
|
|
|
|
|
variant = QVector2D(list.at(0).toDouble(), list.at(1).toDouble());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type::Vec3: {
|
|
|
|
|
QStringList list = value.split(QLatin1Char(','));
|
|
|
|
|
if (list.size() >= 3)
|
|
|
|
|
variant = QVector3D(list.at(0).toDouble(), list.at(1).toDouble(), list.at(2).toDouble());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type::Vec4: {
|
|
|
|
|
QStringList list = value.split(QLatin1Char(','));
|
|
|
|
|
if (list.size() >= 4)
|
|
|
|
|
variant = QVector4D(list.at(0).toDouble(), list.at(1).toDouble(),
|
|
|
|
|
list.at(2).toDouble(), list.at(3).toDouble());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type::Color: {
|
|
|
|
|
QStringList list = value.split(QLatin1Char(','));
|
|
|
|
|
if (list.size() >= 4)
|
|
|
|
|
variant = QColor::fromRgbF(list.at(0).toDouble(), list.at(1).toDouble(),
|
|
|
|
|
list.at(2).toDouble(), list.at(3).toDouble());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type::Sampler:
|
|
|
|
|
variant = value;
|
|
|
|
|
break;
|
|
|
|
|
case Uniform::Type::Define:
|
|
|
|
|
variant = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return variant;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-28 13:30:36 +03:00
|
|
|
QString Uniform::stringFromType(Uniform::Type type)
|
|
|
|
|
{
|
|
|
|
|
if (type == Type::Bool)
|
|
|
|
|
return "bool";
|
|
|
|
|
else if (type == Type::Int)
|
|
|
|
|
return "int";
|
|
|
|
|
else if (type == Type::Float)
|
|
|
|
|
return "float";
|
|
|
|
|
else if (type == Type::Vec2)
|
|
|
|
|
return "vec2";
|
|
|
|
|
else if (type == Type::Vec3)
|
|
|
|
|
return "vec3";
|
|
|
|
|
else if (type == Type::Vec4)
|
|
|
|
|
return "vec4";
|
|
|
|
|
else if (type == Type::Color)
|
|
|
|
|
return "color";
|
|
|
|
|
else if (type == Type::Sampler)
|
2023-08-30 13:43:24 +03:00
|
|
|
return "sampler2D";
|
2023-08-28 13:30:36 +03:00
|
|
|
else if (type == Type::Define)
|
|
|
|
|
return "define";
|
|
|
|
|
|
|
|
|
|
qWarning() << QString("Unknown type");
|
|
|
|
|
return "float";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Uniform::Type Uniform::typeFromString(const QString &typeString)
|
|
|
|
|
{
|
|
|
|
|
if (typeString == "bool")
|
|
|
|
|
return Uniform::Type::Bool;
|
|
|
|
|
else if (typeString == "int")
|
|
|
|
|
return Uniform::Type::Int;
|
|
|
|
|
else if (typeString == "float")
|
|
|
|
|
return Uniform::Type::Float;
|
|
|
|
|
else if (typeString == "vec2")
|
|
|
|
|
return Uniform::Type::Vec2;
|
|
|
|
|
else if (typeString == "vec3")
|
|
|
|
|
return Uniform::Type::Vec3;
|
|
|
|
|
else if (typeString == "vec4")
|
|
|
|
|
return Uniform::Type::Vec4;
|
|
|
|
|
else if (typeString == "color")
|
|
|
|
|
return Uniform::Type::Color;
|
2023-08-30 13:43:24 +03:00
|
|
|
else if (typeString == "sampler2D")
|
2023-08-28 13:30:36 +03:00
|
|
|
return Uniform::Type::Sampler;
|
|
|
|
|
else if (typeString == "define")
|
|
|
|
|
return Uniform::Type::Define;
|
|
|
|
|
|
|
|
|
|
qWarning() << QString("Unknown type: %1").arg(typeString).toLatin1();
|
|
|
|
|
return Uniform::Type::Float;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 11:27:00 +03:00
|
|
|
QString Uniform::typeToProperty(Uniform::Type type)
|
|
|
|
|
{
|
|
|
|
|
if (type == Uniform::Type::Bool)
|
|
|
|
|
return "bool";
|
|
|
|
|
else if (type == Uniform::Type::Int)
|
|
|
|
|
return "int";
|
|
|
|
|
else if (type == Uniform::Type::Float)
|
|
|
|
|
return "real";
|
|
|
|
|
else if (type == Uniform::Type::Vec2)
|
|
|
|
|
return "point";
|
|
|
|
|
else if (type == Uniform::Type::Vec3)
|
|
|
|
|
return "vector3d";
|
|
|
|
|
else if (type == Uniform::Type::Vec4)
|
|
|
|
|
return "vector4d";
|
|
|
|
|
else if (type == Uniform::Type::Color)
|
|
|
|
|
return "color";
|
|
|
|
|
else if (type == Uniform::Type::Sampler || type == Uniform::Type::Define)
|
|
|
|
|
return "var";
|
|
|
|
|
|
|
|
|
|
qWarning() << QString("Unhandled const variable type: %1").arg(int(type)).toLatin1();
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 15:36:15 +03:00
|
|
|
} // namespace EffectMaker
|