Update ShaderNode
This commit is contained in:
parent
e23eb74802
commit
effaa9b88f
|
|
@ -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"; }
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
#include <DataModels/FragmentOutput.hpp>
|
||||
|
||||
inline FragmentOutput::FragmentOutput(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
#include <ShaderGraph.hpp>
|
||||
#include <DataModels/SampleTexture.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
|
||||
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<QtNodes::NodeData> SampleTexture::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
|
||||
return std::make_shared<Vec4Data>(Nz::Vector4f::Zero());
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_SAMPLETEXTURE_HPP
|
||||
#define NAZARA_SHADERNODES_SAMPLETEXTURE_HPP
|
||||
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <ShaderGraph.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <array>
|
||||
|
||||
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<QtNodes::NodeData> 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 <DataModels/SampleTexture.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#include <DataModels/SampleTexture.hpp>
|
||||
#include <array>
|
||||
|
|
@ -6,10 +6,21 @@
|
|||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <nodes/NodeDataModel>
|
||||
|
||||
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<QtNodes::NodeData>, int) override {};
|
||||
|
||||
private:
|
||||
ShaderGraph& m_graph;
|
||||
};
|
||||
|
||||
#include <DataModels/ShaderNode.inl>
|
||||
|
|
|
|||
|
|
@ -1 +1,16 @@
|
|||
#include <DataModels/ShaderNode.hpp>
|
||||
|
||||
inline ShaderNode::ShaderNode(ShaderGraph& graph) :
|
||||
m_graph(graph)
|
||||
{
|
||||
}
|
||||
|
||||
inline ShaderGraph& ShaderNode::GetGraph()
|
||||
{
|
||||
return m_graph;
|
||||
}
|
||||
|
||||
inline const ShaderGraph& ShaderNode::GetGraph() const
|
||||
{
|
||||
return m_graph;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
#include <DataModels/VecBinOp.hpp>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_VECBINOP_HPP
|
||||
#define NAZARA_SHADERNODES_VECBINOP_HPP
|
||||
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
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<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||
|
||||
private:
|
||||
void UpdatePreview();
|
||||
|
||||
using InternalType = typename Data::InternalType;
|
||||
|
||||
InternalType GetValue() const;
|
||||
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_preview;
|
||||
std::shared_ptr<Vec4Data> m_lhs;
|
||||
std::shared_ptr<Vec4Data> m_rhs;
|
||||
};
|
||||
|
||||
class Vec4Add : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Add>
|
||||
{
|
||||
public:
|
||||
using VecBinOp::VecBinOp;
|
||||
|
||||
QString caption() const override { return "Vec4 addition"; }
|
||||
QString name() const override { return "Vec4Add"; }
|
||||
};
|
||||
|
||||
class Vec4Mul : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Multiply>
|
||||
{
|
||||
public:
|
||||
using VecBinOp::VecBinOp;
|
||||
|
||||
QString caption() const override { return "Vec4 multiplication"; }
|
||||
QString name() const override { return "Vec4Mul"; }
|
||||
};
|
||||
|
||||
#include <DataModels/VecBinOp.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
#include <DataModels/VecBinOp.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
VecBinOp<Data, BinOp>::VecBinOp(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
m_preview = QPixmap(64, 64);
|
||||
|
||||
m_pixmapLabel = new QLabel;
|
||||
m_pixmapLabel->setPixmap(m_preview);
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
Nz::ShaderAst::ExpressionPtr VecBinOp<Data, BinOp>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||
{
|
||||
assert(count == 2);
|
||||
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
|
||||
constexpr BuilderType builder;
|
||||
return builder(expressions[0], expressions[1]);
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
QWidget* VecBinOp<Data, BinOp>::embeddedWidget()
|
||||
{
|
||||
return m_pixmapLabel;
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
QtNodes::NodeDataType VecBinOp<Data, BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
||||
{
|
||||
assert(portIndex == 0 || portIndex == 1);
|
||||
|
||||
return Data::Type();
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
unsigned int VecBinOp<Data, BinOp>::nPorts(QtNodes::PortType portType) const
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case QtNodes::PortType::In: return 2;
|
||||
case QtNodes::PortType::Out: return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
std::shared_ptr<QtNodes::NodeData> VecBinOp<Data, BinOp>::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
return std::make_shared<Data>(GetValue());
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
void VecBinOp<Data, BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||
{
|
||||
std::shared_ptr<Data> castedValue;
|
||||
if (value)
|
||||
{
|
||||
assert(dynamic_cast<Data*>(value.get()) != nullptr);
|
||||
assert(index == 0 || index == 1);
|
||||
|
||||
castedValue = std::static_pointer_cast<Data>(value);
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
m_lhs = std::move(castedValue);
|
||||
else
|
||||
m_rhs = std::move(castedValue);
|
||||
|
||||
UpdatePreview();
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
void VecBinOp<Data, BinOp>::UpdatePreview()
|
||||
{
|
||||
InternalType value = GetValue();
|
||||
m_preview.fill(QColor::fromRgbF(value.x, value.y, value.z, value.w));
|
||||
m_pixmapLabel->setPixmap(m_preview);
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
auto VecBinOp<Data, BinOp>::GetValue() const -> InternalType
|
||||
{
|
||||
if (!m_lhs || !m_rhs)
|
||||
return InternalType::Zero();
|
||||
|
||||
return m_lhs->value * m_rhs->value;
|
||||
}
|
||||
|
|
@ -1,6 +1,55 @@
|
|||
#include <DataModels/VecValue.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
|
||||
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<QtNodes::NodeData> Vec2Value::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
|
||||
return std::make_shared<Vec2Data>(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<QtNodes::NodeData> Vec4Value::outData(QtNodes::PortIndex port)
|
|||
return std::make_shared<Vec4Data>(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());
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <array>
|
||||
|
||||
|
|
@ -12,22 +13,50 @@ template<std::size_t N>
|
|||
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<QDoubleSpinBox*, N> 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<QtNodes::NodeData> 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<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData>, int) override {};
|
||||
|
||||
private:
|
||||
void ComputePreview(QPixmap& pixmap) const override;
|
||||
|
||||
Nz::Vector4f GetValue() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#include <array>
|
||||
|
||||
template<std::size_t N>
|
||||
VecValue<N>::VecValue()
|
||||
VecValue<N>::VecValue(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
constexpr std::array<char, 4> componentName = { 'X', 'Y', 'Z', 'W' };
|
||||
static_assert(N <= componentName.size());
|
||||
|
|
@ -11,10 +12,27 @@ VecValue<N>::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<double>(&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<N>::nPorts(QtNodes::PortType portType) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
Vec4Data::Vec4Data(const Nz::Vector4f& vec) :
|
||||
template<std::size_t N>
|
||||
void VecValue<N>::UpdatePreview()
|
||||
{
|
||||
ComputePreview(m_pixmap);
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
}
|
||||
|
||||
Vec2Data::Vec2Data(const InternalType& vec) :
|
||||
value(vec)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4Data::Vec4Data(const InternalType& vec) :
|
||||
value(vec)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
#include <ShaderGraph.hpp>
|
||||
#include <Nazara/Core/StackArray.hpp>
|
||||
#include <DataModels/FragmentOutput.hpp>
|
||||
#include <DataModels/SampleTexture.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecBinOp.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <QtCore/QDebug>
|
||||
#include <nodes/Node>
|
||||
#include <nodes/NodeData>
|
||||
#include <nodes/NodeGeometry>
|
||||
#include <nodes/FlowScene>
|
||||
#include <nodes/FlowView>
|
||||
#include <nodes/DataModelRegistry>
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
void RegisterShaderNode(ShaderGraph& graph, std::shared_ptr<QtNodes::DataModelRegistry> registry)
|
||||
{
|
||||
auto creator = [&] { return std::make_unique<T>(graph); };
|
||||
registry->registerModel<T>(std::move(creator));
|
||||
}
|
||||
}
|
||||
|
||||
ShaderGraph::ShaderGraph() :
|
||||
m_flowScene(BuildRegistry())
|
||||
{
|
||||
auto& node1 = m_flowScene.createNode(std::make_unique<Vec4Value>(*this));
|
||||
node1.nodeGraphicsObject().setPos(200, 200);
|
||||
|
||||
auto& node2 = m_flowScene.createNode(std::make_unique<FragmentOutput>(*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<Nz::ShaderAst::StatementPtr> statements;
|
||||
|
||||
std::function<Nz::ShaderAst::ExpressionPtr(QtNodes::Node*)> HandleNode;
|
||||
HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr
|
||||
{
|
||||
ShaderNode* shaderNode = static_cast<ShaderNode*>(node->nodeDataModel());
|
||||
|
||||
qDebug() << shaderNode->name();
|
||||
std::size_t inputCount = shaderNode->nPorts(QtNodes::PortType::In);
|
||||
Nz::StackArray<Nz::ShaderAst::ExpressionPtr> 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<Nz::ShaderAst::StatementBlock>(std::move(statements));
|
||||
}
|
||||
|
||||
std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
||||
{
|
||||
auto registry = std::make_shared<QtNodes::DataModelRegistry>();
|
||||
RegisterShaderNode<FragmentOutput>(*this, registry);
|
||||
RegisterShaderNode<SampleTexture>(*this, registry);
|
||||
RegisterShaderNode<Vec4Mul>(*this, registry);
|
||||
RegisterShaderNode<Vec2Value>(*this, registry);
|
||||
RegisterShaderNode<Vec4Value>(*this, registry);
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_SHADERGRAPH_HPP
|
||||
#define NAZARA_SHADERNODES_SHADERGRAPH_HPP
|
||||
|
||||
#include <Nazara/Core/Signal.hpp>
|
||||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <nodes/FlowScene>
|
||||
#include <nodes/FlowView>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<TextureEntry>& GetTextures();
|
||||
|
||||
NazaraSignal(OnTextureListUpdate, ShaderGraph*);
|
||||
|
||||
struct TextureEntry
|
||||
{
|
||||
std::string name;
|
||||
Nz::ShaderAst::ExpressionType type;
|
||||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<QtNodes::DataModelRegistry> BuildRegistry();
|
||||
|
||||
QtNodes::FlowScene m_flowScene;
|
||||
std::vector<TextureEntry> m_textures;
|
||||
};
|
||||
|
||||
#include <ShaderGraph.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include <ShaderGraph.hpp>
|
||||
|
||||
inline QtNodes::FlowScene& ShaderGraph::GetScene()
|
||||
{
|
||||
return m_flowScene;
|
||||
}
|
||||
|
||||
inline auto ShaderGraph::GetTextures() -> const std::vector<TextureEntry>&
|
||||
{
|
||||
return m_textures;
|
||||
}
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
#include <Nazara/Core/StackArray.hpp>
|
||||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <Nazara/Renderer/GlslWriter.hpp>
|
||||
#include <DataModels/FragmentOutput.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMenuBar>
|
||||
|
|
@ -17,103 +13,41 @@
|
|||
#include <nodes/FlowScene>
|
||||
#include <nodes/FlowView>
|
||||
#include <nodes/DataModelRegistry>
|
||||
#include <ShaderGraph.hpp>
|
||||
#include <iostream>
|
||||
|
||||
std::shared_ptr<QtNodes::DataModelRegistry> registerDataModels()
|
||||
void GenerateGLSL(ShaderGraph& graph)
|
||||
{
|
||||
auto ret = std::make_shared<QtNodes::DataModelRegistry>();
|
||||
ret->registerModel<FragmentOutput>();
|
||||
ret->registerModel<Vec4Value>();
|
||||
|
||||
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<Nz::ShaderAst::StatementPtr> statements;
|
||||
Nz::String glsl = writer.Generate(graph.Generate());
|
||||
|
||||
std::function<Nz::ShaderAst::ExpressionPtr(QtNodes::Node*)> HandleNode;
|
||||
HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr
|
||||
{
|
||||
ShaderNode* shaderNode = static_cast<ShaderNode*>(node->nodeDataModel());
|
||||
|
||||
qDebug() << shaderNode->name();
|
||||
std::size_t inputCount = shaderNode->nPorts(QtNodes::PortType::In);
|
||||
Nz::StackArray<Nz::ShaderAst::ExpressionPtr> 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<Nz::ShaderAst::StatementBlock>(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<Vec4Value>());
|
||||
node1.nodeGraphicsObject().setPos(200, 200);
|
||||
|
||||
auto& node2 = scene->createNode(std::make_unique<FragmentOutput>());
|
||||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue