ShaderNodes: Add TextureEdit dialog

This commit is contained in:
Jérôme Leclercq 2020-07-04 22:52:17 +02:00
parent 33d94c05f3
commit 5164294bec
11 changed files with 200 additions and 17 deletions

View File

@ -13,11 +13,11 @@ TOOL.Includes = {
"../include", "../include",
"../extlibs/include", "../extlibs/include",
"../src", "../src",
[[E:\Qt\5.14.1\msvc2017_64\include]], [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include]],
[[E:\Qt\5.14.1\msvc2017_64\include\QtCore]], [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtCore]],
[[E:\Qt\5.14.1\msvc2017_64\include\QtGui]], [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtGui]],
[[E:\Qt\5.14.1\msvc2017_64\include\QtWidgets]], [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\include\QtWidgets]],
[[C:\Users\Lynix\Documents\GitHub\nodeeditor\include]], [[C:\Projets\Libs\nodeeditor\include]],
} }
TOOL.Files = { TOOL.Files = {
@ -37,6 +37,6 @@ TOOL.Libraries = {
} }
TOOL.LibraryPaths.x64 = { TOOL.LibraryPaths.x64 = {
[[E:\Qt\5.14.1\msvc2017_64\lib]], [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\lib]],
[[C:\Users\Lynix\Documents\GitHub\nodeeditor\build\lib\Debug]] [[C:\Projets\Libs\nodeeditor\build\lib\Debug]]
} }

View File

@ -9,19 +9,23 @@ TextureValue::TextureValue(ShaderGraph& graph) :
ShaderNode(graph) ShaderNode(graph)
{ {
m_onTextureListUpdateSlot.Connect(GetGraph().OnTextureListUpdate, [&](ShaderGraph*) { OnTextureListUpdate(); }); 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) if (m_currentTextureIndex == textureIndex)
{ {
UpdatePreview(); UpdatePreview();
Q_EMIT dataUpdated(0); Q_EMIT dataUpdated(0);
} }
}); };
m_onTexturePreviewUpdateSlot.Connect(GetGraph().OnTexturePreviewUpdate, HandleTextureUpdate);
m_onTextureUpdateSlot.Connect(GetGraph().OnTextureUpdate, HandleTextureUpdate);
if (graph.GetTextureCount() > 0) if (graph.GetTextureCount() > 0)
{ {
m_currentTextureIndex = 0; m_currentTextureIndex = 0;
UpdateOutputTexture(); UpdateTexture();
} }
DisableCustomVariableName(); DisableCustomVariableName();
@ -56,7 +60,7 @@ void TextureValue::OnTextureListUpdate()
} }
} }
void TextureValue::UpdateOutputTexture() void TextureValue::UpdateTexture()
{ {
if (m_currentTextureIndex) if (m_currentTextureIndex)
{ {
@ -97,7 +101,7 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout)
else else
m_currentTextureIndex.reset(); m_currentTextureIndex.reset();
UpdateOutputTexture(); UpdateTexture();
UpdatePreview(); UpdatePreview();
Q_EMIT dataUpdated(0); Q_EMIT dataUpdated(0);

View File

@ -35,13 +35,14 @@ class TextureValue : public ShaderNode
protected: protected:
bool ComputePreview(QPixmap& pixmap) override; bool ComputePreview(QPixmap& pixmap) override;
void OnTextureListUpdate(); void OnTextureListUpdate();
void UpdateOutputTexture(); void UpdateTexture();
void restore(const QJsonObject& data) override; void restore(const QJsonObject& data) override;
QJsonObject save() const override; QJsonObject save() const override;
NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot); NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot);
NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot); NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot);
NazaraSlot(ShaderGraph, OnTextureUpdate, m_onTextureUpdateSlot);
std::optional<std::size_t> m_currentTextureIndex; std::optional<std::size_t> m_currentTextureIndex;
std::string m_currentTextureText; std::string m_currentTextureText;

View File

@ -11,12 +11,15 @@ PreviewValues QuadPreview::GetPreview(InputRole role, std::size_t roleIndex) con
return dummy; 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) for (std::size_t x = 0; x < uv.GetWidth(); ++x)
uv(x, y) = Nz::Vector4f(x / 128.f, y / 128.f, 0.f, 1.f); uv(x, y) = Nz::Vector4f(x * invWidth, y * invHeight, 0.f, 1.f);
} }
return uv; return uv;

View File

@ -390,6 +390,17 @@ void ShaderGraph::UpdateOutput(std::size_t outputIndex, std::string name, InOutT
OnOutputUpdate(this, outputIndex); 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) void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview)
{ {
assert(textureIndex < m_textures.size()); assert(textureIndex < m_textures.size());

View File

@ -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 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 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); void UpdateTexturePreview(std::size_t texture, QImage preview);
struct InputEntry struct InputEntry
@ -81,6 +82,7 @@ class ShaderGraph
NazaraSignal(OnSelectedNodeUpdate, ShaderGraph*, ShaderNode* /*node*/); NazaraSignal(OnSelectedNodeUpdate, ShaderGraph*, ShaderNode* /*node*/);
NazaraSignal(OnTextureListUpdate, ShaderGraph*); NazaraSignal(OnTextureListUpdate, ShaderGraph*);
NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/); NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/);
NazaraSignal(OnTextureUpdate, ShaderGraph*, std::size_t /*textureIndex*/);
private: private:
std::shared_ptr<QtNodes::DataModelRegistry> BuildRegistry(); std::shared_ptr<QtNodes::DataModelRegistry> BuildRegistry();

View File

@ -0,0 +1,73 @@
#include <ShaderNode/Widgets/TextureEditDialog.hpp>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QVBoxLayout>
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<TextureType>(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<std::size_t>(m_bindingIndex->value());
inputInfo.name = m_textureName->text().toStdString();
inputInfo.type = static_cast<TextureType>(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();
}

View File

@ -0,0 +1,39 @@
#pragma once
#ifndef NAZARA_SHADERNODES_TEXTUREEDITDIALOG_HPP
#define NAZARA_SHADERNODES_TEXTUREEDITDIALOG_HPP
#include <ShaderNode/Enums.hpp>
#include <QtWidgets/QDialog>
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 <ShaderNode/Widgets/TextureEditDialog.inl>
#endif

View File

@ -0,0 +1 @@
#include <ShaderNode/Widgets/TextureEditDialog.hpp>

View File

@ -1,4 +1,5 @@
#include <ShaderNode/Widgets/TextureEditor.hpp> #include <ShaderNode/Widgets/TextureEditor.hpp>
#include <ShaderNode/Widgets/TextureEditDialog.hpp>
#include <ShaderNode/ShaderGraph.hpp> #include <ShaderNode/ShaderGraph.hpp>
#include <QtWidgets/QFileDialog> #include <QtWidgets/QFileDialog>
#include <QtWidgets/QLabel> #include <QtWidgets/QLabel>
@ -11,6 +12,10 @@ m_shaderGraph(graph)
{ {
m_textureList = new QListWidget; m_textureList = new QListWidget;
connect(m_textureList, &QListWidget::currentRowChanged, this, &TextureEditor::OnTextureSelectionUpdate); 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; m_pixmapLabel = new QLabel;
@ -26,10 +31,44 @@ m_shaderGraph(graph)
m_onTextureListUpdateSlot.Connect(m_shaderGraph.OnTextureListUpdate, this, &TextureEditor::OnTextureListUpdate); m_onTextureListUpdateSlot.Connect(m_shaderGraph.OnTextureListUpdate, this, &TextureEditor::OnTextureListUpdate);
m_onTexturePreviewUpdateSlot.Connect(m_shaderGraph.OnTexturePreviewUpdate, this, &TextureEditor::OnTexturePreviewUpdate); m_onTexturePreviewUpdateSlot.Connect(m_shaderGraph.OnTexturePreviewUpdate, this, &TextureEditor::OnTexturePreviewUpdate);
m_onTextureUpdateSlot.Connect(m_shaderGraph.OnTextureUpdate, this, &TextureEditor::OnTextureUpdate);
RefreshTextures(); 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() void TextureEditor::OnLoadTexture()
{ {
if (!m_currentTextureIndex) if (!m_currentTextureIndex)
@ -64,6 +103,12 @@ void TextureEditor::OnTexturePreviewUpdate(ShaderGraph* /*graph*/, std::size_t t
UpdateTexturePreview(); 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() void TextureEditor::RefreshTextures()
{ {
m_textureList->clear(); m_textureList->clear();

View File

@ -18,15 +18,19 @@ class TextureEditor : public QWidget
~TextureEditor() = default; ~TextureEditor() = default;
private: private:
void OnAddTexture();
void OnEditTexture(int inputIndex);
void OnLoadTexture(); void OnLoadTexture();
void OnTextureSelectionUpdate(int textureIndex); void OnTextureSelectionUpdate(int textureIndex);
void OnTextureListUpdate(ShaderGraph* graph); void OnTextureListUpdate(ShaderGraph* graph);
void OnTexturePreviewUpdate(ShaderGraph* graph, std::size_t textureIndex); void OnTexturePreviewUpdate(ShaderGraph* graph, std::size_t textureIndex);
void OnTextureUpdate(ShaderGraph* graph, std::size_t textureIndex);
void RefreshTextures(); void RefreshTextures();
void UpdateTexturePreview(); void UpdateTexturePreview();
NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot); NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot);
NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot); NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot);
NazaraSlot(ShaderGraph, OnTextureUpdate, m_onTextureUpdateSlot);
std::optional<std::size_t> m_currentTextureIndex; std::optional<std::size_t> m_currentTextureIndex;
ShaderGraph& m_shaderGraph; ShaderGraph& m_shaderGraph;