From effaa9b88fbf956d0e583a58a4433d8a7d174610 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 May 2020 20:06:32 +0200 Subject: [PATCH] Update ShaderNode --- src/ShaderNode/DataModels/FragmentOutput.hpp | 2 + src/ShaderNode/DataModels/FragmentOutput.inl | 5 + src/ShaderNode/DataModels/SampleTexture.cpp | 106 +++++++++++++++++++ src/ShaderNode/DataModels/SampleTexture.hpp | 47 ++++++++ src/ShaderNode/DataModels/SampleTexture.inl | 2 + src/ShaderNode/DataModels/ShaderNode.hpp | 11 ++ src/ShaderNode/DataModels/ShaderNode.inl | 15 +++ src/ShaderNode/DataModels/VecBinOp.cpp | 1 + src/ShaderNode/DataModels/VecBinOp.hpp | 60 +++++++++++ src/ShaderNode/DataModels/VecBinOp.inl | 93 ++++++++++++++++ src/ShaderNode/DataModels/VecValue.cpp | 55 ++++++++++ src/ShaderNode/DataModels/VecValue.hpp | 62 +++++++++-- src/ShaderNode/DataModels/VecValue.inl | 34 +++++- src/ShaderNode/ShaderGraph.cpp | 95 +++++++++++++++++ src/ShaderNode/ShaderGraph.hpp | 45 ++++++++ src/ShaderNode/ShaderGraph.inl | 11 ++ src/ShaderNode/main.cpp | 86 ++------------- 17 files changed, 646 insertions(+), 84 deletions(-) create mode 100644 src/ShaderNode/DataModels/SampleTexture.cpp create mode 100644 src/ShaderNode/DataModels/SampleTexture.hpp create mode 100644 src/ShaderNode/DataModels/SampleTexture.inl create mode 100644 src/ShaderNode/DataModels/VecBinOp.cpp create mode 100644 src/ShaderNode/DataModels/VecBinOp.hpp create mode 100644 src/ShaderNode/DataModels/VecBinOp.inl create mode 100644 src/ShaderNode/ShaderGraph.cpp create mode 100644 src/ShaderNode/ShaderGraph.hpp create mode 100644 src/ShaderNode/ShaderGraph.inl diff --git a/src/ShaderNode/DataModels/FragmentOutput.hpp b/src/ShaderNode/DataModels/FragmentOutput.hpp index 30aa74b90..a682d40a4 100644 --- a/src/ShaderNode/DataModels/FragmentOutput.hpp +++ b/src/ShaderNode/DataModels/FragmentOutput.hpp @@ -10,6 +10,8 @@ class FragmentOutput : public ShaderNode { public: + inline FragmentOutput(ShaderGraph& graph); + Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override; QString caption() const override { return "Fragment shader output"; } diff --git a/src/ShaderNode/DataModels/FragmentOutput.inl b/src/ShaderNode/DataModels/FragmentOutput.inl index f8287a921..539b8091f 100644 --- a/src/ShaderNode/DataModels/FragmentOutput.inl +++ b/src/ShaderNode/DataModels/FragmentOutput.inl @@ -1 +1,6 @@ #include + +inline FragmentOutput::FragmentOutput(ShaderGraph& graph) : +ShaderNode(graph) +{ +} diff --git a/src/ShaderNode/DataModels/SampleTexture.cpp b/src/ShaderNode/DataModels/SampleTexture.cpp new file mode 100644 index 000000000..1f4bd4f80 --- /dev/null +++ b/src/ShaderNode/DataModels/SampleTexture.cpp @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +SampleTexture::SampleTexture(ShaderGraph& graph) : +ShaderNode(graph) +{ + m_layout = new QVBoxLayout; + + m_textureSelection = new QComboBox; + m_textureSelection->setStyleSheet("background-color: rgba(255,255,255,255)"); + + m_layout->addWidget(m_textureSelection); + + m_pixmap = QPixmap(64, 64); + m_pixmap.fill(); + + m_pixmapLabel = new QLabel; + m_pixmapLabel->setPixmap(m_pixmap); + + m_layout->addWidget(m_pixmapLabel); + + m_widget = new QWidget; + m_widget->setStyleSheet("background-color: rgba(0,0,0,0)"); + m_widget->setLayout(m_layout); + + m_onTextureListUpdate.Connect(GetGraph().OnTextureListUpdate, [&](ShaderGraph*) { UpdateTextureList(); }); + UpdateTextureList(); +} + +QWidget* SampleTexture::embeddedWidget() +{ + return m_widget; +} + +unsigned int SampleTexture::nPorts(QtNodes::PortType portType) const +{ + switch (portType) + { + case QtNodes::PortType::In: return 1; + case QtNodes::PortType::Out: return 1; + } + + return 0; +} + +void SampleTexture::UpdatePreview() +{ + ComputePreview(m_pixmap); + m_pixmapLabel->setPixmap(m_pixmap); +} + +void SampleTexture::UpdateTextureList() +{ + QString currentTexture = m_textureSelection->currentText(); + m_textureSelection->clear(); + + for (const auto& textureEntry : GetGraph().GetTextures()) + m_textureSelection->addItem(QString::fromStdString(textureEntry.name)); + + m_textureSelection->setCurrentText(currentTexture); +} + +void SampleTexture::ComputePreview(QPixmap& pixmap) const +{ + pixmap.fill(); +} + +Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const +{ + assert(count == 1); + + auto sampler = Nz::ShaderBuilder::Uniform("Texture0", Nz::ShaderAst::ExpressionType::Sampler2D); + + return Nz::ShaderBuilder::Sample2D(sampler, expressions[0]); +} + +auto SampleTexture::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType +{ + switch (portType) + { + case QtNodes::PortType::In: + { + assert(portIndex == 0); + return Vec2Data::Type(); + } + + case QtNodes::PortType::Out: + { + assert(portIndex == 0); + return Vec4Data::Type(); + } + + default: + assert(false); + throw std::runtime_error("Invalid PortType"); + } +} + +std::shared_ptr SampleTexture::outData(QtNodes::PortIndex port) +{ + assert(port == 0); + + return std::make_shared(Nz::Vector4f::Zero()); +} diff --git a/src/ShaderNode/DataModels/SampleTexture.hpp b/src/ShaderNode/DataModels/SampleTexture.hpp new file mode 100644 index 000000000..df107169c --- /dev/null +++ b/src/ShaderNode/DataModels/SampleTexture.hpp @@ -0,0 +1,47 @@ +#pragma once + +#ifndef NAZARA_SHADERNODES_SAMPLETEXTURE_HPP +#define NAZARA_SHADERNODES_SAMPLETEXTURE_HPP + +#include +#include +#include +#include +#include +#include + +class SampleTexture : public ShaderNode +{ + public: + SampleTexture(ShaderGraph& graph); + ~SampleTexture() = default; + + Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const override; + + QString caption() const override { return "Sample texture"; } + QString name() const override { return "SampleTexture"; } + + 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 outData(QtNodes::PortIndex port) override; + + protected: + void UpdatePreview(); + void UpdateTextureList(); + + void ComputePreview(QPixmap& pixmap) const; + + NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdate); + + QComboBox* m_textureSelection; + QLabel* m_pixmapLabel; + QPixmap m_pixmap; + QWidget* m_widget; + QVBoxLayout* m_layout; +}; + +#include + +#endif diff --git a/src/ShaderNode/DataModels/SampleTexture.inl b/src/ShaderNode/DataModels/SampleTexture.inl new file mode 100644 index 000000000..78d12b21d --- /dev/null +++ b/src/ShaderNode/DataModels/SampleTexture.inl @@ -0,0 +1,2 @@ +#include +#include diff --git a/src/ShaderNode/DataModels/ShaderNode.hpp b/src/ShaderNode/DataModels/ShaderNode.hpp index 5c8f6e7f8..71a279120 100644 --- a/src/ShaderNode/DataModels/ShaderNode.hpp +++ b/src/ShaderNode/DataModels/ShaderNode.hpp @@ -6,10 +6,21 @@ #include #include +class ShaderGraph; + class ShaderNode : public QtNodes::NodeDataModel { public: + inline ShaderNode(ShaderGraph& graph); + virtual Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const = 0; + inline ShaderGraph& GetGraph(); + inline const ShaderGraph& GetGraph() const; + + void setInData(std::shared_ptr, int) override {}; + + private: + ShaderGraph& m_graph; }; #include diff --git a/src/ShaderNode/DataModels/ShaderNode.inl b/src/ShaderNode/DataModels/ShaderNode.inl index fba232649..a244d78b5 100644 --- a/src/ShaderNode/DataModels/ShaderNode.inl +++ b/src/ShaderNode/DataModels/ShaderNode.inl @@ -1 +1,16 @@ #include + +inline ShaderNode::ShaderNode(ShaderGraph& graph) : +m_graph(graph) +{ +} + +inline ShaderGraph& ShaderNode::GetGraph() +{ + return m_graph; +} + +inline const ShaderGraph& ShaderNode::GetGraph() const +{ + return m_graph; +} diff --git a/src/ShaderNode/DataModels/VecBinOp.cpp b/src/ShaderNode/DataModels/VecBinOp.cpp new file mode 100644 index 000000000..dd13b5b56 --- /dev/null +++ b/src/ShaderNode/DataModels/VecBinOp.cpp @@ -0,0 +1 @@ +#include diff --git a/src/ShaderNode/DataModels/VecBinOp.hpp b/src/ShaderNode/DataModels/VecBinOp.hpp new file mode 100644 index 000000000..131a05f6d --- /dev/null +++ b/src/ShaderNode/DataModels/VecBinOp.hpp @@ -0,0 +1,60 @@ +#pragma once + +#ifndef NAZARA_SHADERNODES_VECBINOP_HPP +#define NAZARA_SHADERNODES_VECBINOP_HPP + +#include +#include + +template +class VecBinOp : public ShaderNode +{ + public: + VecBinOp(ShaderGraph& graph); + ~VecBinOp() = default; + + Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override; + + 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 outData(QtNodes::PortIndex port) override; + + void setInData(std::shared_ptr value, int index) override; + + private: + void UpdatePreview(); + + using InternalType = typename Data::InternalType; + + InternalType GetValue() const; + + QLabel* m_pixmapLabel; + QPixmap m_preview; + std::shared_ptr m_lhs; + std::shared_ptr m_rhs; +}; + +class Vec4Add : public VecBinOp +{ + public: + using VecBinOp::VecBinOp; + + QString caption() const override { return "Vec4 addition"; } + QString name() const override { return "Vec4Add"; } +}; + +class Vec4Mul : public VecBinOp +{ + public: + using VecBinOp::VecBinOp; + + QString caption() const override { return "Vec4 multiplication"; } + QString name() const override { return "Vec4Mul"; } +}; + +#include + +#endif diff --git a/src/ShaderNode/DataModels/VecBinOp.inl b/src/ShaderNode/DataModels/VecBinOp.inl new file mode 100644 index 000000000..371905221 --- /dev/null +++ b/src/ShaderNode/DataModels/VecBinOp.inl @@ -0,0 +1,93 @@ +#include +#include + +template +VecBinOp::VecBinOp(ShaderGraph& graph) : +ShaderNode(graph) +{ + m_preview = QPixmap(64, 64); + + m_pixmapLabel = new QLabel; + m_pixmapLabel->setPixmap(m_preview); +} + +template +Nz::ShaderAst::ExpressionPtr VecBinOp::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const +{ + assert(count == 2); + using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder; + constexpr BuilderType builder; + return builder(expressions[0], expressions[1]); +} + +template +QWidget* VecBinOp::embeddedWidget() +{ + return m_pixmapLabel; +} + +template +QtNodes::NodeDataType VecBinOp::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const +{ + assert(portIndex == 0 || portIndex == 1); + + return Data::Type(); +} + +template +unsigned int VecBinOp::nPorts(QtNodes::PortType portType) const +{ + switch (portType) + { + case QtNodes::PortType::In: return 2; + case QtNodes::PortType::Out: return 1; + } + + return 0; +} + +template +std::shared_ptr VecBinOp::outData(QtNodes::PortIndex port) +{ + assert(port == 0); + return std::make_shared(GetValue()); +} + +template +void VecBinOp::setInData(std::shared_ptr value, int index) +{ + std::shared_ptr castedValue; + if (value) + { + assert(dynamic_cast(value.get()) != nullptr); + assert(index == 0 || index == 1); + + castedValue = std::static_pointer_cast(value); + } + + if (index == 0) + m_lhs = std::move(castedValue); + else + m_rhs = std::move(castedValue); + + UpdatePreview(); + + Q_EMIT dataUpdated(0); +} + +template +void VecBinOp::UpdatePreview() +{ + InternalType value = GetValue(); + m_preview.fill(QColor::fromRgbF(value.x, value.y, value.z, value.w)); + m_pixmapLabel->setPixmap(m_preview); +} + +template +auto VecBinOp::GetValue() const -> InternalType +{ + if (!m_lhs || !m_rhs) + return InternalType::Zero(); + + return m_lhs->value * m_rhs->value; +} diff --git a/src/ShaderNode/DataModels/VecValue.cpp b/src/ShaderNode/DataModels/VecValue.cpp index 7986f0b9d..84f1f4ea8 100644 --- a/src/ShaderNode/DataModels/VecValue.cpp +++ b/src/ShaderNode/DataModels/VecValue.cpp @@ -1,6 +1,55 @@ #include #include +Vec2Value::Vec2Value(ShaderGraph& graph) : +VecValue(graph) +{ + UpdatePreview(); +} + +Nz::ShaderAst::ExpressionPtr Vec2Value::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const +{ + assert(count == 0); + + return Nz::ShaderBuilder::Constant(GetValue()); +} + +auto Vec2Value::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType +{ + assert(portType == QtNodes::PortType::Out); + assert(portIndex == 0); + + return Vec2Data::Type(); +} + +std::shared_ptr Vec2Value::outData(QtNodes::PortIndex port) +{ + assert(port == 0); + + return std::make_shared(GetValue()); +} + +void Vec2Value::ComputePreview(QPixmap& pixmap) const +{ + Nz::Vector4f value = GetValue(); + pixmap.fill(QColor::fromRgbF(value.x, value.y, value.z, value.w)); +} + +Nz::Vector2f Vec2Value::GetValue() const +{ + float x = float(m_values[0]->value()); + float y = float(m_values[1]->value()); + + return Nz::Vector2f(x, y); +} + + +Vec4Value::Vec4Value(ShaderGraph& graph) : +VecValue(graph) +{ + UpdatePreview(); +} + Nz::ShaderAst::ExpressionPtr Vec4Value::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const { assert(count == 0); @@ -23,6 +72,12 @@ std::shared_ptr Vec4Value::outData(QtNodes::PortIndex port) return std::make_shared(GetValue()); } +void Vec4Value::ComputePreview(QPixmap& pixmap) const +{ + Nz::Vector4f value = GetValue(); + pixmap.fill(QColor::fromRgbF(value.x, value.y, value.z, value.w)); +} + Nz::Vector4f Vec4Value::GetValue() const { float x = float(m_values[0]->value()); diff --git a/src/ShaderNode/DataModels/VecValue.hpp b/src/ShaderNode/DataModels/VecValue.hpp index 83bd8b3a8..10e215971 100644 --- a/src/ShaderNode/DataModels/VecValue.hpp +++ b/src/ShaderNode/DataModels/VecValue.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -12,22 +13,50 @@ template class VecValue : public ShaderNode { public: - VecValue(); + VecValue(ShaderGraph& graph); ~VecValue() = default; QWidget* embeddedWidget() override; unsigned int nPorts(QtNodes::PortType portType) const override; protected: + void UpdatePreview(); + + virtual void ComputePreview(QPixmap& pixmap) const = 0; + + QLabel* m_pixmapLabel; + QPixmap m_pixmap; QWidget* m_widget; QFormLayout* m_layout; std::array m_values; }; +class Vec2Data : public QtNodes::NodeData +{ + public: + using InternalType = Nz::Vector2f; + + inline Vec2Data(const InternalType& vec); + + QtNodes::NodeDataType type() const override + { + return Type(); + } + + static QtNodes::NodeDataType Type() + { + return { "vec2", "Vec2" }; + } + + InternalType value; +}; + class Vec4Data : public QtNodes::NodeData { public: - inline Vec4Data(const Nz::Vector4f& vec); + using InternalType = Nz::Vector4f; + + inline Vec4Data(const InternalType& vec); QtNodes::NodeDataType type() const override { @@ -39,25 +68,46 @@ class Vec4Data : public QtNodes::NodeData return { "vec4", "Vec4" }; } - Nz::Vector4f value; + InternalType value; +}; + +class Vec2Value : public VecValue<2> +{ + public: + Vec2Value(ShaderGraph& graph); + + Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override; + + QString caption() const override { return "Vec2 value"; } + QString name() const override { return "Vec2Value"; } + + QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override; + + std::shared_ptr outData(QtNodes::PortIndex port) override; + + private: + void ComputePreview(QPixmap& pixmap) const override; + + Nz::Vector2f GetValue() const; }; class Vec4Value : public VecValue<4> { public: + Vec4Value(ShaderGraph& graph); + Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override; QString caption() const override { return "Vec4 value"; } - bool captionVisible() const override { return true; } QString name() const override { return "Vec4Value"; } QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override; std::shared_ptr outData(QtNodes::PortIndex port) override; - void setInData(std::shared_ptr, int) override {}; - private: + void ComputePreview(QPixmap& pixmap) const override; + Nz::Vector4f GetValue() const; }; diff --git a/src/ShaderNode/DataModels/VecValue.inl b/src/ShaderNode/DataModels/VecValue.inl index 7377fdbad..e79eef3dc 100644 --- a/src/ShaderNode/DataModels/VecValue.inl +++ b/src/ShaderNode/DataModels/VecValue.inl @@ -2,7 +2,8 @@ #include template -VecValue::VecValue() +VecValue::VecValue(ShaderGraph& graph) : +ShaderNode(graph) { constexpr std::array componentName = { 'X', 'Y', 'Z', 'W' }; static_assert(N <= componentName.size()); @@ -11,10 +12,27 @@ VecValue::VecValue() for (std::size_t i = 0; i < N; ++i) { m_values[i] = new QDoubleSpinBox; + m_values[i]->setDecimals(6); + m_values[i]->setValue(1.0); m_values[i]->setStyleSheet("background-color: rgba(255,255,255,255)"); + connect(m_values[i], qOverload(&QDoubleSpinBox::valueChanged), [this](double) + { + UpdatePreview(); + + Q_EMIT dataUpdated(0); + }); + m_layout->addRow(QString::fromUtf8(&componentName[i], 1), m_values[i]); } + m_pixmap = QPixmap(64, 64); + m_pixmap.fill(); + + m_pixmapLabel = new QLabel; + m_pixmapLabel->setPixmap(m_pixmap); + + m_layout->addWidget(m_pixmapLabel); + m_widget = new QWidget; m_widget->setStyleSheet("background-color: rgba(0,0,0,0)"); m_widget->setLayout(m_layout); @@ -38,7 +56,19 @@ unsigned int VecValue::nPorts(QtNodes::PortType portType) const return 0; } -Vec4Data::Vec4Data(const Nz::Vector4f& vec) : +template +void VecValue::UpdatePreview() +{ + ComputePreview(m_pixmap); + m_pixmapLabel->setPixmap(m_pixmap); +} + +Vec2Data::Vec2Data(const InternalType& vec) : +value(vec) +{ +} + +Vec4Data::Vec4Data(const InternalType& vec) : value(vec) { } diff --git a/src/ShaderNode/ShaderGraph.cpp b/src/ShaderNode/ShaderGraph.cpp new file mode 100644 index 000000000..478e99408 --- /dev/null +++ b/src/ShaderNode/ShaderGraph.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + template + void RegisterShaderNode(ShaderGraph& graph, std::shared_ptr registry) + { + auto creator = [&] { return std::make_unique(graph); }; + registry->registerModel(std::move(creator)); + } +} + +ShaderGraph::ShaderGraph() : +m_flowScene(BuildRegistry()) +{ + auto& node1 = m_flowScene.createNode(std::make_unique(*this)); + node1.nodeGraphicsObject().setPos(200, 200); + + auto& node2 = m_flowScene.createNode(std::make_unique(*this)); + node2.nodeGraphicsObject().setPos(500, 300); + + m_flowScene.createConnection(node2, 0, node1, 0); +} + +void ShaderGraph::AddTexture(std::string name, Nz::ShaderAst::ExpressionType type) +{ + auto& textureEntry = m_textures.emplace_back(); + textureEntry.name = std::move(name); + textureEntry.type = type; + + OnTextureListUpdate(this); +} + +Nz::ShaderAst::StatementPtr ShaderGraph::Generate() +{ + std::vector statements; + + std::function HandleNode; + HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr + { + ShaderNode* shaderNode = static_cast(node->nodeDataModel()); + + qDebug() << shaderNode->name(); + std::size_t inputCount = shaderNode->nPorts(QtNodes::PortType::In); + Nz::StackArray expressions = NazaraStackArray(Nz::ShaderAst::ExpressionPtr, inputCount); + std::size_t i = 0; + + for (const auto& connectionSet : node->nodeState().getEntries(QtNodes::PortType::In)) + { + for (const auto& [uuid, conn] : connectionSet) + { + assert(i < expressions.size()); + expressions[i] = HandleNode(conn->getNode(QtNodes::PortType::Out)); + i++; + } + } + + return shaderNode->GetExpression(expressions.data(), expressions.size()); + }; + + m_flowScene.iterateOverNodes([&](QtNodes::Node* node) + { + if (node->nodeDataModel()->nPorts(QtNodes::PortType::Out) == 0) + { + statements.emplace_back(Nz::ShaderBuilder::ExprStatement(HandleNode(node))); + } + }); + + return std::make_shared(std::move(statements)); +} + +std::shared_ptr ShaderGraph::BuildRegistry() +{ + auto registry = std::make_shared(); + RegisterShaderNode(*this, registry); + RegisterShaderNode(*this, registry); + RegisterShaderNode(*this, registry); + RegisterShaderNode(*this, registry); + RegisterShaderNode(*this, registry); + + return registry; +} diff --git a/src/ShaderNode/ShaderGraph.hpp b/src/ShaderNode/ShaderGraph.hpp new file mode 100644 index 000000000..8e61175f1 --- /dev/null +++ b/src/ShaderNode/ShaderGraph.hpp @@ -0,0 +1,45 @@ +#pragma once + +#ifndef NAZARA_SHADERNODES_SHADERGRAPH_HPP +#define NAZARA_SHADERNODES_SHADERGRAPH_HPP + +#include +#include +#include +#include +#include +#include + +class ShaderGraph +{ + public: + struct TextureEntry; + + ShaderGraph(); + ~ShaderGraph() = default; + + void AddTexture(std::string name, Nz::ShaderAst::ExpressionType type); + + Nz::ShaderAst::StatementPtr Generate(); + + inline QtNodes::FlowScene& GetScene(); + inline const std::vector& GetTextures(); + + NazaraSignal(OnTextureListUpdate, ShaderGraph*); + + struct TextureEntry + { + std::string name; + Nz::ShaderAst::ExpressionType type; + }; + + private: + std::shared_ptr BuildRegistry(); + + QtNodes::FlowScene m_flowScene; + std::vector m_textures; +}; + +#include + +#endif diff --git a/src/ShaderNode/ShaderGraph.inl b/src/ShaderNode/ShaderGraph.inl new file mode 100644 index 000000000..07c20a134 --- /dev/null +++ b/src/ShaderNode/ShaderGraph.inl @@ -0,0 +1,11 @@ +#include + +inline QtNodes::FlowScene& ShaderGraph::GetScene() +{ + return m_flowScene; +} + +inline auto ShaderGraph::GetTextures() -> const std::vector& +{ + return m_textures; +} diff --git a/src/ShaderNode/main.cpp b/src/ShaderNode/main.cpp index 34141730c..7878bec22 100644 --- a/src/ShaderNode/main.cpp +++ b/src/ShaderNode/main.cpp @@ -1,10 +1,6 @@ -#include #include #include #include -#include -#include -#include #include #include #include @@ -17,103 +13,41 @@ #include #include #include +#include #include -std::shared_ptr registerDataModels() +void GenerateGLSL(ShaderGraph& graph) { - auto ret = std::make_shared(); - ret->registerModel(); - ret->registerModel(); - - return ret; -} - -void GenerateGLSL(QtNodes::FlowScene* scene) -{ - /*using namespace ShaderBuilder; - using ShaderAst::BuiltinEntry; - using ShaderAst::ExpressionType; - - // Fragment shader - { - auto rt0 = Output("RenderTarget0", ExpressionType::Float4); - auto color = Uniform("Color", ExpressionType::Float4); - - fragmentShader = writer.Generate(ExprStatement(Assign(rt0, color))); - }*/ - Nz::GlslWriter writer; - std::vector statements; + Nz::String glsl = writer.Generate(graph.Generate()); - std::function HandleNode; - HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr - { - ShaderNode* shaderNode = static_cast(node->nodeDataModel()); - - qDebug() << shaderNode->name(); - std::size_t inputCount = shaderNode->nPorts(QtNodes::PortType::In); - Nz::StackArray expressions = NazaraStackArray(Nz::ShaderAst::ExpressionPtr, inputCount); - std::size_t i = 0; - - for (const auto& connectionSet : node->nodeState().getEntries(QtNodes::PortType::In)) - { - for (const auto& [uuid, conn] : connectionSet) - { - assert(i < expressions.size()); - expressions[i] = HandleNode(conn->getNode(QtNodes::PortType::Out)); - i++; - } - } - - return shaderNode->GetExpression(expressions.data(), expressions.size()); - }; - - scene->iterateOverNodes([&](QtNodes::Node* node) - { - if (node->nodeDataModel()->nPorts(QtNodes::PortType::Out) == 0) - { - statements.emplace_back(Nz::ShaderBuilder::ExprStatement(HandleNode(node))); - //qDebug() << node->nodeDataModel()->name(); - } - }); - - Nz::String glsl = writer.Generate(std::make_shared(std::move(statements))); + std::cout << glsl << std::endl; QTextEdit* output = new QTextEdit; + output->setReadOnly(true); output->setText(QString::fromUtf8(glsl.GetConstBuffer(), glsl.GetSize())); output->setAttribute(Qt::WA_DeleteOnClose, true); output->setWindowTitle("GLSL Output"); output->show(); - - std::cout << glsl << std::endl; -} - -void SetupTestScene(QtNodes::FlowScene* scene) -{ - auto& node1 = scene->createNode(std::make_unique()); - node1.nodeGraphicsObject().setPos(200, 200); - - auto& node2 = scene->createNode(std::make_unique()); - node2.nodeGraphicsObject().setPos(500, 300); - - scene->createConnection(node2, 0, node1, 0); } int main(int argc, char* argv[]) { QApplication app(argc, argv); + ShaderGraph shaderGraph; + shaderGraph.AddTexture("TextureMachin", Nz::ShaderAst::ExpressionType::Sampler2D); + QWidget mainWindow; QVBoxLayout* layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - QtNodes::FlowScene* scene = new QtNodes::FlowScene(registerDataModels()); - SetupTestScene(scene); + QtNodes::FlowScene* scene = &shaderGraph.GetScene(); QMenuBar* menuBar = new QMenuBar; QAction* glslCode = menuBar->addAction("To GLSL"); - QObject::connect(glslCode, &QAction::triggered, [&](bool) { GenerateGLSL(scene); }); + QObject::connect(glslCode, &QAction::triggered, [&](bool) { GenerateGLSL(shaderGraph); }); layout->addWidget(new QtNodes::FlowView(scene)); layout->addWidget(menuBar);