ShaderNode: Add preview / cast / texture sampling
This commit is contained in:
parent
206724c911
commit
93e76a17c7
|
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_CAST_HPP
|
||||
#define NAZARA_SHADERNODES_CAST_HPP
|
||||
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <ShaderGraph.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <array>
|
||||
|
||||
template<typename From, typename To>
|
||||
class CastVec : public ShaderNode
|
||||
{
|
||||
public:
|
||||
CastVec(ShaderGraph& graph);
|
||||
~CastVec() = default;
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override;
|
||||
|
||||
QString caption() const override;
|
||||
QString name() const override;
|
||||
|
||||
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||
QWidget* embeddedWidget() override;
|
||||
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||
|
||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||
|
||||
private:
|
||||
static constexpr std::size_t FromComponents = From::ComponentCount;
|
||||
static constexpr std::size_t ToComponents = To::ComponentCount;
|
||||
static constexpr std::size_t ComponentDiff = (ToComponents >= FromComponents) ? ToComponents - FromComponents : 0;
|
||||
|
||||
void ComputePreview(QPixmap& pixmap) const;
|
||||
void UpdatePreview();
|
||||
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_pixmap;
|
||||
QWidget* m_widget;
|
||||
std::array<QDoubleSpinBox*, ComponentDiff> m_spinboxes;
|
||||
std::shared_ptr<From> m_input;
|
||||
std::shared_ptr<To> m_output;
|
||||
};
|
||||
|
||||
using CastVec2ToVec3 = CastVec<Vec2Data, Vec3Data>;
|
||||
using CastVec2ToVec4 = CastVec<Vec2Data, Vec4Data>;
|
||||
using CastVec3ToVec2 = CastVec<Vec3Data, Vec2Data>;
|
||||
using CastVec3ToVec4 = CastVec<Vec3Data, Vec4Data>;
|
||||
using CastVec4ToVec2 = CastVec<Vec4Data, Vec2Data>;
|
||||
using CastVec4ToVec3 = CastVec<Vec4Data, Vec3Data>;
|
||||
|
||||
#include <DataModels/Cast.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
#include <DataModels/Cast.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
template<typename From, typename To>
|
||||
CastVec<From, To>::CastVec(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
constexpr std::array<char, 4> componentName = { 'X', 'Y', 'Z', 'W' };
|
||||
static_assert(ComponentDiff <= componentName.size());
|
||||
|
||||
QFormLayout* layout = new QFormLayout;
|
||||
|
||||
if constexpr (ComponentDiff > 0)
|
||||
{
|
||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
||||
{
|
||||
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();
|
||||
});
|
||||
|
||||
layout->addRow(QString::fromUtf8(&componentName[FromComponents + i], 1), m_spinboxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_pixmap = QPixmap(64, 64);
|
||||
m_pixmap.fill();
|
||||
|
||||
m_pixmapLabel = new QLabel;
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
|
||||
layout->addWidget(m_pixmapLabel);
|
||||
|
||||
m_widget = new QWidget;
|
||||
m_widget->setStyleSheet("background-color: rgba(0,0,0,0)");
|
||||
m_widget->setLayout(layout);
|
||||
|
||||
m_output = std::make_shared<To>();
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
Nz::ShaderAst::ExpressionPtr CastVec<From, To>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||
{
|
||||
assert(count == 1);
|
||||
|
||||
if constexpr (ComponentDiff > 0)
|
||||
{
|
||||
std::array<Nz::ShaderAst::ExpressionPtr, ComponentDiff> constants;
|
||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
||||
constants[i] = Nz::ShaderBuilder::Constant(float(m_spinboxes[i]->value()));
|
||||
|
||||
return std::apply([&](auto&&... values)
|
||||
{
|
||||
return Nz::ShaderBuilder::Cast<To::ExpressionType>(expressions[0], values...); //< TODO: Forward
|
||||
}, constants);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::array<Nz::ShaderAst::SwizzleComponent, ToComponents> swizzleComponents;
|
||||
for (std::size_t i = 0; i < ToComponents; ++i)
|
||||
swizzleComponents[i] = static_cast<Nz::ShaderAst::SwizzleComponent>(static_cast<std::size_t>(Nz::ShaderAst::SwizzleComponent::First) + i);
|
||||
|
||||
return std::apply([&](auto... components)
|
||||
{
|
||||
std::initializer_list<Nz::ShaderAst::SwizzleComponent> componentList{ components... };
|
||||
return Nz::ShaderBuilder::Swizzle(expressions[0], componentList);
|
||||
}, swizzleComponents);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
QString CastVec<From, To>::caption() const
|
||||
{
|
||||
static QString caption = From::Type().name + " to " + To::Type().name;
|
||||
return caption;
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
QString CastVec<From, To>::name() const
|
||||
{
|
||||
static QString name = From::Type().id + "to" + To::Type().id;
|
||||
return name;
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
QtNodes::NodeDataType CastVec<From, To>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||
{
|
||||
assert(portIndex == 0);
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case QtNodes::PortType::In: return From::Type();
|
||||
case QtNodes::PortType::Out: return To::Type();
|
||||
}
|
||||
|
||||
assert(false);
|
||||
throw std::runtime_error("Invalid port type");
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
QWidget* CastVec<From, To>::embeddedWidget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
unsigned int CastVec<From, To>::nPorts(QtNodes::PortType portType) const
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case QtNodes::PortType::In: return 1;
|
||||
case QtNodes::PortType::Out: return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
std::shared_ptr<QtNodes::NodeData> CastVec<From, To>::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
return m_output;
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
void CastVec<From, To>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||
{
|
||||
assert(index == 0);
|
||||
if (value)
|
||||
{
|
||||
assert(dynamic_cast<From*>(value.get()) != nullptr);
|
||||
m_input = std::static_pointer_cast<From>(value);
|
||||
}
|
||||
else
|
||||
m_input.reset();
|
||||
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
void CastVec<From, To>::ComputePreview(QPixmap& pixmap) const
|
||||
{
|
||||
assert(m_input);
|
||||
|
||||
const QImage& input = m_input->preview;
|
||||
|
||||
int inputWidth = input.width();
|
||||
int inputHeight = input.height();
|
||||
|
||||
QImage& output = m_output->preview;
|
||||
output = QImage(inputWidth, inputHeight, QImage::Format_RGBA8888);
|
||||
|
||||
std::array<std::uint8_t, ComponentDiff> constants;
|
||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
||||
constants[i] = static_cast<std::uint8_t>(std::clamp(int(m_spinboxes[i]->value() * 255), 0, 255));
|
||||
|
||||
std::uint8_t* outputPtr = output.bits();
|
||||
const std::uint8_t* inputPtr = input.constBits();
|
||||
for (int y = 0; y < inputHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < inputWidth; ++x)
|
||||
{
|
||||
constexpr std::size_t CommonComponents = std::min(FromComponents, ToComponents);
|
||||
constexpr std::size_t VoidComponents = 4 - ComponentDiff - CommonComponents;
|
||||
|
||||
for (std::size_t i = 0; i < CommonComponents; ++i)
|
||||
*outputPtr++ = inputPtr[i];
|
||||
|
||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
||||
*outputPtr++ = constants[i];
|
||||
|
||||
for (std::size_t i = 0; i < VoidComponents; ++i)
|
||||
*outputPtr++ = (i == VoidComponents - 1) ? 255 : 0;
|
||||
|
||||
inputPtr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pixmap = QPixmap::fromImage(output).scaled(64, 64);
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
void CastVec<From, To>::UpdatePreview()
|
||||
{
|
||||
if (!m_input)
|
||||
{
|
||||
m_pixmap = QPixmap(64, 64);
|
||||
m_pixmap.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||
}
|
||||
else
|
||||
ComputePreview(m_pixmap);
|
||||
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
|
|
@ -62,6 +62,12 @@ void InputValue::UpdatePreview()
|
|||
if (m_inputSelection->count() == 0)
|
||||
return;
|
||||
|
||||
const ShaderGraph& graph = GetGraph();
|
||||
const auto& inputEntry = graph.GetInput(m_currentInputIndex);
|
||||
const auto& preview = graph.GetPreviewModel();
|
||||
|
||||
m_previewLabel->setPixmap(QPixmap::fromImage(preview.GetImage(inputEntry.role, inputEntry.roleIndex)));
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +82,7 @@ void InputValue::UpdateInputList()
|
|||
m_inputSelection->setCurrentText(currentInput);
|
||||
}
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr InputValue::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||
Nz::ShaderAst::ExpressionPtr InputValue::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
||||
{
|
||||
assert(count == 0);
|
||||
|
||||
|
|
@ -111,7 +117,7 @@ auto InputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portInd
|
|||
//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::Float3: return Vec3Data::Type();
|
||||
case InputType::Float4: return Vec4Data::Type();
|
||||
}
|
||||
|
||||
|
|
@ -123,10 +129,12 @@ std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
|
|||
{
|
||||
assert(port == 0);
|
||||
|
||||
const auto& inputEntry = GetGraph().GetInput(m_currentInputIndex);
|
||||
const ShaderGraph& graph = GetGraph();
|
||||
const auto& inputEntry = graph.GetInput(m_currentInputIndex);
|
||||
const auto& preview = graph.GetPreviewModel();
|
||||
|
||||
auto vecData = std::make_shared<Vec4Data>();
|
||||
vecData->preview = QImage();
|
||||
auto vecData = std::make_shared<Vec2Data>();
|
||||
vecData->preview = preview.GetImage(inputEntry.role, inputEntry.roleIndex);
|
||||
|
||||
return vecData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ SampleTexture::SampleTexture(ShaderGraph& graph) :
|
|||
ShaderNode(graph),
|
||||
m_currentTextureIndex(0)
|
||||
{
|
||||
m_output = std::make_shared<Vec4Data>();
|
||||
|
||||
m_layout = new QVBoxLayout;
|
||||
|
||||
m_textureSelection = new QComboBox;
|
||||
|
|
@ -85,9 +87,45 @@ void SampleTexture::UpdateTextureList()
|
|||
|
||||
void SampleTexture::ComputePreview(QPixmap& pixmap) const
|
||||
{
|
||||
if (!m_uv)
|
||||
return;
|
||||
|
||||
const auto& textureEntry = GetGraph().GetTexture(m_currentTextureIndex);
|
||||
|
||||
pixmap = QPixmap::fromImage(textureEntry.preview).scaled(128, 128, Qt::KeepAspectRatio);
|
||||
int textureWidth = textureEntry.preview.width();
|
||||
int textureHeight = textureEntry.preview.height();
|
||||
|
||||
QImage& output = m_output->preview;
|
||||
const QImage& uv = m_uv->preview;
|
||||
|
||||
int uvWidth = uv.width();
|
||||
int uvHeight = uv.height();
|
||||
|
||||
output = QImage(uvWidth, uvHeight, QImage::Format_RGBA8888);
|
||||
|
||||
std::uint8_t* outputPtr = output.bits();
|
||||
const std::uint8_t* uvPtr = uv.constBits();
|
||||
const std::uint8_t* texturePtr = textureEntry.preview.constBits();
|
||||
for (int y = 0; y < uvHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < uvWidth; ++x)
|
||||
{
|
||||
float u = float(uvPtr[0]) / 255;
|
||||
float v = float(uvPtr[1]) / 255;
|
||||
|
||||
int texX = std::clamp(int(u * textureWidth), 0, textureWidth - 1);
|
||||
int texY = std::clamp(int(v * textureHeight), 0, textureHeight - 1);
|
||||
int texPixel = (texY * textureWidth + texX) * 4;
|
||||
|
||||
*outputPtr++ = texturePtr[texPixel + 0];
|
||||
*outputPtr++ = texturePtr[texPixel + 1];
|
||||
*outputPtr++ = texturePtr[texPixel + 2];
|
||||
*outputPtr++ = texturePtr[texPixel + 3];
|
||||
uvPtr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pixmap = QPixmap::fromImage(output).scaled(128, 128, Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||
|
|
@ -156,7 +194,7 @@ QString SampleTexture::portCaption(QtNodes::PortType portType, QtNodes::PortInde
|
|||
}
|
||||
}
|
||||
|
||||
bool SampleTexture::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||
bool SampleTexture::portCaptionVisible(QtNodes::PortType /*portType*/, QtNodes::PortIndex /*portIndex*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -165,10 +203,21 @@ std::shared_ptr<QtNodes::NodeData> SampleTexture::outData(QtNodes::PortIndex por
|
|||
{
|
||||
assert(port == 0);
|
||||
|
||||
const auto& textureEntry = GetGraph().GetTexture(m_currentTextureIndex);
|
||||
|
||||
auto vecData = std::make_shared<Vec4Data>();
|
||||
vecData->preview = textureEntry.preview;
|
||||
|
||||
return vecData;
|
||||
return m_output;
|
||||
}
|
||||
|
||||
void SampleTexture::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||
{
|
||||
assert(index == 0);
|
||||
|
||||
if (value)
|
||||
{
|
||||
assert(dynamic_cast<Vec2Data*>(value.get()) != nullptr);
|
||||
|
||||
m_uv = std::static_pointer_cast<Vec2Data>(value);
|
||||
}
|
||||
else
|
||||
m_uv.reset();
|
||||
|
||||
UpdatePreview();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QtWidgets/QLabel>
|
||||
#include <ShaderGraph.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <array>
|
||||
|
||||
class SampleTexture : public ShaderNode
|
||||
|
|
@ -32,6 +33,8 @@ class SampleTexture : public ShaderNode
|
|||
|
||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||
|
||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||
|
||||
protected:
|
||||
void ComputePreview(QPixmap& pixmap) const;
|
||||
void UpdatePreview();
|
||||
|
|
@ -41,6 +44,8 @@ class SampleTexture : public ShaderNode
|
|||
NazaraSlot(ShaderGraph, OnTexturePreviewUpdate, m_onTexturePreviewUpdateSlot);
|
||||
|
||||
std::size_t m_currentTextureIndex;
|
||||
std::shared_ptr<Vec2Data> m_uv;
|
||||
std::shared_ptr<Vec4Data> m_output;
|
||||
QComboBox* m_textureSelection;
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_pixmap;
|
||||
|
|
|
|||
|
|
@ -1,23 +1 @@
|
|||
#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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,33 +30,59 @@ class VecBinOp : public ShaderNode
|
|||
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_preview;
|
||||
std::shared_ptr<Vec4Data> m_lhs;
|
||||
std::shared_ptr<Vec4Data> m_rhs;
|
||||
std::shared_ptr<Vec4Data> m_output;
|
||||
std::shared_ptr<Data> m_lhs;
|
||||
std::shared_ptr<Data> m_rhs;
|
||||
std::shared_ptr<Data> m_output;
|
||||
};
|
||||
|
||||
class Vec4Add : public VecBinOp<Vec4Data, Nz::ShaderAst::BinaryType::Add>
|
||||
template<typename Data>
|
||||
class VecAdd : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Add>
|
||||
{
|
||||
public:
|
||||
using VecBinOp::VecBinOp;
|
||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Add>::VecBinOp;
|
||||
|
||||
QString caption() const override { return "Vec4 addition"; }
|
||||
QString name() const override { return "Vec4Add"; }
|
||||
QString caption() const override;
|
||||
QString name() const override;
|
||||
|
||||
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>
|
||||
template<typename Data>
|
||||
class VecMul : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Multiply>
|
||||
{
|
||||
public:
|
||||
using VecBinOp::VecBinOp;
|
||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Multiply>::VecBinOp;
|
||||
|
||||
QString caption() const override { return "Vec4 multiplication"; }
|
||||
QString name() const override { return "Vec4Mul"; }
|
||||
QString caption() const override;
|
||||
QString name() const override;
|
||||
|
||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) override;
|
||||
};
|
||||
|
||||
template<typename Data>
|
||||
class VecSub : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Substract>
|
||||
{
|
||||
public:
|
||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Substract>::VecBinOp;
|
||||
|
||||
QString caption() const override;
|
||||
QString name() const override;
|
||||
|
||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) override;
|
||||
};
|
||||
|
||||
using Vec2Add = VecAdd<Vec2Data>;
|
||||
using Vec3Add = VecAdd<Vec3Data>;
|
||||
using Vec4Add = VecAdd<Vec4Data>;
|
||||
|
||||
using Vec2Mul = VecMul<Vec2Data>;
|
||||
using Vec3Mul = VecMul<Vec3Data>;
|
||||
using Vec4Mul = VecMul<Vec4Data>;
|
||||
|
||||
using Vec2Sub = VecSub<Vec2Data>;
|
||||
using Vec3Sub = VecSub<Vec3Data>;
|
||||
using Vec4Sub = VecSub<Vec4Data>;
|
||||
|
||||
#include <DataModels/VecBinOp.inl>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -96,14 +96,10 @@ void VecBinOp<Data, BinOp>::UpdatePreview()
|
|||
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);
|
||||
m_preview = QPixmap::fromImage(m_output->preview).scaled(64, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -113,3 +109,83 @@ void VecBinOp<Data, BinOp>::UpdatePreview()
|
|||
|
||||
m_pixmapLabel->setPixmap(m_preview);
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecAdd<Data>::caption() const
|
||||
{
|
||||
static QString caption = Data::Type().name + " addition";
|
||||
return caption;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecAdd<Data>::name() const
|
||||
{
|
||||
static QString name = Data::Type().name + "add";
|
||||
return name;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
void VecAdd<Data>::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));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecMul<Data>::caption() const
|
||||
{
|
||||
static QString caption = Data::Type().name + " multiplication";
|
||||
return caption;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecMul<Data>::name() const
|
||||
{
|
||||
static QString name = Data::Type().name + "mul";
|
||||
return name;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
void VecMul<Data>::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);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecSub<Data>::caption() const
|
||||
{
|
||||
static QString caption = Data::Type().name + " subtraction";
|
||||
return caption;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecSub<Data>::name() const
|
||||
{
|
||||
static QString name = Data::Type().name + "sub";
|
||||
return name;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
void VecSub<Data>::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];
|
||||
|
||||
unsigned int sub = (lValue >= rValue) ? lValue - rValue : 0u;
|
||||
|
||||
output[i] = static_cast<std::uint8_t>(sub);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
#include <DataModels/VecData.hpp>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_VECDATA_HPP
|
||||
#define NAZARA_SHADERNODES_VECDATA_HPP
|
||||
|
||||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <nodes/NodeData>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
struct VecData : public QtNodes::NodeData
|
||||
{
|
||||
inline VecData();
|
||||
|
||||
QImage preview;
|
||||
};
|
||||
|
||||
struct Vec2Data : public VecData
|
||||
{
|
||||
static constexpr std::size_t ComponentCount = 2;
|
||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float2;
|
||||
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec2", "Vec2" };
|
||||
}
|
||||
};
|
||||
|
||||
struct Vec3Data : public VecData
|
||||
{
|
||||
static constexpr std::size_t ComponentCount = 3;
|
||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float3;
|
||||
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec3", "Vec3" };
|
||||
}
|
||||
};
|
||||
|
||||
struct Vec4Data : public VecData
|
||||
{
|
||||
static constexpr std::size_t ComponentCount = 4;
|
||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float4;
|
||||
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec4", "Vec4" };
|
||||
}
|
||||
};
|
||||
|
||||
#include <DataModels/VecData.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include <DataModels/VecData.hpp>
|
||||
|
||||
inline VecData::VecData() :
|
||||
preview(64, 64, QImage::Format_RGBA8888)
|
||||
{
|
||||
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecData.hpp>
|
||||
#include <array>
|
||||
|
||||
template<std::size_t N>
|
||||
|
|
@ -33,13 +34,16 @@ struct VecTypeHelper<4>
|
|||
|
||||
template<std::size_t N> using VecType = typename VecTypeHelper<N>::template Type;
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
template<typename Data>
|
||||
class VecValue : public ShaderNode
|
||||
{
|
||||
public:
|
||||
VecValue(ShaderGraph& graph);
|
||||
~VecValue() = default;
|
||||
|
||||
QString caption() const override;
|
||||
QString name() const override;
|
||||
|
||||
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||
|
||||
QWidget* embeddedWidget() override;
|
||||
|
|
@ -50,67 +54,22 @@ class VecValue : public ShaderNode
|
|||
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const override;
|
||||
|
||||
protected:
|
||||
static constexpr std::size_t ComponentCount = Data::ComponentCount;
|
||||
|
||||
QColor ToColor() const;
|
||||
VecType<N> ToVector() const;
|
||||
VecType<ComponentCount> ToVector() const;
|
||||
void UpdatePreview();
|
||||
|
||||
QLabel* m_pixmapLabel;
|
||||
QPixmap m_pixmap;
|
||||
QWidget* m_widget;
|
||||
QFormLayout* m_layout;
|
||||
std::array<QDoubleSpinBox*, N> m_spinboxes;
|
||||
std::array<QDoubleSpinBox*, ComponentCount> m_spinboxes;
|
||||
};
|
||||
|
||||
struct VecData : public QtNodes::NodeData
|
||||
{
|
||||
inline VecData();
|
||||
|
||||
QImage preview;
|
||||
};
|
||||
|
||||
struct Vec2Data : public VecData
|
||||
{
|
||||
QtNodes::NodeDataType type() const override
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
static QtNodes::NodeDataType Type()
|
||||
{
|
||||
return { "vec2", "Vec2" };
|
||||
}
|
||||
};
|
||||
|
||||
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:
|
||||
using VecValue::VecValue;
|
||||
|
||||
QString caption() const override { return "Vec2 value"; }
|
||||
QString name() const override { return "Vec2Value"; }
|
||||
};
|
||||
|
||||
class Vec4Value : public VecValue<4, Vec4Data>
|
||||
{
|
||||
public:
|
||||
using VecValue::VecValue;
|
||||
|
||||
QString caption() const override { return "Vec4 value"; }
|
||||
QString name() const override { return "Vec4Value"; }
|
||||
};
|
||||
using Vec2Value = VecValue<Vec2Data>;
|
||||
using Vec3Value = VecValue<Vec3Data>;
|
||||
using Vec4Value = VecValue<Vec4Data>;
|
||||
|
||||
#include <DataModels/VecValue.inl>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@
|
|||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
VecValue<N, Data>::VecValue(ShaderGraph& graph) :
|
||||
template<typename Data>
|
||||
VecValue<Data>::VecValue(ShaderGraph& graph) :
|
||||
ShaderNode(graph)
|
||||
{
|
||||
constexpr std::array<char, 4> componentName = { 'X', 'Y', 'Z', 'W' };
|
||||
static_assert(N <= componentName.size());
|
||||
static_assert(ComponentCount <= componentName.size());
|
||||
|
||||
m_layout = new QFormLayout;
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||
{
|
||||
m_spinboxes[i] = new QDoubleSpinBox;
|
||||
m_spinboxes[i]->setDecimals(6);
|
||||
|
|
@ -42,8 +43,22 @@ ShaderNode(graph)
|
|||
UpdatePreview();
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
QtNodes::NodeDataType VecValue<N, Data>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||
template<typename Data>
|
||||
QString VecValue<Data>::caption() const
|
||||
{
|
||||
static QString caption = Data::Type().name + " constant";
|
||||
return caption;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QString VecValue<Data>::name() const
|
||||
{
|
||||
static QString name = Data::Type().id + "Value";
|
||||
return name;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
QtNodes::NodeDataType VecValue<Data>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||
{
|
||||
assert(portType == QtNodes::PortType::Out);
|
||||
assert(portIndex == 0);
|
||||
|
|
@ -51,14 +66,14 @@ QtNodes::NodeDataType VecValue<N, Data>::dataType(QtNodes::PortType portType, Qt
|
|||
return Data::Type();
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
QWidget* VecValue<N, Data>::embeddedWidget()
|
||||
template<typename Data>
|
||||
QWidget* VecValue<Data>::embeddedWidget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
unsigned int VecValue<N, Data>::nPorts(QtNodes::PortType portType) const
|
||||
template<typename Data>
|
||||
unsigned int VecValue<Data>::nPorts(QtNodes::PortType portType) const
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
|
|
@ -69,8 +84,8 @@ unsigned int VecValue<N, Data>::nPorts(QtNodes::PortType portType) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
std::shared_ptr<QtNodes::NodeData> VecValue<N, Data>::outData(QtNodes::PortIndex port)
|
||||
template<typename Data>
|
||||
std::shared_ptr<QtNodes::NodeData> VecValue<Data>::outData(QtNodes::PortIndex port)
|
||||
{
|
||||
assert(port == 0);
|
||||
|
||||
|
|
@ -81,52 +96,42 @@ std::shared_ptr<QtNodes::NodeData> VecValue<N, Data>::outData(QtNodes::PortIndex
|
|||
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
|
||||
template<typename Data>
|
||||
Nz::ShaderAst::ExpressionPtr VecValue<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
|
||||
template<typename Data>
|
||||
QColor VecValue<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);
|
||||
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||
values[i] = std::clamp(float(m_spinboxes[i]->value()), 0.f, 1.f);
|
||||
|
||||
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
|
||||
template<typename Data>
|
||||
auto VecValue<Data>::ToVector() const -> VecType<ComponentCount>
|
||||
{
|
||||
std::array<float, 4> values = { 0.f, 0.f, 0.f, 1.f };
|
||||
std::array<float, ComponentCount> values;
|
||||
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
values[i] = std::clamp<float>(m_spinboxes[i]->value(), 0.0, 1.0);
|
||||
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||
values[i] = std::clamp(float(m_spinboxes[i]->value()), 0.f, 1.f);
|
||||
|
||||
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");
|
||||
return std::apply([](auto... values)
|
||||
{
|
||||
return VecType<ComponentCount>(values...);
|
||||
}, values);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Data>
|
||||
void VecValue<N, Data>::UpdatePreview()
|
||||
template<typename Data>
|
||||
void VecValue<Data>::UpdatePreview()
|
||||
{
|
||||
m_pixmap.fill(ToColor());
|
||||
m_pixmapLabel->setPixmap(m_pixmap);
|
||||
}
|
||||
|
||||
inline VecData::VecData() :
|
||||
preview(64, 64, QImage::Format_RGBA8888)
|
||||
{
|
||||
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
#include <Previews/PreviewModel.hpp>
|
||||
|
||||
PreviewModel::~PreviewModel() = default;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_PREVIEWMODEL_HPP
|
||||
#define NAZARA_SHADERNODES_PREVIEWMODEL_HPP
|
||||
|
||||
#include <Enums.hpp>
|
||||
|
||||
class QImage;
|
||||
|
||||
class PreviewModel
|
||||
{
|
||||
public:
|
||||
PreviewModel() = default;
|
||||
virtual ~PreviewModel();
|
||||
|
||||
virtual QImage GetImage(InputRole role, std::size_t roleIndex) const = 0;
|
||||
};
|
||||
|
||||
#include <Previews/PreviewModel.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include <Previews/PreviewModel.hpp>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#include <Previews/QuadPreview.hpp>
|
||||
#include <cassert>
|
||||
|
||||
QImage QuadPreview::GetImage(InputRole role, std::size_t roleIndex) const
|
||||
{
|
||||
assert(role == InputRole::TexCoord);
|
||||
assert(roleIndex == 0);
|
||||
|
||||
QImage uv(128, 128, QImage::Format_RGBA8888);
|
||||
|
||||
std::uint8_t* content = uv.bits();
|
||||
for (std::size_t y = 0; y < 128; ++y)
|
||||
{
|
||||
for (std::size_t x = 0; x < 128; ++x)
|
||||
{
|
||||
*content++ = (x * 255) / 128;
|
||||
*content++ = (y * 255) / 128;
|
||||
*content++ = 0;
|
||||
*content++ = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADERNODES_QUADPREVIEW_HPP
|
||||
#define NAZARA_SHADERNODES_QUADPREVIEW_HPP
|
||||
|
||||
#include <Previews/PreviewModel.hpp>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
class QuadPreview : public PreviewModel
|
||||
{
|
||||
public:
|
||||
QuadPreview() = default;
|
||||
~QuadPreview() = default;
|
||||
|
||||
QImage GetImage(InputRole role, std::size_t roleIndex) const override;
|
||||
};
|
||||
|
||||
#include <Previews/QuadPreview.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include <Previews/QuadPreview.hpp>
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
#include <ShaderGraph.hpp>
|
||||
#include <Nazara/Core/StackArray.hpp>
|
||||
#include <DataModels/Cast.hpp>
|
||||
#include <DataModels/FragmentOutput.hpp>
|
||||
#include <DataModels/InputValue.hpp>
|
||||
#include <DataModels/SampleTexture.hpp>
|
||||
#include <DataModels/ShaderNode.hpp>
|
||||
#include <DataModels/VecBinOp.hpp>
|
||||
#include <DataModels/VecValue.hpp>
|
||||
#include <Previews/QuadPreview.hpp>
|
||||
#include <QtCore/QDebug>
|
||||
#include <nodes/Node>
|
||||
#include <nodes/NodeData>
|
||||
|
|
@ -34,6 +36,13 @@ m_flowScene(BuildRegistry())
|
|||
node2.nodeGraphicsObject().setPos(500, 300);
|
||||
|
||||
m_flowScene.createConnection(node2, 0, node1, 0);
|
||||
|
||||
m_previewModel = std::make_unique<QuadPreview>();
|
||||
}
|
||||
|
||||
ShaderGraph::~ShaderGraph()
|
||||
{
|
||||
m_flowScene.clearScene();
|
||||
}
|
||||
|
||||
std::size_t ShaderGraph::AddInput(std::string name, InputType type, InputRole role, std::size_t roleIndex)
|
||||
|
|
@ -125,12 +134,26 @@ void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview)
|
|||
std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
||||
{
|
||||
auto registry = std::make_shared<QtNodes::DataModelRegistry>();
|
||||
RegisterShaderNode<CastVec2ToVec3>(*this, registry, "Casts");
|
||||
RegisterShaderNode<CastVec2ToVec4>(*this, registry, "Casts");
|
||||
RegisterShaderNode<CastVec3ToVec2>(*this, registry, "Casts");
|
||||
RegisterShaderNode<CastVec3ToVec4>(*this, registry, "Casts");
|
||||
RegisterShaderNode<CastVec4ToVec2>(*this, registry, "Casts");
|
||||
RegisterShaderNode<CastVec4ToVec3>(*this, registry, "Casts");
|
||||
RegisterShaderNode<FragmentOutput>(*this, registry, "Outputs");
|
||||
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
|
||||
RegisterShaderNode<SampleTexture>(*this, registry, "Texture");
|
||||
RegisterShaderNode<Vec2Add>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec2Mul>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec2Sub>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec3Add>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec3Mul>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec3Sub>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec4Add>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec4Mul>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec4Sub>(*this, registry, "Vector operations");
|
||||
RegisterShaderNode<Vec2Value>(*this, registry, "Constants");
|
||||
RegisterShaderNode<Vec3Value>(*this, registry, "Constants");
|
||||
RegisterShaderNode<Vec4Value>(*this, registry, "Constants");
|
||||
|
||||
return registry;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <nodes/FlowScene>
|
||||
#include <Enums.hpp>
|
||||
#include <Previews/PreviewModel.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -17,13 +18,14 @@ class ShaderGraph
|
|||
struct TextureEntry;
|
||||
|
||||
ShaderGraph();
|
||||
~ShaderGraph() = default;
|
||||
~ShaderGraph();
|
||||
|
||||
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 const PreviewModel& GetPreviewModel() const;
|
||||
inline QtNodes::FlowScene& GetScene();
|
||||
inline const TextureEntry& GetTexture(std::size_t textureIndex) const;
|
||||
inline const std::vector<TextureEntry>& GetTextures() const;
|
||||
|
|
@ -59,6 +61,7 @@ class ShaderGraph
|
|||
QtNodes::FlowScene m_flowScene;
|
||||
std::vector<InputEntry> m_inputs;
|
||||
std::vector<TextureEntry> m_textures;
|
||||
std::unique_ptr<PreviewModel> m_previewModel;
|
||||
};
|
||||
|
||||
#include <ShaderGraph.inl>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ inline auto ShaderGraph::GetInputs() const -> const std::vector<InputEntry>&
|
|||
return m_inputs;
|
||||
}
|
||||
|
||||
inline const PreviewModel& ShaderGraph::GetPreviewModel() const
|
||||
{
|
||||
return *m_previewModel;
|
||||
}
|
||||
|
||||
inline QtNodes::FlowScene& ShaderGraph::GetScene()
|
||||
{
|
||||
return m_flowScene;
|
||||
|
|
|
|||
Loading…
Reference in New Issue