ShaderNode: Add inputs

This commit is contained in:
Lynix 2020-05-22 23:50:46 +02:00
parent 5169e0fe83
commit 206724c911
20 changed files with 620 additions and 12 deletions

View File

@ -0,0 +1,132 @@
#include <ShaderGraph.hpp>
#include <DataModels/InputValue.hpp>
#include <DataModels/VecValue.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
InputValue::InputValue(ShaderGraph& graph) :
ShaderNode(graph),
m_currentInputIndex(0)
{
m_layout = new QVBoxLayout;
m_inputSelection = new QComboBox;
m_inputSelection->setStyleSheet("background-color: rgba(255,255,255,255)");
connect(m_inputSelection, qOverload<int>(&QComboBox::currentIndexChanged), [&](int index)
{
if (index < 0)
return;
m_currentInputIndex = static_cast<std::size_t>(index);
UpdatePreview();
});
m_layout->addWidget(m_inputSelection);
m_previewLabel = new QLabel;
m_layout->addWidget(m_previewLabel);
m_widget = new QWidget;
m_widget->setStyleSheet("background-color: rgba(0,0,0,0)");
m_widget->setLayout(m_layout);
m_onInputListUpdateSlot.Connect(GetGraph().OnInputListUpdate, [&](ShaderGraph*) { UpdateInputList(); });
m_onInputUpdateSlot.Connect(GetGraph().OnInputUpdate, [&](ShaderGraph*, std::size_t inputIndex)
{
if (m_currentInputIndex == inputIndex)
UpdatePreview();
});
UpdateInputList();
UpdatePreview();
}
QWidget* InputValue::embeddedWidget()
{
return m_widget;
}
unsigned int InputValue::nPorts(QtNodes::PortType portType) const
{
switch (portType)
{
case QtNodes::PortType::In: return 0;
case QtNodes::PortType::Out: return 1;
}
return 0;
}
void InputValue::UpdatePreview()
{
if (m_inputSelection->count() == 0)
return;
Q_EMIT dataUpdated(0);
}
void InputValue::UpdateInputList()
{
QString currentInput = m_inputSelection->currentText();
m_inputSelection->clear();
for (const auto& inputEntry : GetGraph().GetInputs())
m_inputSelection->addItem(QString::fromStdString(inputEntry.name));
m_inputSelection->setCurrentText(currentInput);
}
Nz::ShaderAst::ExpressionPtr InputValue::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
{
assert(count == 0);
const auto& inputEntry = GetGraph().GetInput(m_currentInputIndex);
Nz::ShaderAst::ExpressionType expression = [&]
{
switch (inputEntry.type)
{
case InputType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
case InputType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
case InputType::Float2: return Nz::ShaderAst::ExpressionType::Float2;
case InputType::Float3: return Nz::ShaderAst::ExpressionType::Float3;
case InputType::Float4: return Nz::ShaderAst::ExpressionType::Float4;
}
assert(false);
throw std::runtime_error("Unhandled input type");
}();
return Nz::ShaderBuilder::Input(inputEntry.name, expression);
}
auto InputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType
{
assert(portType == QtNodes::PortType::Out);
assert(portIndex == 0);
const auto& inputEntry = GetGraph().GetInput(m_currentInputIndex);
switch (inputEntry.type)
{
//case InputType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
//case InputType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
case InputType::Float2: return Vec2Data::Type();
//case InputType::Float3: return Nz::ShaderAst::ExpressionType::Float3;
case InputType::Float4: return Vec4Data::Type();
}
assert(false);
throw std::runtime_error("Unhandled input type");
}
std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
{
assert(port == 0);
const auto& inputEntry = GetGraph().GetInput(m_currentInputIndex);
auto vecData = std::make_shared<Vec4Data>();
vecData->preview = QImage();
return vecData;
}

View File

@ -0,0 +1,47 @@
#pragma once
#ifndef NAZARA_SHADERNODES_INPUTVALUE_HPP
#define NAZARA_SHADERNODES_INPUTVALUE_HPP
#include <QtWidgets/QComboBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLabel>
#include <ShaderGraph.hpp>
#include <DataModels/ShaderNode.hpp>
#include <array>
class InputValue : public ShaderNode
{
public:
InputValue(ShaderGraph& graph);
~InputValue() = default;
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const override;
QString caption() const override { return "Input"; }
QString name() const override { return "Input"; }
QWidget* embeddedWidget() override;
unsigned int nPorts(QtNodes::PortType portType) const override;
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
protected:
void UpdatePreview();
void UpdateInputList();
NazaraSlot(ShaderGraph, OnInputListUpdate, m_onInputListUpdateSlot);
NazaraSlot(ShaderGraph, OnInputUpdate, m_onInputUpdateSlot);
std::size_t m_currentInputIndex;
QComboBox* m_inputSelection;
QLabel* m_previewLabel;
QWidget* m_widget;
QVBoxLayout* m_layout;
};
#include <DataModels/InputValue.inl>
#endif

View File

@ -0,0 +1,2 @@
#include <DataModels/InputValue.hpp>
#include <array>

View File

@ -94,7 +94,20 @@ Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::Express
{ {
assert(count == 1); assert(count == 1);
auto sampler = Nz::ShaderBuilder::Uniform("Texture0", Nz::ShaderAst::ExpressionType::Sampler2D); const auto& textureEntry = GetGraph().GetTexture(m_currentTextureIndex);
Nz::ShaderAst::ExpressionType expression = [&]
{
switch (textureEntry.type)
{
case TextureType::Sampler2D: return Nz::ShaderAst::ExpressionType::Sampler2D;
}
assert(false);
throw std::runtime_error("Unhandled texture type");
}();
auto sampler = Nz::ShaderBuilder::Uniform(textureEntry.name, expression);
return Nz::ShaderBuilder::Sample2D(sampler, expressions[0]); return Nz::ShaderBuilder::Sample2D(sampler, expressions[0]);
} }

42
src/ShaderNode/Enums.cpp Normal file
View File

@ -0,0 +1,42 @@
#include <Enums.hpp>
#include <cassert>
const char* EnumToString(InputRole role)
{
switch (role)
{
case InputRole::None: return "None";
case InputRole::Normal: return "Normal";
case InputRole::Position: return "Position";
case InputRole::TexCoord: return "TexCoord";
}
assert(false);
return "<Unhandled>";
}
const char* EnumToString(InputType input)
{
switch (input)
{
case InputType::Bool: return "Bool";
case InputType::Float1: return "Float";
case InputType::Float2: return "Float2";
case InputType::Float3: return "Float3";
case InputType::Float4: return "Float4";
}
assert(false);
return "<Unhandled>";
}
const char* EnumToString(TextureType textureType)
{
switch (textureType)
{
case TextureType::Sampler2D: return "Sampler2D";
}
assert(false);
return "<Unhandled>";
}

48
src/ShaderNode/Enums.hpp Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#ifndef NAZARA_SHADERNODES_ENUMS_HPP
#define NAZARA_SHADERNODES_ENUMS_HPP
#include <cstddef>
enum class InputRole
{
None,
Normal,
Position,
TexCoord,
Max = TexCoord
};
constexpr std::size_t InputRoleCount = static_cast<std::size_t>(InputRole::Max) + 1;
enum class InputType
{
Bool,
Float1,
Float2,
Float3,
Float4,
Max = Float4
};
constexpr std::size_t InputTypeCount = static_cast<std::size_t>(InputType::Max) + 1;
enum class TextureType
{
Sampler2D,
Max = Sampler2D
};
constexpr std::size_t TextureTypeCount = static_cast<std::size_t>(TextureType::Max) + 1;
const char* EnumToString(InputRole role);
const char* EnumToString(InputType input);
const char* EnumToString(TextureType textureType);
#include <Enums.inl>
#endif

1
src/ShaderNode/Enums.inl Normal file
View File

@ -0,0 +1 @@
#include <Enums.hpp>

View File

@ -1,6 +1,7 @@
#include <ShaderGraph.hpp> #include <ShaderGraph.hpp>
#include <Nazara/Core/StackArray.hpp> #include <Nazara/Core/StackArray.hpp>
#include <DataModels/FragmentOutput.hpp> #include <DataModels/FragmentOutput.hpp>
#include <DataModels/InputValue.hpp>
#include <DataModels/SampleTexture.hpp> #include <DataModels/SampleTexture.hpp>
#include <DataModels/ShaderNode.hpp> #include <DataModels/ShaderNode.hpp>
#include <DataModels/VecBinOp.hpp> #include <DataModels/VecBinOp.hpp>
@ -35,7 +36,21 @@ m_flowScene(BuildRegistry())
m_flowScene.createConnection(node2, 0, node1, 0); m_flowScene.createConnection(node2, 0, node1, 0);
} }
std::size_t ShaderGraph::AddTexture(std::string name, Nz::ShaderAst::ExpressionType type) std::size_t ShaderGraph::AddInput(std::string name, InputType type, InputRole role, std::size_t roleIndex)
{
std::size_t index = m_inputs.size();
auto& inputEntry = m_inputs.emplace_back();
inputEntry.name = std::move(name);
inputEntry.role = role;
inputEntry.roleIndex = roleIndex;
inputEntry.type = type;
OnInputListUpdate(this);
return index;
}
std::size_t ShaderGraph::AddTexture(std::string name, TextureType type)
{ {
std::size_t index = m_textures.size(); std::size_t index = m_textures.size();
auto& textureEntry = m_textures.emplace_back(); auto& textureEntry = m_textures.emplace_back();
@ -85,6 +100,18 @@ Nz::ShaderAst::StatementPtr ShaderGraph::ToAst()
return std::make_shared<Nz::ShaderAst::StatementBlock>(std::move(statements)); return std::make_shared<Nz::ShaderAst::StatementBlock>(std::move(statements));
} }
void ShaderGraph::UpdateInput(std::size_t inputIndex, std::string name, InputType type, InputRole role, std::size_t roleIndex)
{
assert(inputIndex < m_inputs.size());
auto& inputEntry = m_inputs[inputIndex];
inputEntry.name = std::move(name);
inputEntry.role = role;
inputEntry.roleIndex = roleIndex;
inputEntry.type = type;
OnInputUpdate(this, inputIndex);
}
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());
@ -98,7 +125,8 @@ void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview)
std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry() std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
{ {
auto registry = std::make_shared<QtNodes::DataModelRegistry>(); auto registry = std::make_shared<QtNodes::DataModelRegistry>();
RegisterShaderNode<FragmentOutput>(*this, registry, "Output"); RegisterShaderNode<FragmentOutput>(*this, registry, "Outputs");
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
RegisterShaderNode<SampleTexture>(*this, registry, "Texture"); RegisterShaderNode<SampleTexture>(*this, registry, "Texture");
RegisterShaderNode<Vec4Add>(*this, registry, "Vector operations"); RegisterShaderNode<Vec4Add>(*this, registry, "Vector operations");
RegisterShaderNode<Vec4Mul>(*this, registry, "Vector operations"); RegisterShaderNode<Vec4Mul>(*this, registry, "Vector operations");

View File

@ -6,35 +6,50 @@
#include <Nazara/Core/Signal.hpp> #include <Nazara/Core/Signal.hpp>
#include <Nazara/Renderer/ShaderAst.hpp> #include <Nazara/Renderer/ShaderAst.hpp>
#include <nodes/FlowScene> #include <nodes/FlowScene>
#include <nodes/FlowView> #include <Enums.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
class ShaderGraph class ShaderGraph
{ {
public: public:
struct InputEntry;
struct TextureEntry; struct TextureEntry;
ShaderGraph(); ShaderGraph();
~ShaderGraph() = default; ~ShaderGraph() = default;
std::size_t AddTexture(std::string name, Nz::ShaderAst::ExpressionType type); std::size_t AddInput(std::string name, InputType type, InputRole role, std::size_t roleIndex);
std::size_t AddTexture(std::string name, TextureType type);
inline const InputEntry& GetInput(std::size_t inputIndex) const;
inline const std::vector<InputEntry>& GetInputs() const;
inline QtNodes::FlowScene& GetScene(); inline QtNodes::FlowScene& GetScene();
inline const TextureEntry& GetTexture(std::size_t textureIndex) const; inline const TextureEntry& GetTexture(std::size_t textureIndex) const;
inline const std::vector<TextureEntry>& GetTextures(); inline const std::vector<TextureEntry>& GetTextures() const;
Nz::ShaderAst::StatementPtr ToAst(); Nz::ShaderAst::StatementPtr ToAst();
void UpdateInput(std::size_t inputIndex, std::string name, InputType type, InputRole role, std::size_t roleIndex);
void UpdateTexturePreview(std::size_t texture, QImage preview); void UpdateTexturePreview(std::size_t texture, QImage preview);
struct InputEntry
{
std::size_t roleIndex;
std::string name;
InputRole role;
InputType type;
};
struct TextureEntry struct TextureEntry
{ {
std::string name; std::string name;
Nz::ShaderAst::ExpressionType type; TextureType type;
QImage preview; QImage preview;
}; };
NazaraSignal(OnInputListUpdate, ShaderGraph*);
NazaraSignal(OnInputUpdate, ShaderGraph*, std::size_t /*inputIndex*/);
NazaraSignal(OnTextureListUpdate, ShaderGraph*); NazaraSignal(OnTextureListUpdate, ShaderGraph*);
NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/); NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/);
@ -42,6 +57,7 @@ class ShaderGraph
std::shared_ptr<QtNodes::DataModelRegistry> BuildRegistry(); std::shared_ptr<QtNodes::DataModelRegistry> BuildRegistry();
QtNodes::FlowScene m_flowScene; QtNodes::FlowScene m_flowScene;
std::vector<InputEntry> m_inputs;
std::vector<TextureEntry> m_textures; std::vector<TextureEntry> m_textures;
}; };

