diff --git a/src/ShaderNode/DataModels/Cast.hpp b/src/ShaderNode/DataModels/Cast.hpp index 90dad931e..bb287555c 100644 --- a/src/ShaderNode/DataModels/Cast.hpp +++ b/src/ShaderNode/DataModels/Cast.hpp @@ -38,6 +38,9 @@ class CastVec : public ShaderNode bool ComputePreview(QPixmap& pixmap) override; void UpdateOutput(); + void restore(const QJsonObject& data) override; + QJsonObject save() const override; + std::shared_ptr m_input; std::shared_ptr m_output; VecType m_overflowComponents; diff --git a/src/ShaderNode/DataModels/Cast.inl b/src/ShaderNode/DataModels/Cast.inl index f8870201a..1a304c2c7 100644 --- a/src/ShaderNode/DataModels/Cast.inl +++ b/src/ShaderNode/DataModels/Cast.inl @@ -34,6 +34,7 @@ void CastVec::BuildNodeEdition(QFormLayout* layout) { QDoubleSpinBox* spinbox = new QDoubleSpinBox; spinbox->setDecimals(6); + spinbox->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); spinbox->setValue(m_overflowComponents[i]); connect(spinbox, qOverload(&QDoubleSpinBox::valueChanged), [=](double) @@ -66,7 +67,7 @@ Nz::ShaderAst::ExpressionPtr CastVec::GetExpression(Nz::Shader constexpr auto ExpressionType = VecExpressionType; - return Nz::ShaderBuilder::Cast(expr.data(), overflowComponentCount); + return Nz::ShaderBuilder::Cast(expr.data(), 1 + overflowComponentCount); } else if (ToComponentCount < fromComponentCount) { @@ -232,3 +233,29 @@ void CastVec::UpdateOutput() UpdatePreview(); } + +template +void CastVec::restore(const QJsonObject& data) +{ + QJsonArray vecValues = data["value"].toArray(); + std::size_t commonValues = std::min(static_cast(vecValues.size()), ToComponentCount); + + for (std::size_t i = 0; i < commonValues; ++i) + m_overflowComponents[i] = float(vecValues[int(i)].toDouble(m_overflowComponents[i])); + + ShaderNode::restore(data); +} + +template +QJsonObject CastVec::save() const +{ + QJsonObject data = ShaderNode::save(); + + QJsonArray vecValues; + for (std::size_t i = 0; i < ToComponentCount; ++i) + vecValues.push_back(m_overflowComponents[i]); + + data["value"] = vecValues; + + return data; +} diff --git a/src/ShaderNode/DataModels/FloatValue.cpp b/src/ShaderNode/DataModels/FloatValue.cpp index 23d5a30d3..3da83982e 100644 --- a/src/ShaderNode/DataModels/FloatValue.cpp +++ b/src/ShaderNode/DataModels/FloatValue.cpp @@ -57,6 +57,7 @@ void FloatValue::BuildNodeEdition(QFormLayout* layout) QDoubleSpinBox* spinbox = new QDoubleSpinBox; spinbox->setDecimals(6); + spinbox->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); spinbox->setValue(m_value); connect(spinbox, qOverload(&QDoubleSpinBox::valueChanged), [=](double) diff --git a/src/ShaderNode/DataModels/InputValue.cpp b/src/ShaderNode/DataModels/InputValue.cpp index 3f8d2fbdc..92d08ba3e 100644 --- a/src/ShaderNode/DataModels/InputValue.cpp +++ b/src/ShaderNode/DataModels/InputValue.cpp @@ -20,9 +20,8 @@ ShaderNode(graph) if (graph.GetInputCount() > 0) { - auto& firstInput = graph.GetInput(0); m_currentInputIndex = 0; - m_currentInputText = firstInput.name; + UpdateInputText(); } DisableCustomVariableName(); @@ -70,11 +69,27 @@ void InputValue::OnInputListUpdate() } } +void InputValue::UpdateInputText() +{ + if (m_currentInputIndex) + { + auto& input = GetGraph().GetInput(*m_currentInputIndex); + m_currentInputText = input.name; + } + else + m_currentInputText.clear(); +} + void InputValue::BuildNodeEdition(QFormLayout* layout) { ShaderNode::BuildNodeEdition(layout); QComboBox* inputSelection = new QComboBox; + for (const auto& inputEntry : GetGraph().GetInputs()) + inputSelection->addItem(QString::fromStdString(inputEntry.name)); + + if (m_currentInputIndex) + inputSelection->setCurrentIndex(int(*m_currentInputIndex)); connect(inputSelection, qOverload(&QComboBox::currentIndexChanged), [&](int index) { @@ -83,11 +98,11 @@ void InputValue::BuildNodeEdition(QFormLayout* layout) else m_currentInputIndex.reset(); + UpdateInputText(); UpdatePreview(); - }); - for (const auto& inputEntry : GetGraph().GetInputs()) - inputSelection->addItem(QString::fromStdString(inputEntry.name)); + Q_EMIT dataUpdated(0); + }); layout->addRow(tr("Input"), inputSelection); } diff --git a/src/ShaderNode/DataModels/InputValue.hpp b/src/ShaderNode/DataModels/InputValue.hpp index 681a85e8d..a5eaabf01 100644 --- a/src/ShaderNode/DataModels/InputValue.hpp +++ b/src/ShaderNode/DataModels/InputValue.hpp @@ -36,6 +36,7 @@ class InputValue : public ShaderNode private: bool ComputePreview(QPixmap& pixmap) override; void OnInputListUpdate(); + void UpdateInputText(); void restore(const QJsonObject& data) override; QJsonObject save() const override; diff --git a/src/ShaderNode/DataModels/OutputValue.cpp b/src/ShaderNode/DataModels/OutputValue.cpp index 538884706..09d7aff78 100644 --- a/src/ShaderNode/DataModels/OutputValue.cpp +++ b/src/ShaderNode/DataModels/OutputValue.cpp @@ -17,9 +17,8 @@ ShaderNode(graph) if (graph.GetOutputCount() > 0) { - auto& firstOutput = graph.GetOutput(0); m_currentOutputIndex = 0; - m_currentOutputText = firstOutput.name; + UpdateOutputText(); } EnablePreview(); @@ -32,7 +31,12 @@ void OutputValue::BuildNodeEdition(QFormLayout* layout) ShaderNode::BuildNodeEdition(layout); QComboBox* outputSelection = new QComboBox; + for (const auto& outputEntry : GetGraph().GetOutputs()) + outputSelection->addItem(QString::fromStdString(outputEntry.name)); + if (m_currentOutputIndex) + outputSelection->setCurrentIndex(int(*m_currentOutputIndex)); + connect(outputSelection, qOverload(&QComboBox::currentIndexChanged), [&](int index) { if (index >= 0) @@ -40,12 +44,10 @@ void OutputValue::BuildNodeEdition(QFormLayout* layout) else m_currentOutputIndex.reset(); + UpdateOutputText(); UpdatePreview(); }); - for (const auto& outputEntry : GetGraph().GetOutputs()) - outputSelection->addItem(QString::fromStdString(outputEntry.name)); - layout->addRow(tr("Output"), outputSelection); } @@ -189,9 +191,20 @@ void OutputValue::OnOutputListUpdate() } } +void OutputValue::UpdateOutputText() +{ + if (m_currentOutputIndex) + { + auto& output = GetGraph().GetOutput(*m_currentOutputIndex); + m_currentOutputText = output.name; + } + else + m_currentOutputText.clear(); +} + void OutputValue::restore(const QJsonObject& data) { - m_currentOutputText = data["input"].toString().toStdString(); + m_currentOutputText = data["output"].toString().toStdString(); OnOutputListUpdate(); ShaderNode::restore(data); @@ -200,7 +213,7 @@ void OutputValue::restore(const QJsonObject& data) QJsonObject OutputValue::save() const { QJsonObject data = ShaderNode::save(); - data["input"] = QString::fromStdString(m_currentOutputText); + data["output"] = QString::fromStdString(m_currentOutputText); return data; } diff --git a/src/ShaderNode/DataModels/OutputValue.hpp b/src/ShaderNode/DataModels/OutputValue.hpp index 4cc523b66..320b2bacb 100644 --- a/src/ShaderNode/DataModels/OutputValue.hpp +++ b/src/ShaderNode/DataModels/OutputValue.hpp @@ -35,6 +35,7 @@ class OutputValue : public ShaderNode private: bool ComputePreview(QPixmap& pixmap) override; void OnOutputListUpdate(); + void UpdateOutputText(); void restore(const QJsonObject& data) override; QJsonObject save() const override; diff --git a/src/ShaderNode/DataModels/TextureValue.cpp b/src/ShaderNode/DataModels/TextureValue.cpp index 78f7df761..d543a502e 100644 --- a/src/ShaderNode/DataModels/TextureValue.cpp +++ b/src/ShaderNode/DataModels/TextureValue.cpp @@ -20,9 +20,8 @@ ShaderNode(graph) if (graph.GetTextureCount() > 0) { - auto& firstInput = graph.GetTexture(0); m_currentTextureIndex = 0; - m_currentTextureText = firstInput.name; + UpdateOutputTexture(); } DisableCustomVariableName(); @@ -57,6 +56,17 @@ void TextureValue::OnTextureListUpdate() } } +void TextureValue::UpdateOutputTexture() +{ + if (m_currentTextureIndex) + { + auto& texture = GetGraph().GetTexture(*m_currentTextureIndex); + m_currentTextureText = texture.name; + } + else + m_currentTextureText.clear(); +} + bool TextureValue::ComputePreview(QPixmap& pixmap) { if (!m_currentTextureIndex) @@ -74,6 +84,12 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout) ShaderNode::BuildNodeEdition(layout); QComboBox* textureSelection = new QComboBox; + for (const auto& textureEntry : GetGraph().GetTextures()) + textureSelection->addItem(QString::fromStdString(textureEntry.name)); + + if (m_currentTextureIndex) + textureSelection->setCurrentIndex(int(*m_currentTextureIndex)); + connect(textureSelection, qOverload(&QComboBox::currentIndexChanged), [&](int index) { if (index >= 0) @@ -81,14 +97,12 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout) else m_currentTextureIndex.reset(); + UpdateOutputTexture(); UpdatePreview(); Q_EMIT dataUpdated(0); }); - for (const auto& textureEntry : GetGraph().GetTextures()) - textureSelection->addItem(QString::fromStdString(textureEntry.name)); - layout->addRow(tr("Texture"), textureSelection); } @@ -120,7 +134,7 @@ auto TextureValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portI assert(portType == QtNodes::PortType::Out); assert(portIndex == 0); - return VecData::Type(); + return Texture2Data::Type(); } std::shared_ptr TextureValue::outData(QtNodes::PortIndex port) diff --git a/src/ShaderNode/DataModels/TextureValue.hpp b/src/ShaderNode/DataModels/TextureValue.hpp index 4b46be4d6..89cfcff21 100644 --- a/src/ShaderNode/DataModels/TextureValue.hpp +++ b/src/ShaderNode/DataModels/TextureValue.hpp @@ -35,6 +35,7 @@ class TextureValue : public ShaderNode protected: bool ComputePreview(QPixmap& pixmap) override; void OnTextureListUpdate(); + void UpdateOutputTexture(); void restore(const QJsonObject& data) override; QJsonObject save() const override; diff --git a/src/ShaderNode/DataModels/VecValue.inl b/src/ShaderNode/DataModels/VecValue.inl index a35a95686..a3ea2068e 100644 --- a/src/ShaderNode/DataModels/VecValue.inl +++ b/src/ShaderNode/DataModels/VecValue.inl @@ -78,6 +78,7 @@ void VecValue::BuildNodeEdition(QFormLayout* layout) { QDoubleSpinBox* spinbox = new QDoubleSpinBox; spinbox->setDecimals(6); + spinbox->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); spinbox->setValue(m_value[i]); connect(spinbox, qOverload(&QDoubleSpinBox::valueChanged), [=](double) @@ -122,8 +123,10 @@ template void VecValue::restore(const QJsonObject& data) { QJsonArray vecValues = data["value"].toArray(); - for (std::size_t i = 0; i < ComponentCount; ++i) - m_value[i] = vecValues[int(i)].toInt(m_value[i]); + std::size_t commonValues = std::min(static_cast(vecValues.size()), ComponentCount); + + for (std::size_t i = 0; i < commonValues; ++i) + m_value[i] = float(vecValues[int(i)].toDouble(m_value[i])); ShaderNode::restore(data); } diff --git a/src/ShaderNode/Previews/QuadPreview.cpp b/src/ShaderNode/Previews/QuadPreview.cpp index 55ae86a52..ef064417d 100644 --- a/src/ShaderNode/Previews/QuadPreview.cpp +++ b/src/ShaderNode/Previews/QuadPreview.cpp @@ -3,8 +3,12 @@ QImage QuadPreview::GetImage(InputRole role, std::size_t roleIndex) const { - assert(role == InputRole::TexCoord); - assert(roleIndex == 0); + if (role != InputRole::TexCoord) + { + QImage dummy(1, 1, QImage::Format_RGBA8888); + dummy.fill(QColor::fromRgb(0, 0, 0, 0)); + return dummy; + } QImage uv(128, 128, QImage::Format_RGBA8888);