ShaderNode: Add texture support
This commit is contained in:
@@ -4,12 +4,21 @@
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
|
||||
SampleTexture::SampleTexture(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
ShaderNode(graph),
|
||||
m_currentTextureIndex(0)
|
||||
{
|
||||
m_layout = new QVBoxLayout;
|
||||
|
||||
m_textureSelection = new QComboBox;
|
||||
m_textureSelection->setStyleSheet("background-color: rgba(255,255,255,255)");
|
||||
connect(m_textureSelection, qOverload<int>(&QComboBox::currentIndexChanged), [&](int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
m_currentTextureIndex = static_cast<std::size_t>(index);
|
||||
UpdatePreview();
|
||||
});
|
||||
|
||||
m_layout->addWidget(m_textureSelection);
|
||||
|
||||
@@ -25,8 +34,15 @@ ShaderNode(graph)
|
||||
m_widget->setStyleSheet("background-color: rgba(0,0,0,0)");
|
||||
m_widget->setLayout(m_layout);
|
||||
|
||||
m_onTextureListUpdate.Connect(GetGraph().OnTextureListUpdate, [&](ShaderGraph*) { UpdateTextureList(); });
|
||||
m_onTextureListUpdateSlot.Connect(GetGraph().OnTextureListUpdate, [&](ShaderGraph*) { UpdateTextureList(); });
|
||||
m_onTexturePreviewUpdateSlot.Connect(GetGraph().OnTexturePreviewUpdate, [&](ShaderGraph*, std::size_t textureIndex)
|
||||
{
|
||||
if (m_currentTextureIndex == textureIndex)
|
||||
UpdatePreview();
|
||||
});
|
||||
|
||||
UpdateTextureList();
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
QWidget* SampleTexture::embeddedWidget()
|
||||
@@ -47,8 +63,13 @@ unsigned int SampleTexture::nPorts(QtNodes::PortType portType) const
|
||||
|
||||
void SampleTexture::UpdatePreview()
|
||||
{
|
||||
if (m_textureSelection->count() == 0)
|
||||
return;
|
||||
|
||||
ComputePreview(m_pixmap);
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
|
||||
void SampleTexture::UpdateTextureList()
|
||||
@@ -64,7 +85,9 @@ void SampleTexture::UpdateTextureList()
|
||||
|
||||
void SampleTexture::ComputePreview(QPixmap& pixmap) const
|
||||
{
|
||||
pixmap.fill();
|
||||
const auto& textureEntry = GetGraph().GetTexture(m_currentTextureIndex);
|
||||
|
||||
pixmap = QPixmap::fromImage(textureEntry.preview).scaled(128, 128, Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||
@@ -102,5 +125,10 @@ std::shared_ptr<QtNodes::NodeData> SampleTexture::outData(QtNodes::PortIndex por
|
||||
{
|
||||
assert(port == 0);
|
||||
|
||||
return std::make_shared<Vec4Data>(Nz::Vector4f::Zero());
|
||||
const auto& textureEntry = GetGraph().GetTexture(m_currentTextureIndex);
|
||||
|
||||
auto vecData = std::make_shared<Vec4Data>();
|
||||
vecData->preview = textureEntry.preview;
|
||||
|
||||
return vecData;
|
||||
}
|
||||
|
||||
@@ -28,13 +28,14 @@ class SampleTexture : public ShaderNode
|
||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
protected:
|
||||
void ComputePreview(QPixmap& pixmap) const;
|
||||
void UpdatePreview();
|
||||
void UpdateTextureList();
|
||||
|
||||
void ComputePreview(QPixmap& pixmap) const;
|
||||
|
||||
NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdate);
|
||||
NazaraSlot(ShaderGraph, OnTextureListUpdate, m_onTextureListUpdateSlot);
|
||||
NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot);
|
||||
|
||||
std::size_t m_currentTextureIndex;
|
||||
QComboBox* m_textureSelection;
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_pixmap;
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
|
||||
void ShaderNode::setInData(std::shared_ptr<QtNodes::NodeData>, int)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class ShaderNode : public QtNodes::NodeDataModel
|
||||
inline ShaderGraph& GetGraph();
|
||||
inline const ShaderGraph& GetGraph() const;
|
||||
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData>, int) override {};
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData>, int) override;
|
||||
|
||||
private:
|
||||
ShaderGraph& m_graph;
|
||||
|
||||
@@ -1 +1,23 @@
|
||||
#include <DataModels/VecBinOp.hpp>
|
||||
|
||||
void Vec4Add::ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount)
|
||||
{
|
||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||
{
|
||||
unsigned int lValue = left[i];
|
||||
unsigned int rValue = right[i];
|
||||
|
||||
output[i] = static_cast<std::uint8_t>(std::min(lValue + rValue, 255U));
|
||||
}
|
||||
}
|
||||
|
||||
void Vec4Mul::ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount)
|
||||
{
|
||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||
{
|
||||
unsigned int lValue = left[i];
|
||||
unsigned int rValue = right[i];
|
||||
|
||||
output[i] = static_cast<std::uint8_t>(lValue * rValue / 255);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,16 +25,14 @@ class VecBinOp : public ShaderNode
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||
|
||||
private:
|
||||
virtual void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) = 0;
|
||||
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;
|
||||
std::shared_ptr<Vec4Data> m_output;
|
||||
};
|
||||
|
||||
class Vec4Add : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Add>
|
||||
@@ -44,6 +42,8 @@ class Vec4Add : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Add>
|
||||
|
||||
QString caption() const override { return "Vec4 addition"; }
|
||||
QString name() const override { return "Vec4Add"; }
|
||||
|
||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) override;
|
||||
};
|
||||
|
||||
class Vec4Mul : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Multiply>
|
||||
@@ -53,6 +53,8 @@ class Vec4Mul : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Multiply>
|
||||
|
||||
QString caption() const override { return "Vec4 multiplication"; }
|
||||
QString name() const override { return "Vec4Mul"; }
|
||||
|
||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) override;
|
||||
};
|
||||
|
||||
#include <DataModels/VecBinOp.inl>
|
||||
|
||||
@@ -5,10 +5,11 @@ template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
VecBinOp<Data, BinOp>::VecBinOp(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
m_preview = QPixmap(64, 64);
|
||||
m_output = std::make_shared<Data>();
|
||||
|
||||
m_pixmapLabel = new QLabel;
|
||||
m_pixmapLabel->setPixmap(m_preview);
|
||||
m_pixmapLabel->setStyleSheet("background-color: rgba(0,0,0,0)");
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
@@ -39,7 +40,7 @@ unsigned int VecBinOp<Data, BinOp>::nPorts(QtNodes::PortType portType) const
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case QtNodes::PortType::In: return 2;
|
||||
case QtNodes::PortType::In: return 2;
|
||||
case QtNodes::PortType::Out: return 1;
|
||||
}
|
||||
|
||||
@@ -50,17 +51,18 @@ 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());
|
||||
return m_output;
|
||||
}
|
||||
|
||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
||||
void VecBinOp<Data, BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||
{
|
||||
assert(index == 0 || index == 1);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -78,16 +80,36 @@ void VecBinOp<Data, BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value,
|
||||
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));
|
||||
if (m_lhs && m_rhs)
|
||||
{
|
||||
const QImage& leftPreview = m_lhs->preview;
|
||||
const QImage& rightPreview = m_rhs->preview;
|
||||
int maxWidth = std::max(leftPreview.width(), rightPreview.width());
|
||||
int maxHeight = std::max(leftPreview.height(), rightPreview.height());
|
||||
|
||||
// Exploit COW
|
||||
QImage leftResized = leftPreview;
|
||||
if (leftResized.width() != maxWidth || leftResized.height() != maxHeight)
|
||||
leftResized = leftResized.scaled(maxWidth, maxHeight);
|
||||
|
||||
QImage rightResized = rightPreview;
|
||||
if (rightResized.width() != maxWidth || rightResized.height() != maxHeight)
|
||||
rightResized = rightResized.scaled(maxWidth, maxHeight);
|
||||
|
||||
int w = m_output->preview.width();
|
||||
int h = m_output->preview.height();
|
||||
|
||||
m_output->preview = QImage(maxWidth, maxHeight, QImage::Format_RGBA8888);
|
||||
ApplyOp(leftResized.constBits(), rightResized.constBits(), m_output->preview.bits(), maxWidth * maxHeight * 4);
|
||||
m_output->preview = m_output->preview.scaled(w, h);
|
||||
|
||||
m_preview = QPixmap::fromImage(m_output->preview, Qt::AutoColor | Qt::NoOpaqueDetection);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_preview = QPixmap(64, 64);
|
||||
m_preview.fill(QColor::fromRgb(255, 255, 0, 0));
|
||||
}
|
||||
|
||||
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,89 +1 @@
|
||||
#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);
|
||||
|
||||
return Nz::ShaderBuilder::Constant(GetValue());
|
||||
}
|
||||
|
||||
auto Vec4Value::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType
|
||||
{
|
||||
assert(portType == QtNodes::PortType::Out);
|
||||
assert(portIndex == 0);
|
||||
|
||||
return Vec4Data::Type();
|
||||
}
|
||||
|
||||
std::shared_ptr<QtNodes::NodeData> Vec4Value::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
|
||||
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());
|
||||
float y = float(m_values[1]->value());
|
||||
float z = float(m_values[2]->value());
|
||||
float w = float(m_values[3]->value());
|
||||
|
||||
return Nz::Vector4f(x, y, z, w);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef NAZARA_SHADERNODES_VECVALUE_HPP
|
||||
#define NAZARA_SHADERNODES_VECVALUE_HPP
|
||||
|
||||
#include <QtGui/QImage>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
@@ -10,105 +11,105 @@
|
||||
#include <array>
|
||||
|
||||
template<std::size_t N>
|
||||
struct VecTypeHelper;
|
||||
|
||||
template<>
|
||||
struct VecTypeHelper<2>
|
||||
{
|
||||
using Type = Nz::Vector2f;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct VecTypeHelper<3>
|
||||
{
|
||||
using Type = Nz::Vector3f;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct VecTypeHelper<4>
|
||||
{
|
||||
using Type = Nz::Vector4f;
|
||||
};
|
||||
|
||||
template<std::size_t N> using VecType = typename VecTypeHelper<N>::template Type;
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
class VecValue : public ShaderNode
|
||||
{
|
||||
public:
|
||||
VecValue(ShaderGraph& graph);
|
||||
~VecValue() = default;
|
||||
|
||||
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||
|
||||
QWidget* embeddedWidget() override;
|
||||
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||
|
||||
protected:
|
||||
void UpdatePreview();
|
||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
virtual void ComputePreview(QPixmap& pixmap) const = 0;
|
||||
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override;
|
||||
|
||||
protected:
|
||||
QColor ToColor() const;
|
||||
VecType<N> ToVector() const;
|
||||
void UpdatePreview();
|
||||
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_pixmap;
|
||||
QWidget* m_widget;
|
||||
QFormLayout* m_layout;
|
||||
std::array<QDoubleSpinBox*, N> m_values;
|
||||
std::array<QDoubleSpinBox*, N> m_spinboxes;
|
||||
};
|
||||
|
||||
class Vec2Data : public QtNodes::NodeData
|
||||
struct VecData : public QtNodes::NodeData
|
||||
{
|
||||
public:
|
||||
using InternalType = Nz::Vector2f;
|
||||
inline VecData();
|
||||
|
||||
inline Vec2Data(const InternalType& vec);
|
||||
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec2", "Vec2" };
|
||||
}
|
||||
|
||||
InternalType value;
|
||||
QImage preview;
|
||||
};
|
||||
|
||||
class Vec4Data : public QtNodes::NodeData
|
||||
struct Vec2Data : public VecData
|
||||
{
|
||||
public:
|
||||
using InternalType = Nz::Vector4f;
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
inline Vec4Data(const InternalType& vec);
|
||||
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec4", "Vec4" };
|
||||
}
|
||||
|
||||
InternalType value;
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec2", "Vec2" };
|
||||
}
|
||||
};
|
||||
|
||||
class Vec2Value : public VecValue<2>
|
||||
struct Vec4Data : public VecData
|
||||
{
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec4", "Vec4" };
|
||||
}
|
||||
};
|
||||
|
||||
class Vec2Value : public VecValue<2, Vec2Data>
|
||||
{
|
||||
public:
|
||||
Vec2Value(ShaderGraph& graph);
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override;
|
||||
using VecValue::VecValue;
|
||||
|
||||
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>
|
||||
class Vec4Value : public VecValue<4, Vec4Data>
|
||||
{
|
||||
public:
|
||||
Vec4Value(ShaderGraph& graph);
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override;
|
||||
using VecValue::VecValue;
|
||||
|
||||
QString caption() const override { return "Vec4 value"; }
|
||||
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;
|
||||
|
||||
private:
|
||||
void ComputePreview(QPixmap& pixmap) const override;
|
||||
|
||||
Nz::Vector4f GetValue() const;
|
||||
};
|
||||
|
||||
#include <DataModels/VecValue.inl>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <array>
|
||||
|
||||
template<std::size_t N>
|
||||
VecValue<N>::VecValue(ShaderGraph& graph) :
|
||||
template<std::size_t N, typename Data>
|
||||
VecValue<N, Data>::VecValue(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
constexpr std::array<char, 4> componentName = { 'X', 'Y', 'Z', 'W' };
|
||||
@@ -11,21 +13,21 @@ ShaderNode(graph)
|
||||
m_layout = new QFormLayout;
|
||||
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)
|
||||
m_spinboxes[i] = new QDoubleSpinBox;
|
||||
m_spinboxes[i]->setDecimals(6);
|
||||
m_spinboxes[i]->setValue(1.0);
|
||||
m_spinboxes[i]->setStyleSheet("background-color: rgba(255,255,255,255)");
|
||||
connect(m_spinboxes[i], qOverload<double>(&QDoubleSpinBox::valueChanged), [this](double)
|
||||
{
|
||||
UpdatePreview();
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
});
|
||||
|
||||
m_layout->addRow(QString::fromUtf8(&componentName[i], 1), m_values[i]);
|
||||
m_layout->addRow(QString::fromUtf8(&componentName[i], 1), m_spinboxes[i]);
|
||||
}
|
||||
|
||||
m_pixmap = QPixmap(64, 64);
|
||||
m_pixmap = QPixmap(32, 32);
|
||||
m_pixmap.fill();
|
||||
|
||||
m_pixmapLabel = new QLabel;
|
||||
@@ -36,16 +38,27 @@ ShaderNode(graph)
|
||||
m_widget = new QWidget;
|
||||
m_widget->setStyleSheet("background-color: rgba(0,0,0,0)");
|
||||
m_widget->setLayout(m_layout);
|
||||
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
QWidget* VecValue<N>::embeddedWidget()
|
||||
template<std::size_t N, typename Data>
|
||||
QtNodes::NodeDataType VecValue<N, Data>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||
{
|
||||
assert(portType == QtNodes::PortType::Out);
|
||||
assert(portIndex == 0);
|
||||
|
||||
return Data::Type();
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
QWidget* VecValue<N, Data>::embeddedWidget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
unsigned int VecValue<N>::nPorts(QtNodes::PortType portType) const
|
||||
template<std::size_t N, typename Data>
|
||||
unsigned int VecValue<N, Data>::nPorts(QtNodes::PortType portType) const
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
@@ -56,19 +69,64 @@ unsigned int VecValue<N>::nPorts(QtNodes::PortType portType) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void VecValue<N>::UpdatePreview()
|
||||
template<std::size_t N, typename Data>
|
||||
std::shared_ptr<QtNodes::NodeData> VecValue<N, Data>::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
ComputePreview(m_pixmap);
|
||||
assert(port == 0);
|
||||
|
||||
auto out = std::make_shared<Data>();
|
||||
out->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
||||
out->preview.fill(ToColor());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
Nz::ShaderAst::ExpressionPtr VecValue<N, Data>::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
||||
{
|
||||
assert(count == 0);
|
||||
|
||||
return Nz::ShaderBuilder::Constant(ToVector());
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
QColor VecValue<N, Data>::ToColor() const
|
||||
{
|
||||
std::array<float, 4> values = { 0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
values[i] = std::clamp<float>(m_spinboxes[i]->value(), 0.0, 1.0);
|
||||
|
||||
return QColor::fromRgbF(values[0], values[1], values[2], values[3]);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
VecType<N> VecValue<N, Data>::ToVector() const
|
||||
{
|
||||
std::array<float, 4> values = { 0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
values[i] = std::clamp<float>(m_spinboxes[i]->value(), 0.0, 1.0);
|
||||
|
||||
if constexpr (N == 2)
|
||||
return Nz::Vector2f(values[0], values[1]);
|
||||
else if constexpr (N == 3)
|
||||
return Nz::Vector3f(values[0], values[1], values[2]);
|
||||
else if constexpr (N == 4)
|
||||
return Nz::Vector4f(values[0], values[1], values[2], values[3]);
|
||||
else
|
||||
static_assert(Nz::AlwaysFalse<std::make_integer_sequence<int, N>>(), "Unhandled vector size");
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
void VecValue<N, Data>::UpdatePreview()
|
||||
{
|
||||
m_pixmap.fill(ToColor());
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
}
|
||||
|
||||
Vec2Data::Vec2Data(const InternalType& vec) :
|
||||
value(vec)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4Data::Vec4Data(const InternalType& vec) :
|
||||
value(vec)
|
||||
inline VecData::VecData() :
|
||||
preview(64, 64, QImage::Format_RGBA8888)
|
||||
{
|
||||
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user