View File

@ -1,5 +1,16 @@
#include <ShaderGraph.hpp> #include <ShaderGraph.hpp>
inline auto ShaderGraph::GetInput(std::size_t inputIndex) const -> const InputEntry&
{
assert(inputIndex < m_inputs.size());
return m_inputs[inputIndex];
}
inline auto ShaderGraph::GetInputs() const -> const std::vector<InputEntry>&
{
return m_inputs;
}
inline QtNodes::FlowScene& ShaderGraph::GetScene() inline QtNodes::FlowScene& ShaderGraph::GetScene()
{ {
return m_flowScene; return m_flowScene;
@ -11,7 +22,7 @@ inline auto ShaderGraph::GetTexture(std::size_t textureIndex) const -> const Tex
return m_textures[textureIndex]; return m_textures[textureIndex];
} }
inline auto ShaderGraph::GetTextures() -> const std::vector<TextureEntry>& inline auto ShaderGraph::GetTextures() const -> const std::vector<TextureEntry>&
{ {
return m_textures; return m_textures;
} }

View File

@ -0,0 +1,80 @@
#include <Widgets/InputEditDialog.hpp>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QVBoxLayout>
InputEditDialog::InputEditDialog(QWidget* parent) :
QDialog(parent)
{
setWindowTitle(tr("Input edit dialog"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
m_inputName = new QLineEdit;
m_typeList = new QComboBox;
for (std::size_t i = 0; i < InputTypeCount; ++i)
m_typeList->addItem(EnumToString(static_cast<InputType>(i)));
m_roleList = new QComboBox;
for (std::size_t i = 0; i < InputRoleCount; ++i)
m_roleList->addItem(EnumToString(static_cast<InputRole>(i)));
m_roleIndex = new QSpinBox;
QFormLayout* formLayout = new QFormLayout;
formLayout->addRow(tr("Name"), m_inputName);
formLayout->addRow(tr("Type"), m_typeList);
formLayout->addRow(tr("Role"), m_roleList);
formLayout->addRow(tr("Role index"), m_roleIndex);
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, &QDialogButtonBox::accepted, this, &InputEditDialog::OnAccept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QVBoxLayout* verticalLayout = new QVBoxLayout;
verticalLayout->addLayout(formLayout);
verticalLayout->addWidget(buttonBox);
setLayout(verticalLayout);
}
InputEditDialog::InputEditDialog(const InputInfo& input, QWidget* parent) :
InputEditDialog(parent)
{
m_inputName->setText(QString::fromStdString(input.name));
m_roleIndex->setValue(int(input.roleIndex));
m_roleList->setCurrentText(EnumToString(input.role));
m_typeList->setCurrentText(EnumToString(input.type));
}
InputInfo InputEditDialog::GetInputInfo() const
{
InputInfo inputInfo;
inputInfo.name = m_inputName->text().toStdString();
inputInfo.role = static_cast<InputRole>(m_roleList->currentIndex());
inputInfo.roleIndex = static_cast<std::size_t>(m_roleIndex->value());
inputInfo.type = static_cast<InputType>(m_typeList->currentIndex());
return inputInfo;
}
void InputEditDialog::OnAccept()
{
if (m_inputName->text().isEmpty())
{
QMessageBox::critical(this, tr("Empty name"), tr("Input 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,41 @@
#pragma once
#ifndef NAZARA_SHADERNODES_INPUTEDITDIALOG_HPP
#define NAZARA_SHADERNODES_INPUTEDITDIALOG_HPP
#include <Enums.hpp>
#include <QtWidgets/QDialog>
class QComboBox;
class QLineEdit;
class QSpinBox;
struct InputInfo
{
std::size_t roleIndex;
std::string name;
InputRole role;
InputType type;
};
class InputEditDialog : public QDialog
{
public:
InputEditDialog(QWidget* parent = nullptr);
InputEditDialog(const InputInfo& input, QWidget* parent = nullptr);
~InputEditDialog() = default;
InputInfo GetInputInfo() const;
private:
void OnAccept();
QComboBox* m_roleList;
QComboBox* m_typeList;
QLineEdit* m_inputName;
QSpinBox* m_roleIndex;
};
#include <Widgets/InputEditor.inl>
#endif

View File

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

View File

@ -0,0 +1,97 @@
#include <Widgets/InputEditor.hpp>
#include <Widgets/InputEditDialog.hpp>
#include <ShaderGraph.hpp>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QListWidget>
#include <QtWidgets/QVBoxLayout>
InputEditor::InputEditor(ShaderGraph& graph) :
m_shaderGraph(graph)
{
m_inputList = new QListWidget(this);
connect(m_inputList, &QListWidget::currentRowChanged, this, &InputEditor::OnInputSelectionUpdate);
connect(m_inputList, &QListWidget::itemDoubleClicked, [this](QListWidgetItem* item)
{
OnEditInput(m_inputList->row(item));
});
QPushButton* addInputButton = new QPushButton(tr("Add input..."));
connect(addInputButton, &QPushButton::released, this, &InputEditor::OnAddInput);
m_layout = new QVBoxLayout;
m_layout->addWidget(m_inputList);
m_layout->addWidget(addInputButton);
setLayout(m_layout);
m_onInputListUpdateSlot.Connect(m_shaderGraph.OnInputListUpdate, this, &InputEditor::OnInputListUpdate);
m_onInputUpdateSlot.Connect(m_shaderGraph.OnInputUpdate, this, &InputEditor::OnInputUpdate);
RefreshInputs();
}
void InputEditor::OnAddInput()
{
InputEditDialog* dialog = new InputEditDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
connect(dialog, &QDialog::accepted, [this, dialog]
{
InputInfo inputInfo = dialog->GetInputInfo();
m_shaderGraph.AddInput(std::move(inputInfo.name), inputInfo.type, inputInfo.role, inputInfo.roleIndex);
});
dialog->open();
}
void InputEditor::OnEditInput(int inputIndex)
{
const auto& input = m_shaderGraph.GetInput(inputIndex);
InputInfo info;
info.name = input.name;
info.type = input.type;
info.role = input.role;
info.roleIndex = input.roleIndex;
InputEditDialog* dialog = new InputEditDialog(std::move(info), this);
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
connect(dialog, &QDialog::accepted, [this, dialog, inputIndex]
{
InputInfo inputInfo = dialog->GetInputInfo();
m_shaderGraph.UpdateInput(inputIndex, std::move(inputInfo.name), inputInfo.type, inputInfo.role, inputInfo.roleIndex);
});
dialog->open();
}
void InputEditor::OnInputSelectionUpdate(int inputIndex)
{
if (inputIndex >= 0)
{
m_currentInputIndex = inputIndex;
}
else
m_currentInputIndex.reset();
}
void InputEditor::OnInputListUpdate(ShaderGraph* /*graph*/)
{
RefreshInputs();
}
void InputEditor::OnInputUpdate(ShaderGraph* /*graph*/, std::size_t inputIndex)
{
const auto& inputEntry = m_shaderGraph.GetInput(inputIndex);
m_inputList->item(int(inputIndex))->setText(QString::fromStdString(inputEntry.name));
}
void InputEditor::RefreshInputs()
{
m_inputList->clear();
m_inputList->setCurrentRow(-1);
for (const auto& inputEntry : m_shaderGraph.GetInputs())
m_inputList->addItem(QString::fromStdString(inputEntry.name));
}

View File

@ -0,0 +1,39 @@
#pragma once
#ifndef NAZARA_SHADERNODES_INPUTEDITOR_HPP
#define NAZARA_SHADERNODES_INPUTEDITOR_HPP
#include <ShaderGraph.hpp>
#include <QtWidgets/QWidget>
#include <optional>
class QLabel;
class QListWidget;
class QVBoxLayout;
class InputEditor : public QWidget
{
public:
InputEditor(ShaderGraph& graph);
~InputEditor() = default;
private:
void OnAddInput();
void OnEditInput(int inputIndex);
void OnInputSelectionUpdate(int inputIndex);
void OnInputListUpdate(ShaderGraph* graph);
void OnInputUpdate(ShaderGraph* graph, std::size_t inputIndex);
void RefreshInputs();
NazaraSlot(ShaderGraph, OnInputListUpdate, m_onInputListUpdateSlot);
NazaraSlot(ShaderGraph, OnInputUpdate, m_onInputUpdateSlot);
std::optional<std::size_t> m_currentInputIndex;
ShaderGraph& m_shaderGraph;
QListWidget* m_inputList;
QVBoxLayout* m_layout;
};
#include <Widgets/InputEditor.inl>
#endif

View File

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

View File

@ -1,8 +1,10 @@
#include <Widgets/MainWindow.hpp> #include <Widgets/MainWindow.hpp>
#include <Nazara/Renderer/GlslWriter.hpp> #include <Nazara/Renderer/GlslWriter.hpp>
#include <ShaderGraph.hpp> #include <ShaderGraph.hpp>
#include <Widgets/InputEditor.hpp>
#include <Widgets/TextureEditor.hpp> #include <Widgets/TextureEditor.hpp>
#include <nodes/FlowView> #include <nodes/FlowView>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QMenuBar> #include <QtWidgets/QMenuBar>
#include <QtWidgets/QTextEdit> #include <QtWidgets/QTextEdit>
#include <iostream> #include <iostream>
@ -17,6 +19,13 @@ m_shaderGraph(graph)
QtNodes::FlowView* flowView = new QtNodes::FlowView(scene); QtNodes::FlowView* flowView = new QtNodes::FlowView(scene);
setCentralWidget(flowView); setCentralWidget(flowView);
QDockWidget* inputDock = new QDockWidget(tr("&Inputs"));
InputEditor* inputEditor = new InputEditor(m_shaderGraph);
inputDock->setWidget(inputEditor);
addDockWidget(Qt::LeftDockWidgetArea, inputDock);
QDockWidget* textureDock = new QDockWidget(tr("&Textures")); QDockWidget* textureDock = new QDockWidget(tr("&Textures"));
TextureEditor* textureEditor = new TextureEditor(m_shaderGraph); TextureEditor* textureEditor = new TextureEditor(m_shaderGraph);

View File

@ -9,7 +9,7 @@
TextureEditor::TextureEditor(ShaderGraph& graph) : TextureEditor::TextureEditor(ShaderGraph& graph) :
m_shaderGraph(graph) m_shaderGraph(graph)
{ {
m_textureList = new QListWidget(this); m_textureList = new QListWidget;
connect(m_textureList, &QListWidget::currentRowChanged, this, &TextureEditor::OnTextureSelectionUpdate); connect(m_textureList, &QListWidget::currentRowChanged, this, &TextureEditor::OnTextureSelectionUpdate);
m_pixmapLabel = new QLabel; m_pixmapLabel = new QLabel;

View File

@ -4,7 +4,7 @@
#define NAZARA_SHADERNODES_TEXTUREEDITOR_HPP #define NAZARA_SHADERNODES_TEXTUREEDITOR_HPP
#include <ShaderGraph.hpp> #include <ShaderGraph.hpp>
#include <QtWidgets/QDockWidget> #include <QtWidgets/QWidget>
#include <optional> #include <optional>
class QLabel; class QLabel;

View File

@ -8,8 +8,8 @@ int main(int argc, char* argv[])
QApplication app(argc, argv); QApplication app(argc, argv);
ShaderGraph shaderGraph; ShaderGraph shaderGraph;
shaderGraph.AddTexture("Potato", Nz::ShaderAst::ExpressionType::Sampler2D); shaderGraph.AddInput("UV", InputType::Float2, InputRole::TexCoord, 0);
shaderGraph.AddTexture("Blackbird", Nz::ShaderAst::ExpressionType::Sampler2D); shaderGraph.AddTexture("Potato", TextureType::Sampler2D);
MainWindow mainWindow(shaderGraph); MainWindow mainWindow(shaderGraph);
mainWindow.resize(1280, 720); mainWindow.resize(1280, 720);