ShaderNode: Handle vector component count at runtime
This commit is contained in:
parent
2ecc624fe4
commit
effd1b4552
|
|
@ -258,6 +258,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
|
inline Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
|
||||||
|
inline Cast(ExpressionType castTo, ExpressionPtr* expressions, std::size_t expressionCount);
|
||||||
|
|
||||||
ExpressionType GetExpressionType() const override;
|
ExpressionType GetExpressionType() const override;
|
||||||
void Register(ShaderWriter& visitor) override;
|
void Register(ShaderWriter& visitor) override;
|
||||||
|
|
@ -265,6 +266,9 @@ namespace Nz
|
||||||
|
|
||||||
ExpressionType exprType;
|
ExpressionType exprType;
|
||||||
std::array<ExpressionPtr, 4> expressions;
|
std::array<ExpressionPtr, 4> expressions;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Validate() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NAZARA_RENDERER_API Constant : public Expression
|
class NAZARA_RENDERER_API Constant : public Expression
|
||||||
|
|
|
||||||
|
|
@ -169,19 +169,16 @@ namespace Nz
|
||||||
exprType(castTo),
|
exprType(castTo),
|
||||||
expressions({ {first, second, third, fourth} })
|
expressions({ {first, second, third, fourth} })
|
||||||
{
|
{
|
||||||
unsigned int componentCount = 0;
|
Validate();
|
||||||
unsigned int requiredComponents = GetComponentCount(exprType);
|
}
|
||||||
for (const auto& exprPtr : expressions)
|
|
||||||
{
|
|
||||||
if (!exprPtr)
|
|
||||||
break;
|
|
||||||
|
|
||||||
componentCount += GetComponentCount(exprPtr->GetExpressionType());
|
inline Cast::Cast(ExpressionType castTo, ExpressionPtr* Expressions, std::size_t expressionCount) :
|
||||||
}
|
exprType(castTo)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < expressionCount; ++i)
|
||||||
|
expressions[i] = Expressions[i];
|
||||||
|
|
||||||
//TODO: AstParseError
|
Validate();
|
||||||
if (componentCount != requiredComponents)
|
|
||||||
throw std::runtime_error("Component count doesn't match required component count");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Constant::Constant(bool value) :
|
inline Constant::Constant(bool value) :
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,23 @@ namespace Nz::ShaderAst
|
||||||
visitor.Write(*this);
|
visitor.Write(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cast::Validate() const
|
||||||
|
{
|
||||||
|
unsigned int componentCount = 0;
|
||||||
|
unsigned int requiredComponents = GetComponentCount(exprType);
|
||||||
|
for (const auto& exprPtr : expressions)
|
||||||
|
{
|
||||||
|
if (!exprPtr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
componentCount += GetComponentCount(exprPtr->GetExpressionType());
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: AstParseError
|
||||||
|
if (componentCount != requiredComponents)
|
||||||
|
throw std::runtime_error("Component count doesn't match required component count");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ExpressionCategory SwizzleOp::GetExpressionCategory() const
|
ExpressionCategory SwizzleOp::GetExpressionCategory() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
class CastVec : public ShaderNode
|
class CastVec : public ShaderNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -31,25 +31,21 @@ class CastVec : public ShaderNode
|
||||||
|
|
||||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
private:
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
static constexpr std::size_t FromComponents = From::ComponentCount;
|
QString validationMessage() const override;
|
||||||
static constexpr std::size_t ToComponents = To::ComponentCount;
|
|
||||||
static constexpr std::size_t ComponentDiff = (ToComponents >= FromComponents) ? ToComponents - FromComponents : 0;
|
|
||||||
|
|
||||||
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void UpdateOutput();
|
void UpdateOutput();
|
||||||
|
|
||||||
VecType<ComponentDiff> m_overflowComponents;
|
std::shared_ptr<VecData> m_input;
|
||||||
std::shared_ptr<From> m_input;
|
std::shared_ptr<VecData> m_output;
|
||||||
std::shared_ptr<To> m_output;
|
VecType<ToComponentCount> m_overflowComponents;
|
||||||
};
|
};
|
||||||
|
|
||||||
using CastVec2ToVec3 = CastVec<Vec2Data, Vec3Data>;
|
using CastToVec2 = CastVec<2>;
|
||||||
using CastVec2ToVec4 = CastVec<Vec2Data, Vec4Data>;
|
using CastToVec3 = CastVec<3>;
|
||||||
using CastVec3ToVec2 = CastVec<Vec3Data, Vec2Data>;
|
using CastToVec4 = CastVec<4>;
|
||||||
using CastVec3ToVec4 = CastVec<Vec3Data, Vec4Data>;
|
|
||||||
using CastVec4ToVec2 = CastVec<Vec4Data, Vec2Data>;
|
|
||||||
using CastVec4ToVec3 = CastVec<Vec4Data, Vec3Data>;
|
|
||||||
|
|
||||||
#include <ShaderNode/DataModels/Cast.inl>
|
#include <ShaderNode/DataModels/Cast.inl>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,32 @@
|
||||||
#include <QtWidgets/QFormLayout>
|
#include <QtWidgets/QFormLayout>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
CastVec<From, To>::CastVec(ShaderGraph& graph) :
|
CastVec<ToComponentCount>::CastVec(ShaderGraph& graph) :
|
||||||
ShaderNode(graph)
|
ShaderNode(graph)
|
||||||
{
|
{
|
||||||
static_assert(ComponentDiff <= s_vectorComponents.size());
|
static_assert(ToComponentCount <= s_vectorComponents.size());
|
||||||
|
|
||||||
|
m_overflowComponents.fill(0.f);
|
||||||
|
|
||||||
|
m_output = std::make_shared<VecData>(ToComponentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
void CastVec<From, To>::BuildNodeEdition(QFormLayout* layout)
|
void CastVec<ToComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
{
|
{
|
||||||
ShaderNode::BuildNodeEdition(layout);
|
ShaderNode::BuildNodeEdition(layout);
|
||||||
|
|
||||||
if constexpr (ComponentDiff > 0)
|
if (!m_input)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::size_t fromComponentCount = m_input->componentCount;
|
||||||
|
|
||||||
|
if (ToComponentCount > fromComponentCount)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
std::size_t overflowComponentCount = ToComponentCount - fromComponentCount;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
||||||
{
|
{
|
||||||
QDoubleSpinBox* spinbox = new QDoubleSpinBox;
|
QDoubleSpinBox* spinbox = new QDoubleSpinBox;
|
||||||
spinbox->setDecimals(6);
|
spinbox->setDecimals(6);
|
||||||
|
|
@ -30,31 +41,36 @@ void CastVec<From, To>::BuildNodeEdition(QFormLayout* layout)
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
});
|
});
|
||||||
|
|
||||||
layout->addRow(QString::fromUtf8(&s_vectorComponents[FromComponents + i], 1), spinbox);
|
layout->addRow(QString::fromUtf8(&s_vectorComponents[fromComponentCount + i], 1), spinbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
Nz::ShaderAst::ExpressionPtr CastVec<From, To>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderAst::ExpressionPtr CastVec<ToComponentCount>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||||
{
|
{
|
||||||
|
assert(m_input);
|
||||||
assert(count == 1);
|
assert(count == 1);
|
||||||
|
|
||||||
if constexpr (ComponentDiff > 0)
|
std::size_t fromComponentCount = m_input->componentCount;
|
||||||
{
|
|
||||||
std::array<Nz::ShaderAst::ExpressionPtr, ComponentDiff> constants;
|
|
||||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
|
||||||
constants[i] = Nz::ShaderBuilder::Constant(m_overflowComponents[i]);
|
|
||||||
|
|
||||||
return std::apply([&](auto&&... values)
|
if (ToComponentCount > fromComponentCount)
|
||||||
{
|
|
||||||
return Nz::ShaderBuilder::Cast<To::ExpressionType>(expressions[0], values...); //< TODO: Forward
|
|
||||||
}, constants);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
std::array<Nz::ShaderAst::SwizzleComponent, ToComponents> swizzleComponents;
|
std::size_t overflowComponentCount = ToComponentCount - fromComponentCount;
|
||||||
for (std::size_t i = 0; i < ToComponents; ++i)
|
|
||||||
|
std::array<Nz::ShaderAst::ExpressionPtr, 4> expr;
|
||||||
|
expr[0] = expressions[0];
|
||||||
|
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
||||||
|
expr[i + 1] = Nz::ShaderBuilder::Constant(m_overflowComponents[i]);
|
||||||
|
|
||||||
|
constexpr auto ExpressionType = VecExpressionType<ToComponentCount>;
|
||||||
|
|
||||||
|
return Nz::ShaderBuilder::Cast<ExpressionType>(expr.data(), overflowComponentCount);
|
||||||
|
}
|
||||||
|
else if (ToComponentCount < fromComponentCount)
|
||||||
|
{
|
||||||
|
std::array<Nz::ShaderAst::SwizzleComponent, ToComponentCount> swizzleComponents;
|
||||||
|
for (std::size_t i = 0; i < ToComponentCount; ++i)
|
||||||
swizzleComponents[i] = static_cast<Nz::ShaderAst::SwizzleComponent>(static_cast<std::size_t>(Nz::ShaderAst::SwizzleComponent::First) + i);
|
swizzleComponents[i] = static_cast<Nz::ShaderAst::SwizzleComponent>(static_cast<std::size_t>(Nz::ShaderAst::SwizzleComponent::First) + i);
|
||||||
|
|
||||||
return std::apply([&](auto... components)
|
return std::apply([&](auto... components)
|
||||||
|
|
@ -63,39 +79,41 @@ Nz::ShaderAst::ExpressionPtr CastVec<From, To>::GetExpression(Nz::ShaderAst::Exp
|
||||||
return Nz::ShaderBuilder::Swizzle(expressions[0], componentList);
|
return Nz::ShaderBuilder::Swizzle(expressions[0], componentList);
|
||||||
}, swizzleComponents);
|
}, swizzleComponents);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return expressions[0]; //< no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
QString CastVec<From, To>::caption() const
|
QString CastVec<ToComponentCount>::caption() const
|
||||||
{
|
{
|
||||||
static QString caption = From::Type().name + " to " + To::Type().name;
|
static QString caption = "To Vector" + QString::number(ToComponentCount);
|
||||||
return caption;
|
return caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
QString CastVec<From, To>::name() const
|
QString CastVec<ToComponentCount>::name() const
|
||||||
{
|
{
|
||||||
static QString name = From::Type().id + "to" + To::Type().id;
|
static QString name = "cast_vec" + QString::number(ToComponentCount);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
QtNodes::NodeDataType CastVec<From, To>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
QtNodes::NodeDataType CastVec<ToComponentCount>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
|
|
||||||
switch (portType)
|
switch (portType)
|
||||||
{
|
{
|
||||||
case QtNodes::PortType::In: return From::Type();
|
case QtNodes::PortType::In: return VecData::Type();
|
||||||
case QtNodes::PortType::Out: return To::Type();
|
case QtNodes::PortType::Out: return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
throw std::runtime_error("Invalid port type");
|
throw std::runtime_error("Invalid port type");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
unsigned int CastVec<From, To>::nPorts(QtNodes::PortType portType) const
|
unsigned int CastVec<ToComponentCount>::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
switch (portType)
|
switch (portType)
|
||||||
{
|
{
|
||||||
|
|
@ -106,8 +124,8 @@ unsigned int CastVec<From, To>::nPorts(QtNodes::PortType portType) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
std::shared_ptr<QtNodes::NodeData> CastVec<From, To>::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> CastVec<ToComponentCount>::outData(QtNodes::PortIndex port)
|
||||||
{
|
{
|
||||||
assert(port == 0);
|
assert(port == 0);
|
||||||
|
|
||||||
|
|
@ -117,14 +135,14 @@ std::shared_ptr<QtNodes::NodeData> CastVec<From, To>::outData(QtNodes::PortIndex
|
||||||
return m_output;
|
return m_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
void CastVec<From, To>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
void CastVec<ToComponentCount>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
{
|
{
|
||||||
assert(index == 0);
|
assert(index == 0);
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<From*>(value.get()) != nullptr);
|
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
|
||||||
m_input = std::static_pointer_cast<From>(value);
|
m_input = std::static_pointer_cast<VecData>(value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_input.reset();
|
m_input.reset();
|
||||||
|
|
@ -132,8 +150,26 @@ void CastVec<From, To>::setInData(std::shared_ptr<QtNodes::NodeData> value, int
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
bool CastVec<From, To>::ComputePreview(QPixmap& pixmap)
|
QtNodes::NodeValidationState CastVec<ToComponentCount>::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_input)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ToComponentCount>
|
||||||
|
QString CastVec<ToComponentCount>::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_input)
|
||||||
|
return "Missing input";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ToComponentCount>
|
||||||
|
bool CastVec<ToComponentCount>::ComputePreview(QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
if (!m_input)
|
if (!m_input)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -142,8 +178,8 @@ bool CastVec<From, To>::ComputePreview(QPixmap& pixmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To>
|
template<std::size_t ToComponentCount>
|
||||||
void CastVec<From, To>::UpdateOutput()
|
void CastVec<ToComponentCount>::UpdateOutput()
|
||||||
{
|
{
|
||||||
if (!m_input)
|
if (!m_input)
|
||||||
{
|
{
|
||||||
|
|
@ -160,10 +196,15 @@ void CastVec<From, To>::UpdateOutput()
|
||||||
QImage& output = m_output->preview;
|
QImage& output = m_output->preview;
|
||||||
output = QImage(inputWidth, inputHeight, QImage::Format_RGBA8888);
|
output = QImage(inputWidth, inputHeight, QImage::Format_RGBA8888);
|
||||||
|
|
||||||
std::array<std::uint8_t, ComponentDiff> constants;
|
std::size_t fromComponentCount = m_input->componentCount;
|
||||||
if constexpr (ComponentDiff > 0)
|
std::size_t commonComponents = std::min(fromComponentCount, ToComponentCount);
|
||||||
|
std::size_t overflowComponentCount = (ToComponentCount > fromComponentCount) ? ToComponentCount - fromComponentCount : 0;
|
||||||
|
std::size_t voidComponents = 4 - overflowComponentCount - commonComponents;
|
||||||
|
|
||||||
|
std::array<std::uint8_t, 4> constants;
|
||||||
|
if (ToComponentCount > fromComponentCount)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
||||||
constants[i] = static_cast<std::uint8_t>(std::clamp(int(m_overflowComponents[i] * 255), 0, 255));
|
constants[i] = static_cast<std::uint8_t>(std::clamp(int(m_overflowComponents[i] * 255), 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,17 +214,14 @@ void CastVec<From, To>::UpdateOutput()
|
||||||
{
|
{
|
||||||
for (int x = 0; x < inputWidth; ++x)
|
for (int x = 0; x < inputWidth; ++x)
|
||||||
{
|
{
|
||||||
constexpr std::size_t CommonComponents = std::min(FromComponents, ToComponents);
|
for (std::size_t i = 0; i < commonComponents; ++i)
|
||||||
constexpr std::size_t VoidComponents = 4 - ComponentDiff - CommonComponents;
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < CommonComponents; ++i)
|
|
||||||
*outputPtr++ = inputPtr[i];
|
*outputPtr++ = inputPtr[i];
|
||||||
|
|
||||||
for (std::size_t i = 0; i < ComponentDiff; ++i)
|
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
||||||
*outputPtr++ = constants[i];
|
*outputPtr++ = constants[i];
|
||||||
|
|
||||||
for (std::size_t i = 0; i < VoidComponents; ++i)
|
for (std::size_t i = 0; i < voidComponents; ++i)
|
||||||
*outputPtr++ = (i == VoidComponents - 1) ? 255 : 0;
|
*outputPtr++ = (i == voidComponents - 1) ? 255 : 0;
|
||||||
|
|
||||||
inputPtr += 4;
|
inputPtr += 4;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,16 +121,17 @@ auto InputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portInd
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
|
|
||||||
if (!m_currentInputIndex)
|
if (!m_currentInputIndex)
|
||||||
return Vec4Data::Type();
|
return VecData::Type();
|
||||||
|
|
||||||
const auto& inputEntry = GetGraph().GetInput(*m_currentInputIndex);
|
const auto& inputEntry = GetGraph().GetInput(*m_currentInputIndex);
|
||||||
switch (inputEntry.type)
|
switch (inputEntry.type)
|
||||||
{
|
{
|
||||||
//case InputType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
|
//case InputType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
|
||||||
//case InputType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
|
//case InputType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
|
||||||
case InOutType::Float2: return Vec2Data::Type();
|
case InOutType::Float2:
|
||||||
case InOutType::Float3: return Vec3Data::Type();
|
case InOutType::Float3:
|
||||||
case InOutType::Float4: return Vec4Data::Type();
|
case InOutType::Float4:
|
||||||
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -148,8 +149,24 @@ std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
|
||||||
const auto& inputEntry = graph.GetInput(*m_currentInputIndex);
|
const auto& inputEntry = graph.GetInput(*m_currentInputIndex);
|
||||||
const auto& preview = graph.GetPreviewModel();
|
const auto& preview = graph.GetPreviewModel();
|
||||||
|
|
||||||
auto vecData = std::make_shared<Vec2Data>();
|
auto vecData = std::make_shared<VecData>(GetComponentCount(inputEntry.type));
|
||||||
vecData->preview = preview.GetImage(inputEntry.role, inputEntry.roleIndex);
|
vecData->preview = preview.GetImage(inputEntry.role, inputEntry.roleIndex);
|
||||||
|
|
||||||
return vecData;
|
return vecData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState InputValue::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_currentInputIndex)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString InputValue::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_currentInputIndex)
|
||||||
|
return "No input selected";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ class InputValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void OnInputListUpdate();
|
void OnInputListUpdate();
|
||||||
|
|
|
||||||
|
|
@ -87,16 +87,17 @@ QtNodes::NodeDataType OutputValue::dataType(QtNodes::PortType portType, QtNodes:
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
|
|
||||||
if (!m_currentOutputIndex)
|
if (!m_currentOutputIndex)
|
||||||
return Vec4Data::Type();
|
return VecData::Type();
|
||||||
|
|
||||||
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
|
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
|
||||||
switch (outputEntry.type)
|
switch (outputEntry.type)
|
||||||
{
|
{
|
||||||
//case InOutType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
|
//case InOutType::Bool: return Nz::ShaderAst::ExpressionType::Boolean;
|
||||||
//case InOutType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
|
//case InOutType::Float1: return Nz::ShaderAst::ExpressionType::Float1;
|
||||||
case InOutType::Float2: return Vec2Data::Type();
|
case InOutType::Float2:
|
||||||
case InOutType::Float3: return Vec3Data::Type();
|
case InOutType::Float3:
|
||||||
case InOutType::Float4: return Vec4Data::Type();
|
case InOutType::Float4:
|
||||||
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -124,8 +125,8 @@ void OutputValue::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
assert(index == 0);
|
assert(index == 0);
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<Vec4Data*>(value.get()) != nullptr);
|
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
|
||||||
m_input = std::static_pointer_cast<Vec4Data>(value);
|
m_input = std::static_pointer_cast<VecData>(value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_input.reset();
|
m_input.reset();
|
||||||
|
|
@ -133,6 +134,35 @@ void OutputValue::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState OutputValue::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_currentOutputIndex || !m_input)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
|
||||||
|
if (GetComponentCount(outputEntry.type) != m_input->componentCount)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString OutputValue::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_currentOutputIndex)
|
||||||
|
return "No output selected";
|
||||||
|
|
||||||
|
if (!m_input)
|
||||||
|
return "Missing input";
|
||||||
|
|
||||||
|
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
|
||||||
|
std::size_t outputComponentCount = GetComponentCount(outputEntry.type);
|
||||||
|
|
||||||
|
if (m_input->componentCount != outputComponentCount)
|
||||||
|
return "Incompatible component count (expected " + QString::number(outputComponentCount) + ", got " + QString::number(m_input->componentCount) + ")";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
bool OutputValue::ComputePreview(QPixmap& pixmap)
|
bool OutputValue::ComputePreview(QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
if (!m_input)
|
if (!m_input)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ class OutputValue : public ShaderNode
|
||||||
|
|
||||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void OnOutputListUpdate();
|
void OnOutputListUpdate();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
SampleTexture::SampleTexture(ShaderGraph& graph) :
|
SampleTexture::SampleTexture(ShaderGraph& graph) :
|
||||||
ShaderNode(graph)
|
ShaderNode(graph)
|
||||||
{
|
{
|
||||||
m_output = std::make_shared<Vec4Data>();
|
m_output = std::make_shared<VecData>(4);
|
||||||
|
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
@ -82,9 +82,8 @@ bool SampleTexture::ComputePreview(QPixmap& pixmap)
|
||||||
|
|
||||||
Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderAst::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||||
{
|
{
|
||||||
if (!m_texture || !m_uv)
|
assert(m_texture);
|
||||||
throw std::runtime_error("invalid inputs");
|
assert(m_uv);
|
||||||
|
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Sample2D(expressions[0], expressions[1]);
|
return Nz::ShaderBuilder::Sample2D(expressions[0], expressions[1]);
|
||||||
|
|
@ -99,7 +98,7 @@ auto SampleTexture::dataType(QtNodes::PortType portType, QtNodes::PortIndex port
|
||||||
switch (portIndex)
|
switch (portIndex)
|
||||||
{
|
{
|
||||||
case 0: return Texture2Data::Type();
|
case 0: return Texture2Data::Type();
|
||||||
case 1: return Vec2Data::Type();
|
case 1: return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -109,7 +108,7 @@ auto SampleTexture::dataType(QtNodes::PortType portType, QtNodes::PortIndex port
|
||||||
case QtNodes::PortType::Out:
|
case QtNodes::PortType::Out:
|
||||||
{
|
{
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
return Vec4Data::Type();
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -180,9 +179,9 @@ void SampleTexture::setInData(std::shared_ptr<QtNodes::NodeData> value, int inde
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<Vec2Data*>(value.get()) != nullptr);
|
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
|
||||||
|
|
||||||
m_uv = std::static_pointer_cast<Vec2Data>(value);
|
m_uv = std::static_pointer_cast<VecData>(value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_uv.reset();
|
m_uv.reset();
|
||||||
|
|
@ -197,3 +196,28 @@ void SampleTexture::setInData(std::shared_ptr<QtNodes::NodeData> value, int inde
|
||||||
|
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState SampleTexture::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_texture || !m_uv)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
if (m_uv->componentCount != 2)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SampleTexture::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_texture)
|
||||||
|
return "Missing texture";
|
||||||
|
|
||||||
|
if (!m_uv)
|
||||||
|
return "Missing uv";
|
||||||
|
|
||||||
|
if (m_uv->componentCount != 2)
|
||||||
|
return "Incompatible UV (expected 2, got " + QString::number(m_uv->componentCount) + ")";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,16 @@ class SampleTexture : public ShaderNode
|
||||||
|
|
||||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void UpdateOutput();
|
void UpdateOutput();
|
||||||
|
|
||||||
std::shared_ptr<Texture2Data> m_texture;
|
std::shared_ptr<Texture2Data> m_texture;
|
||||||
std::shared_ptr<Vec2Data> m_uv;
|
std::shared_ptr<VecData> m_uv;
|
||||||
std::shared_ptr<Vec4Data> m_output;
|
std::shared_ptr<VecData> m_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <ShaderNode/DataModels/SampleTexture.inl>
|
#include <ShaderNode/DataModels/SampleTexture.inl>
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
Nz::ShaderAst::ExpressionPtr TextureValue::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderAst::ExpressionPtr TextureValue::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
||||||
{
|
{
|
||||||
if (!m_currentTextureIndex)
|
if (!m_currentTextureIndex)
|
||||||
throw std::runtime_error("invalid inputs");
|
throw std::runtime_error("invalid texture input");
|
||||||
|
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ auto TextureValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portI
|
||||||
assert(portType == QtNodes::PortType::Out);
|
assert(portType == QtNodes::PortType::Out);
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
|
|
||||||
return Vec4Data::Type();
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> TextureValue::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> TextureValue::outData(QtNodes::PortIndex port)
|
||||||
|
|
@ -145,3 +145,19 @@ std::shared_ptr<QtNodes::NodeData> TextureValue::outData(QtNodes::PortIndex port
|
||||||
|
|
||||||
return textureData;
|
return textureData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState TextureValue::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_currentTextureIndex)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TextureValue::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_currentTextureIndex)
|
||||||
|
return "No texture selected";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ class TextureValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void OnTextureListUpdate();
|
void OnTextureListUpdate();
|
||||||
|
|
|
||||||
|
|
@ -1 +1,73 @@
|
||||||
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
||||||
|
|
||||||
|
QString VecAdd::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Vector addition";
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecAdd::name() const
|
||||||
|
{
|
||||||
|
static QString name = "vec_add";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecAdd::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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecMul::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Vector multiplication";
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecMul::name() const
|
||||||
|
{
|
||||||
|
static QString name = "vec_mul";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecMul::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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecSub::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Vector subtraction";
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString VecSub::name() const
|
||||||
|
{
|
||||||
|
static QString name = "vec_sub";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecSub::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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
class VecBinOp : public ShaderNode
|
class VecBinOp : public ShaderNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -29,16 +29,15 @@ class VecBinOp : public ShaderNode
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
void UpdateOutput();
|
void UpdateOutput();
|
||||||
|
|
||||||
std::shared_ptr<Data> m_lhs;
|
std::shared_ptr<VecData> m_lhs;
|
||||||
std::shared_ptr<Data> m_rhs;
|
std::shared_ptr<VecData> m_rhs;
|
||||||
std::shared_ptr<Data> m_output;
|
std::shared_ptr<VecData> m_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Data>
|
class VecAdd : public VecBinOp<Nz::ShaderAst::BinaryType::Add>
|
||||||
class VecAdd : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Add>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Add>::VecBinOp;
|
using VecBinOp<Nz::ShaderAst::BinaryType::Add>::VecBinOp;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
@ -46,11 +45,10 @@ class VecAdd : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Add>
|
||||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) 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 VecMul : public VecBinOp<Nz::ShaderAst::BinaryType::Multiply>
|
||||||
class VecMul : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Multiply>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Multiply>::VecBinOp;
|
using VecBinOp<Nz::ShaderAst::BinaryType::Multiply>::VecBinOp;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
@ -58,11 +56,10 @@ class VecMul : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Multiply>
|
||||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) 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<Nz::ShaderAst::BinaryType::Substract>
|
||||||
class VecSub : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Substract>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using VecBinOp<Data, Nz::ShaderAst::BinaryType::Substract>::VecBinOp;
|
using VecBinOp<Nz::ShaderAst::BinaryType::Substract>::VecBinOp;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
@ -70,18 +67,6 @@ class VecSub : public VecBinOp<Data, Nz::ShaderAst::BinaryType::Substract>
|
||||||
void ApplyOp(const std::uint8_t* left, const std::uint8_t* right, std::uint8_t* output, std::size_t pixelCount) 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 <ShaderNode/DataModels/VecBinOp.inl>
|
#include <ShaderNode/DataModels/VecBinOp.inl>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
||||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
VecBinOp<Data, BinOp>::VecBinOp(ShaderGraph& graph) :
|
VecBinOp<BinOp>::VecBinOp(ShaderGraph& graph) :
|
||||||
ShaderNode(graph)
|
ShaderNode(graph)
|
||||||
{
|
{
|
||||||
m_output = std::make_shared<Data>();
|
|
||||||
|
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
Nz::ShaderAst::ExpressionPtr VecBinOp<Data, BinOp>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderAst::ExpressionPtr VecBinOp<BinOp>::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
|
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
|
||||||
|
|
@ -19,16 +17,16 @@ Nz::ShaderAst::ExpressionPtr VecBinOp<Data, BinOp>::GetExpression(Nz::ShaderAst:
|
||||||
return builder(expressions[0], expressions[1]);
|
return builder(expressions[0], expressions[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
QtNodes::NodeDataType VecBinOp<Data, BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
QtNodes::NodeDataType VecBinOp<BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
assert(portIndex == 0 || portIndex == 1);
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
|
||||||
return Data::Type();
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
unsigned int VecBinOp<Data, BinOp>::nPorts(QtNodes::PortType portType) const
|
unsigned int VecBinOp<BinOp>::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
switch (portType)
|
switch (portType)
|
||||||
{
|
{
|
||||||
|
|
@ -39,24 +37,24 @@ unsigned int VecBinOp<Data, BinOp>::nPorts(QtNodes::PortType portType) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
std::shared_ptr<QtNodes::NodeData> VecBinOp<Data, BinOp>::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> VecBinOp<BinOp>::outData(QtNodes::PortIndex port)
|
||||||
{
|
{
|
||||||
assert(port == 0);
|
assert(port == 0);
|
||||||
return m_output;
|
return m_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
void VecBinOp<Data, BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
void VecBinOp<BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
{
|
{
|
||||||
assert(index == 0 || index == 1);
|
assert(index == 0 || index == 1);
|
||||||
|
|
||||||
std::shared_ptr<Data> castedValue;
|
std::shared_ptr<VecData> castedValue;
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<Data*>(value.get()) != nullptr);
|
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
|
||||||
|
|
||||||
castedValue = std::static_pointer_cast<Data>(value);
|
castedValue = std::static_pointer_cast<VecData>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
|
@ -67,8 +65,8 @@ void VecBinOp<Data, BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value,
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
bool VecBinOp<Data, BinOp>::ComputePreview(QPixmap& pixmap)
|
bool VecBinOp<BinOp>::ComputePreview(QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
if (!m_lhs || !m_rhs)
|
if (!m_lhs || !m_rhs)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -77,16 +75,19 @@ bool VecBinOp<Data, BinOp>::ComputePreview(QPixmap& pixmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data, Nz::ShaderAst::BinaryType BinOp>
|
template<Nz::ShaderAst::BinaryType BinOp>
|
||||||
void VecBinOp<Data, BinOp>::UpdateOutput()
|
void VecBinOp<BinOp>::UpdateOutput()
|
||||||
{
|
{
|
||||||
if (!m_lhs || !m_rhs)
|
if (!m_lhs || !m_rhs || m_lhs->componentCount != m_rhs->componentCount)
|
||||||
{
|
{
|
||||||
|
m_output = std::make_shared<VecData>(4);
|
||||||
m_output->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
m_output->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
||||||
m_output->preview.fill(QColor::fromRgb(0, 0, 0, 0));
|
m_output->preview.fill(QColor::fromRgb(0, 0, 0, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_output = std::make_shared<VecData>(m_lhs->componentCount);
|
||||||
|
|
||||||
const QImage& leftPreview = m_lhs->preview;
|
const QImage& leftPreview = m_lhs->preview;
|
||||||
const QImage& rightPreview = m_rhs->preview;
|
const QImage& rightPreview = m_rhs->preview;
|
||||||
int maxWidth = std::max(leftPreview.width(), rightPreview.width());
|
int maxWidth = std::max(leftPreview.width(), rightPreview.width());
|
||||||
|
|
@ -108,83 +109,3 @@ void VecBinOp<Data, BinOp>::UpdateOutput()
|
||||||
|
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
class VecValue : public ShaderNode
|
class VecValue : public ShaderNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -34,16 +34,14 @@ class VecValue : public ShaderNode
|
||||||
private:
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
|
||||||
static constexpr std::size_t ComponentCount = Data::ComponentCount;
|
|
||||||
|
|
||||||
QColor ToColor() const;
|
QColor ToColor() const;
|
||||||
|
|
||||||
VecType<ComponentCount> m_value;
|
VecType<ComponentCount> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Vec2Value = VecValue<Vec2Data>;
|
using Vec2Value = VecValue<2>;
|
||||||
using Vec3Value = VecValue<Vec3Data>;
|
using Vec3Value = VecValue<3>;
|
||||||
using Vec4Value = VecValue<Vec4Data>;
|
using Vec4Value = VecValue<4>;
|
||||||
|
|
||||||
#include <ShaderNode/DataModels/VecValue.inl>
|
#include <ShaderNode/DataModels/VecValue.inl>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
VecValue<Data>::VecValue(ShaderGraph& graph) :
|
VecValue<ComponentCount>::VecValue(ShaderGraph& graph) :
|
||||||
ShaderNode(graph)
|
ShaderNode(graph)
|
||||||
{
|
{
|
||||||
static_assert(ComponentCount <= s_vectorComponents.size());
|
static_assert(ComponentCount <= s_vectorComponents.size());
|
||||||
|
|
@ -21,55 +21,55 @@ ShaderNode(graph)
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
QString VecValue<Data>::caption() const
|
QString VecValue<ComponentCount>::caption() const
|
||||||
{
|
{
|
||||||
static QString caption = Data::Type().name + " constant";
|
static QString caption = "Vector" + QString::number(ComponentCount) + " constant";
|
||||||
return caption;
|
return caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
QString VecValue<Data>::name() const
|
QString VecValue<ComponentCount>::name() const
|
||||||
{
|
{
|
||||||
static QString name = Data::Type().id + "Value";
|
static QString name = "vec" + QString::number(ComponentCount) + "_constant";
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
QtNodes::NodeDataType VecValue<Data>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
QtNodes::NodeDataType VecValue<ComponentCount>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
assert(portType == QtNodes::PortType::Out);
|
assert(portType == QtNodes::PortType::Out);
|
||||||
assert(portIndex == 0);
|
assert(portIndex == 0);
|
||||||
|
|
||||||
return Data::Type();
|
return VecData::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
unsigned int VecValue<Data>::nPorts(QtNodes::PortType portType) const
|
unsigned int VecValue<ComponentCount>::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
switch (portType)
|
switch (portType)
|
||||||
{
|
{
|
||||||
case QtNodes::PortType::In: return 0;
|
case QtNodes::PortType::In: return 0;
|
||||||
case QtNodes::PortType::Out: return 1;
|
case QtNodes::PortType::Out: return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
std::shared_ptr<QtNodes::NodeData> VecValue<Data>::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> VecValue<ComponentCount>::outData(QtNodes::PortIndex port)
|
||||||
{
|
{
|
||||||
assert(port == 0);
|
assert(port == 0);
|
||||||
|
|
||||||
auto out = std::make_shared<Data>();
|
auto out = std::make_shared<VecData>(ComponentCount);
|
||||||
out->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
out->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
||||||
out->preview.fill(ToColor());
|
out->preview.fill(ToColor());
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
void VecValue<Data>::BuildNodeEdition(QFormLayout* layout)
|
void VecValue<ComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
{
|
{
|
||||||
ShaderNode::BuildNodeEdition(layout);
|
ShaderNode::BuildNodeEdition(layout);
|
||||||
|
|
||||||
|
|
@ -91,23 +91,23 @@ void VecValue<Data>::BuildNodeEdition(QFormLayout* layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
Nz::ShaderAst::ExpressionPtr VecValue<Data>::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderAst::ExpressionPtr VecValue<ComponentCount>::GetExpression(Nz::ShaderAst::ExpressionPtr* /*expressions*/, std::size_t count) const
|
||||||
{
|
{
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Constant(m_value);
|
return Nz::ShaderBuilder::Constant(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
bool VecValue<Data>::ComputePreview(QPixmap& pixmap)
|
bool VecValue<ComponentCount>::ComputePreview(QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
pixmap.fill(ToColor());
|
pixmap.fill(ToColor());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Data>
|
template<std::size_t ComponentCount>
|
||||||
QColor VecValue<Data>::ToColor() const
|
QColor VecValue<ComponentCount>::ToColor() const
|
||||||
{
|
{
|
||||||
std::array<float, 4> values = { 0.f, 0.f, 0.f, 1.f };
|
std::array<float, 4> values = { 0.f, 0.f, 0.f, 1.f };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_FLOATDATA_HPP
|
||||||
|
#define NAZARA_SHADERNODES_FLOATDATA_HPP
|
||||||
|
|
||||||
|
#include <nodes/NodeData>
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
|
||||||
|
struct FloatData : public QtNodes::NodeData
|
||||||
|
{
|
||||||
|
inline FloatData();
|
||||||
|
|
||||||
|
QtNodes::NodeDataType type() const override
|
||||||
|
{
|
||||||
|
return Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QtNodes::NodeDataType Type()
|
||||||
|
{
|
||||||
|
return { "float", "Float" };
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage preview;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
|
||||||
|
inline FloatData::FloatData() :
|
||||||
|
preview(1, 1, QImage::Format_RGBA8888)
|
||||||
|
{
|
||||||
|
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||||
|
}
|
||||||
|
|
@ -1 +1,18 @@
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
Nz::ShaderAst::ExpressionType VecData::GetExpressionType() const
|
||||||
|
{
|
||||||
|
switch (componentCount)
|
||||||
|
{
|
||||||
|
case 2: return Nz::ShaderAst::ExpressionType::Float2;
|
||||||
|
case 3: return Nz::ShaderAst::ExpressionType::Float3;
|
||||||
|
case 4: return Nz::ShaderAst::ExpressionType::Float4;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid component count");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,59 +9,48 @@
|
||||||
|
|
||||||
struct VecData : public QtNodes::NodeData
|
struct VecData : public QtNodes::NodeData
|
||||||
{
|
{
|
||||||
inline VecData();
|
inline VecData(std::size_t componentCount);
|
||||||
|
|
||||||
|
inline QtNodes::NodeDataType type() const override;
|
||||||
|
|
||||||
|
Nz::ShaderAst::ExpressionType GetExpressionType() const;
|
||||||
|
|
||||||
|
static inline QtNodes::NodeDataType Type();
|
||||||
|
|
||||||
|
std::size_t componentCount;
|
||||||
QImage preview;
|
QImage preview;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vec2Data : public VecData
|
template<std::size_t N>
|
||||||
|
struct VecExpressionTypeHelper;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct VecExpressionTypeHelper<1>
|
||||||
|
{
|
||||||
|
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct VecExpressionTypeHelper<2>
|
||||||
{
|
{
|
||||||
static constexpr std::size_t ComponentCount = 2;
|
|
||||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float2;
|
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
|
template<>
|
||||||
|
struct VecExpressionTypeHelper<3>
|
||||||
{
|
{
|
||||||
static constexpr std::size_t ComponentCount = 3;
|
|
||||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float3;
|
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
|
template<>
|
||||||
|
struct VecExpressionTypeHelper<4>
|
||||||
{
|
{
|
||||||
static constexpr std::size_t ComponentCount = 4;
|
|
||||||
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float4;
|
static constexpr Nz::ShaderAst::ExpressionType ExpressionType = Nz::ShaderAst::ExpressionType::Float4;
|
||||||
|
|
||||||
QtNodes::NodeDataType type() const override
|
|
||||||
{
|
|
||||||
return Type();
|
|
||||||
}
|
|
||||||
|
|
||||||
static QtNodes::NodeDataType Type()
|
|
||||||
{
|
|
||||||
return { "vec4", "Vec4" };
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<std::size_t N> constexpr Nz::ShaderAst::ExpressionType VecExpressionType = VecExpressionTypeHelper<N>::template ExpressionType;
|
||||||
|
|
||||||
|
|
||||||
struct VecTypeDummy {};
|
struct VecTypeDummy {};
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
|
|
@ -76,7 +65,7 @@ struct VecTypeHelper<0>
|
||||||
template<>
|
template<>
|
||||||
struct VecTypeHelper<1>
|
struct VecTypeHelper<1>
|
||||||
{
|
{
|
||||||
using Type = std::array<float, 1>;
|
using Type = std::array<float, 1>; //< To allow [0]
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
inline VecData::VecData() :
|
inline VecData::VecData(std::size_t ComponentCount) :
|
||||||
|
componentCount(ComponentCount),
|
||||||
preview(64, 64, QImage::Format_RGBA8888)
|
preview(64, 64, QImage::Format_RGBA8888)
|
||||||
{
|
{
|
||||||
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
preview.fill(QColor::fromRgb(255, 255, 255, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QtNodes::NodeDataType VecData::type() const
|
||||||
|
{
|
||||||
|
return Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QtNodes::NodeDataType VecData::Type()
|
||||||
|
{
|
||||||
|
return { "vector", "Vector" };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,21 @@
|
||||||
#include <ShaderNode/Enums.hpp>
|
#include <ShaderNode/Enums.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
std::size_t GetComponentCount(InOutType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case InOutType::Bool: return 1;
|
||||||
|
case InOutType::Float1: return 1;
|
||||||
|
case InOutType::Float2: return 2;
|
||||||
|
case InOutType::Float3: return 3;
|
||||||
|
case InOutType::Float4: return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char* EnumToString(InputRole role)
|
const char* EnumToString(InputRole role)
|
||||||
{
|
{
|
||||||
switch (role)
|
switch (role)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ enum class TextureType
|
||||||
|
|
||||||
constexpr std::size_t TextureTypeCount = static_cast<std::size_t>(TextureType::Max) + 1;
|
constexpr std::size_t TextureTypeCount = static_cast<std::size_t>(TextureType::Max) + 1;
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t GetComponentCount(InOutType type);
|
||||||
const char* EnumToString(InputRole role);
|
const char* EnumToString(InputRole role);
|
||||||
const char* EnumToString(InOutType input);
|
const char* EnumToString(InOutType input);
|
||||||
const char* EnumToString(TextureType textureType);
|
const char* EnumToString(TextureType textureType);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ m_flowScene(BuildRegistry())
|
||||||
auto& node3 = m_flowScene.createNode(std::make_unique<SampleTexture>(*this));
|
auto& node3 = m_flowScene.createNode(std::make_unique<SampleTexture>(*this));
|
||||||
node3.nodeGraphicsObject().setPos(200, 200);
|
node3.nodeGraphicsObject().setPos(200, 200);
|
||||||
|
|
||||||
auto& node4 = m_flowScene.createNode(std::make_unique<Vec4Mul>(*this));
|
auto& node4 = m_flowScene.createNode(std::make_unique<VecMul>(*this));
|
||||||
node4.nodeGraphicsObject().setPos(400, 200);
|
node4.nodeGraphicsObject().setPos(400, 200);
|
||||||
|
|
||||||
auto& node5 = m_flowScene.createNode(std::make_unique<OutputValue>(*this));
|
auto& node5 = m_flowScene.createNode(std::make_unique<OutputValue>(*this));
|
||||||
|
|
@ -154,6 +154,8 @@ Nz::ShaderAst::StatementPtr ShaderGraph::ToAst()
|
||||||
HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr
|
HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr
|
||||||
{
|
{
|
||||||
ShaderNode* shaderNode = static_cast<ShaderNode*>(node->nodeDataModel());
|
ShaderNode* shaderNode = static_cast<ShaderNode*>(node->nodeDataModel());
|
||||||
|
if (shaderNode->validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
throw std::runtime_error(shaderNode->validationMessage().toStdString());
|
||||||
|
|
||||||
qDebug() << shaderNode->name() << node->id();
|
qDebug() << shaderNode->name() << node->id();
|
||||||
if (auto it = variableExpressions.find(node->id()); it != variableExpressions.end())
|
if (auto it = variableExpressions.find(node->id()); it != variableExpressions.end())
|
||||||
|
|
@ -211,21 +213,13 @@ Nz::ShaderAst::StatementPtr ShaderGraph::ToAst()
|
||||||
return expression;
|
return expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
try
|
m_flowScene.iterateOverNodes([&](QtNodes::Node* node)
|
||||||
{
|
{
|
||||||
m_flowScene.iterateOverNodes([&](QtNodes::Node* node)
|
if (node->nodeDataModel()->nPorts(QtNodes::PortType::Out) == 0)
|
||||||
{
|
{
|
||||||
if (node->nodeDataModel()->nPorts(QtNodes::PortType::Out) == 0)
|
statements.emplace_back(Nz::ShaderBuilder::ExprStatement(HandleNode(node)));
|
||||||
{
|
}
|
||||||
statements.emplace_back(Nz::ShaderBuilder::ExprStatement(HandleNode(node)));
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (const std::exception&)
|
|
||||||
{
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_shared<Nz::ShaderAst::StatementBlock>(std::move(statements));
|
return std::make_shared<Nz::ShaderAst::StatementBlock>(std::move(statements));
|
||||||
}
|
}
|
||||||
|
|
@ -265,25 +259,16 @@ void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview)
|
||||||
std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
||||||
{
|
{
|
||||||
auto registry = std::make_shared<QtNodes::DataModelRegistry>();
|
auto registry = std::make_shared<QtNodes::DataModelRegistry>();
|
||||||
RegisterShaderNode<CastVec2ToVec3>(*this, registry, "Casts");
|
RegisterShaderNode<CastToVec2>(*this, registry, "Casts");
|
||||||
RegisterShaderNode<CastVec2ToVec4>(*this, registry, "Casts");
|
RegisterShaderNode<CastToVec3>(*this, registry, "Casts");
|
||||||
RegisterShaderNode<CastVec3ToVec2>(*this, registry, "Casts");
|
RegisterShaderNode<CastToVec4>(*this, registry, "Casts");
|
||||||
RegisterShaderNode<CastVec3ToVec4>(*this, registry, "Casts");
|
|
||||||
RegisterShaderNode<CastVec4ToVec2>(*this, registry, "Casts");
|
|
||||||
RegisterShaderNode<CastVec4ToVec3>(*this, registry, "Casts");
|
|
||||||
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
|
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
|
||||||
RegisterShaderNode<OutputValue>(*this, registry, "Outputs");
|
RegisterShaderNode<OutputValue>(*this, registry, "Outputs");
|
||||||
RegisterShaderNode<SampleTexture>(*this, registry, "Texture");
|
RegisterShaderNode<SampleTexture>(*this, registry, "Texture");
|
||||||
RegisterShaderNode<TextureValue>(*this, registry, "Texture");
|
RegisterShaderNode<TextureValue>(*this, registry, "Texture");
|
||||||
RegisterShaderNode<Vec2Add>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecAdd>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<Vec2Mul>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecMul>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<Vec2Sub>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecSub>(*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<Vec2Value>(*this, registry, "Constants");
|
||||||
RegisterShaderNode<Vec3Value>(*this, registry, "Constants");
|
RegisterShaderNode<Vec3Value>(*this, registry, "Constants");
|
||||||
RegisterShaderNode<Vec4Value>(*this, registry, "Constants");
|
RegisterShaderNode<Vec4Value>(*this, registry, "Constants");
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <nodes/FlowView>
|
#include <nodes/FlowView>
|
||||||
#include <QtWidgets/QDockWidget>
|
#include <QtWidgets/QDockWidget>
|
||||||
#include <QtWidgets/QMenuBar>
|
#include <QtWidgets/QMenuBar>
|
||||||
|
#include <QtWidgets/QMessageBox>
|
||||||
#include <QtWidgets/QTextEdit>
|
#include <QtWidgets/QTextEdit>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -83,15 +84,22 @@ void MainWindow::BuildMenu()
|
||||||
|
|
||||||
void MainWindow::OnCompileToGLSL()
|
void MainWindow::OnCompileToGLSL()
|
||||||
{
|
{
|
||||||
Nz::GlslWriter writer;
|
try
|
||||||
Nz::String glsl = writer.Generate(m_shaderGraph.ToAst());
|
{
|
||||||
|
Nz::GlslWriter writer;
|
||||||
|
Nz::String glsl = writer.Generate(m_shaderGraph.ToAst());
|
||||||
|
|
||||||
std::cout << glsl << std::endl;
|
std::cout << glsl << std::endl;
|
||||||
|
|
||||||
QTextEdit* output = new QTextEdit;
|
QTextEdit* output = new QTextEdit;
|
||||||
output->setReadOnly(true);
|
output->setReadOnly(true);
|
||||||
output->setText(QString::fromUtf8(glsl.GetConstBuffer(), int(glsl.GetSize())));
|
output->setText(QString::fromUtf8(glsl.GetConstBuffer(), int(glsl.GetSize())));
|
||||||
output->setAttribute(Qt::WA_DeleteOnClose, true);
|
output->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
output->setWindowTitle("GLSL Output");
|
output->setWindowTitle("GLSL Output");
|
||||||
output->show();
|
output->show();
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Compilation failed"), QString("Compilation failed: ") + e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue