diff --git a/build/scripts/tools/shadernodes.lua b/build/scripts/tools/shadernodes.lua index 415b71c75..3abeaa658 100644 --- a/build/scripts/tools/shadernodes.lua +++ b/build/scripts/tools/shadernodes.lua @@ -13,11 +13,11 @@ TOOL.Includes = { "../include", "../extlibs/include", "../src", - [[E:\Qt\5.14.1\msvc2017_64\include]], - [[E:\Qt\5.14.1\msvc2017_64\include\QtCore]], - [[E:\Qt\5.14.1\msvc2017_64\include\QtGui]], - [[E:\Qt\5.14.1\msvc2017_64\include\QtWidgets]], - [[C:\Users\Lynix\Documents\GitHub\nodeeditor\include]], + [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include]], + [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtCore]], + [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtGui]], + [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtWidgets]], + [[C:\Projets\Libs\nodeeditor\include]], } TOOL.Files = { @@ -37,6 +37,6 @@ TOOL.Libraries = { } TOOL.LibraryPaths.x64 = { - [[E:\Qt\5.14.1\msvc2017_64\lib]], - [[C:\Users\Lynix\Documents\GitHub\nodeeditor\build\lib\Debug]] + [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\lib]], + [[C:\Projets\Libs\nodeeditor\build\lib\Debug]] } diff --git a/src/ShaderNode/DataModels/TextureValue.cpp b/src/ShaderNode/DataModels/TextureValue.cpp index d0237e8bd..6a6402cf4 100644 --- a/src/ShaderNode/DataModels/TextureValue.cpp +++ b/src/ShaderNode/DataModels/TextureValue.cpp @@ -9,19 +9,23 @@ TextureValue::TextureValue(ShaderGraph& graph) : ShaderNode(graph) { m_onTextureListUpdateSlot.Connect(GetGraph().OnTextureListUpdate, [&](ShaderGraph*) { OnTextureListUpdate(); }); - m_onTexturePreviewUpdateSlot.Connect(GetGraph().OnTexturePreviewUpdate, [&](ShaderGraph*, std::size_t textureIndex) + + auto HandleTextureUpdate = [&](ShaderGraph*, std::size_t textureIndex) { if (m_currentTextureIndex == textureIndex) { UpdatePreview(); Q_EMIT dataUpdated(0); } - }); + }; + + m_onTexturePreviewUpdateSlot.Connect(GetGraph().OnTexturePreviewUpdate, HandleTextureUpdate); + m_onTextureUpdateSlot.Connect(GetGraph().OnTextureUpdate, HandleTextureUpdate); if (graph.GetTextureCount() > 0) { m_currentTextureIndex = 0; - UpdateOutputTexture(); + UpdateTexture(); } DisableCustomVariableName(); @@ -56,7 +60,7 @@ void TextureValue::OnTextureListUpdate() } } -void TextureValue::UpdateOutputTexture() +void TextureValue::UpdateTexture() { if (m_currentTextureIndex) { @@ -97,7 +101,7 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout) else m_currentTextureIndex.reset(); - UpdateOutputTexture(); + UpdateTexture(); UpdatePreview(); Q_EMIT dataUpdated(0); diff --git a/src/ShaderNode/DataModels/TextureValue.hpp b/src/ShaderNode/DataModels/TextureValue.hpp index dfb7efaff..d328e2f05 100644 --- a/src/ShaderNode/DataModels/TextureValue.hpp +++ b/src/ShaderNode/DataModels/TextureValue.hpp @@ -35,13 +35,14 @@ class TextureValue : public ShaderNode protected: bool ComputePreview(QPixmap& pixmap) override; void OnTextureListUpdate(); - void UpdateOutputTexture(); + void UpdateTexture(); void restore(const QJsonObject& data) override; QJsonObject save() const override; NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot); NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot); + NazaraSlot(ShaderGraph, OnTextureUpdate, m_onTextureUpdateSlot); std::optional m_currentTextureIndex; std::string m_currentTextureText; diff --git a/src/ShaderNode/Previews/QuadPreview.cpp b/src/ShaderNode/Previews/QuadPreview.cpp index a4edc9267..ce6155903 100644 --- a/src/ShaderNode/Previews/QuadPreview.cpp +++ b/src/ShaderNode/Previews/QuadPreview.cpp @@ -11,12 +11,15 @@ PreviewValues QuadPreview::GetPreview(InputRole role, std::size_t roleIndex) con return dummy; } - PreviewValues uv(128, 128); + PreviewValues uv(128, 128); - for (std::size_t y = 0; y < 128; ++y) + float invWidth = 1.f / uv.GetWidth(); + float invHeight = 1.f / uv.GetHeight(); + + for (std::size_t y = 0; y < uv.GetHeight(); ++y) { - for (std::size_t x = 0; x < 128; ++x) - uv(x, y) = Nz::Vector4f(x / 128.f, y / 128.f, 0.f, 1.f); + for (std::size_t x = 0; x < uv.GetWidth(); ++x) + uv(x, y) = Nz::Vector4f(x * invWidth, y * invHeight, 0.f, 1.f); } return uv; diff --git a/src/ShaderNode/ShaderGraph.cpp b/src/ShaderNode/ShaderGraph.cpp index 880afb2a9..5788e1f8b 100644 --- a/src/ShaderNode/ShaderGraph.cpp +++ b/src/ShaderNode/ShaderGraph.cpp @@ -390,6 +390,17 @@ void ShaderGraph::UpdateOutput(std::size_t outputIndex, std::string name, InOutT OnOutputUpdate(this, outputIndex); } +void ShaderGraph::UpdateTexture(std::size_t textureIndex, std::string name, TextureType type, std::size_t bindingIndex) +{ + assert(textureIndex < m_textures.size()); + auto& textureEntry = m_textures[textureIndex]; + textureEntry.bindingIndex = bindingIndex; + textureEntry.name = std::move(name); + textureEntry.type = type; + + OnTextureUpdate(this, textureIndex); +} + void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview) { assert(textureIndex < m_textures.size()); diff --git a/src/ShaderNode/ShaderGraph.hpp b/src/ShaderNode/ShaderGraph.hpp index add7e52ab..b65694f65 100644 --- a/src/ShaderNode/ShaderGraph.hpp +++ b/src/ShaderNode/ShaderGraph.hpp @@ -48,6 +48,7 @@ class ShaderGraph void UpdateInput(std::size_t inputIndex, std::string name, InOutType type, InputRole role, std::size_t roleIndex, std::size_t locationIndex); void UpdateOutput(std::size_t outputIndex, std::string name, InOutType type, std::size_t locationIndex); + void UpdateTexture(std::size_t textureIndex, std::string name, TextureType type, std::size_t bindingIndex); void UpdateTexturePreview(std::size_t texture, QImage preview); struct InputEntry @@ -81,6 +82,7 @@ class ShaderGraph NazaraSignal(OnSelectedNodeUpdate, ShaderGraph*, ShaderNode* /*node*/); NazaraSignal(OnTextureListUpdate, ShaderGraph*); NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/); + NazaraSignal(OnTextureUpdate, ShaderGraph*, std::size_t /*textureIndex*/); private: std::shared_ptr BuildRegistry(); diff --git a/src/ShaderNode/Widgets/TextureEditDialog.cpp b/src/ShaderNode/Widgets/TextureEditDialog.cpp new file mode 100644 index 000000000..f16530e1f --- /dev/null +++ b/src/ShaderNode/Widgets/TextureEditDialog.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +TextureEditDialog::TextureEditDialog(QWidget* parent) : +QDialog(parent) +{ + setWindowTitle(tr("Texture edit dialog")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + m_textureName = new QLineEdit; + + m_typeList = new QComboBox; + for (std::size_t i = 0; i < TextureTypeCount; ++i) + m_typeList->addItem(EnumToString(static_cast(i))); + + m_bindingIndex = new QSpinBox; + + QFormLayout* formLayout = new QFormLayout; + formLayout->addRow(tr("Name"), m_textureName); + formLayout->addRow(tr("Type"), m_typeList); + formLayout->addRow(tr("Binding index"), m_bindingIndex); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, &QDialogButtonBox::accepted, this, &TextureEditDialog::OnAccept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + QVBoxLayout* verticalLayout = new QVBoxLayout; + verticalLayout->addLayout(formLayout); + verticalLayout->addWidget(buttonBox); + + setLayout(verticalLayout); +} + +TextureEditDialog::TextureEditDialog(const TextureInfo& texture, QWidget* parent) : +TextureEditDialog(parent) +{ + m_bindingIndex->setValue(int(texture.bindingIndex)); + m_textureName->setText(QString::fromStdString(texture.name)); + m_typeList->setCurrentText(EnumToString(texture.type)); +} + +TextureInfo TextureEditDialog::GetTextureInfo() const +{ + TextureInfo inputInfo; + inputInfo.bindingIndex = static_cast(m_bindingIndex->value()); + inputInfo.name = m_textureName->text().toStdString(); + inputInfo.type = static_cast(m_typeList->currentIndex()); + + return inputInfo; +} + +void TextureEditDialog::OnAccept() +{ + if (m_textureName->text().isEmpty()) + { + QMessageBox::critical(this, tr("Empty name"), tr("Texture name must be set"), QMessageBox::Ok); + return; + } + + if (m_typeList->currentIndex() < 0) + { + QMessageBox::critical(this, tr("Invalid type"), tr("You must select a type"), QMessageBox::Ok); + return; + } + + accept(); +} diff --git a/src/ShaderNode/Widgets/TextureEditDialog.hpp b/src/ShaderNode/Widgets/TextureEditDialog.hpp new file mode 100644 index 000000000..ea402f31d --- /dev/null +++ b/src/ShaderNode/Widgets/TextureEditDialog.hpp @@ -0,0 +1,39 @@ +#pragma once + +#ifndef NAZARA_SHADERNODES_TEXTUREEDITDIALOG_HPP +#define NAZARA_SHADERNODES_TEXTUREEDITDIALOG_HPP + +#include +#include + +class QComboBox; +class QLineEdit; +class QSpinBox; + +struct TextureInfo +{ + std::size_t bindingIndex; + std::string name; + TextureType type; +}; + +class TextureEditDialog : public QDialog +{ + public: + TextureEditDialog(QWidget* parent = nullptr); + TextureEditDialog(const TextureInfo& Texture, QWidget* parent = nullptr); + ~TextureEditDialog() = default; + + TextureInfo GetTextureInfo() const; + + private: + void OnAccept(); + + QComboBox* m_typeList; + QLineEdit* m_textureName; + QSpinBox* m_bindingIndex; +}; + +#include + +#endif diff --git a/src/ShaderNode/Widgets/TextureEditDialog.inl b/src/ShaderNode/Widgets/TextureEditDialog.inl new file mode 100644 index 000000000..c15d4e41c --- /dev/null +++ b/src/ShaderNode/Widgets/TextureEditDialog.inl @@ -0,0 +1 @@ +#include diff --git a/src/ShaderNode/Widgets/TextureEditor.cpp b/src/ShaderNode/Widgets/TextureEditor.cpp index 40cce4652..99b40316a 100644 --- a/src/ShaderNode/Widgets/TextureEditor.cpp +++ b/src/ShaderNode/Widgets/TextureEditor.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -11,6 +12,10 @@ m_shaderGraph(graph) { m_textureList = new QListWidget; connect(m_textureList, &QListWidget::currentRowChanged, this, &TextureEditor::OnTextureSelectionUpdate); + connect(m_textureList, &QListWidget::itemDoubleClicked, [this](QListWidgetItem* item) + { + OnEditTexture(m_textureList->row(item)); + }); m_pixmapLabel = new QLabel; @@ -26,10 +31,44 @@ m_shaderGraph(graph) m_onTextureListUpdateSlot.Connect(m_shaderGraph.OnTextureListUpdate, this, &TextureEditor::OnTextureListUpdate); m_onTexturePreviewUpdateSlot.Connect(m_shaderGraph.OnTexturePreviewUpdate, this, &TextureEditor::OnTexturePreviewUpdate); + m_onTextureUpdateSlot.Connect(m_shaderGraph.OnTextureUpdate, this, &TextureEditor::OnTextureUpdate); RefreshTextures(); } +void TextureEditor::OnAddTexture() +{ + TextureEditDialog* dialog = new TextureEditDialog(this); + dialog->setAttribute(Qt::WA_DeleteOnClose, true); + connect(dialog, &QDialog::accepted, [this, dialog] + { + TextureInfo outputInfo = dialog->GetTextureInfo(); + m_shaderGraph.AddTexture(std::move(outputInfo.name), outputInfo.type, outputInfo.bindingIndex); + }); + + dialog->open(); +} + +void TextureEditor::OnEditTexture(int inputIndex) +{ + const auto& output = m_shaderGraph.GetTexture(inputIndex); + + TextureInfo info; + info.bindingIndex = output.bindingIndex; + info.name = output.name; + info.type = output.type; + + TextureEditDialog* dialog = new TextureEditDialog(std::move(info), this); + dialog->setAttribute(Qt::WA_DeleteOnClose, true); + connect(dialog, &QDialog::accepted, [this, dialog, inputIndex] + { + TextureInfo textureInfo = dialog->GetTextureInfo(); + m_shaderGraph.UpdateTexture(inputIndex, std::move(textureInfo.name), textureInfo.type, textureInfo.bindingIndex); + }); + + dialog->open(); +} + void TextureEditor::OnLoadTexture() { if (!m_currentTextureIndex) @@ -64,6 +103,12 @@ void TextureEditor::OnTexturePreviewUpdate(ShaderGraph* /*graph*/, std::size_t t UpdateTexturePreview(); } +void TextureEditor::OnTextureUpdate(ShaderGraph* /*graph*/, std::size_t inputIndex) +{ + const auto& inputEntry = m_shaderGraph.GetTexture(inputIndex); + m_textureList->item(int(inputIndex))->setText(QString::fromStdString(inputEntry.name)); +} + void TextureEditor::RefreshTextures() { m_textureList->clear(); diff --git a/src/ShaderNode/Widgets/TextureEditor.hpp b/src/ShaderNode/Widgets/TextureEditor.hpp index a3497f288..1c006e0ab 100644 --- a/src/ShaderNode/Widgets/TextureEditor.hpp +++ b/src/ShaderNode/Widgets/TextureEditor.hpp @@ -18,15 +18,19 @@ class TextureEditor : public QWidget ~TextureEditor() = default; private: + void OnAddTexture(); + void OnEditTexture(int inputIndex); void OnLoadTexture(); void OnTextureSelectionUpdate(int textureIndex); void OnTextureListUpdate(ShaderGraph* graph); void OnTexturePreviewUpdate(ShaderGraph* graph, std::size_t textureIndex); + void OnTextureUpdate(ShaderGraph* graph, std::size_t textureIndex); void RefreshTextures(); void UpdateTexturePreview(); NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot); NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot); + NazaraSlot(ShaderGraph, OnTextureUpdate, m_onTextureUpdateSlot); std::optional m_currentTextureIndex; ShaderGraph& m_shaderGraph;