ShaderNode: Add Mat4x4 type and nodes

This commit is contained in:
Jérôme Leclercq 2020-07-22 14:46:44 +02:00
parent b441bab218
commit 5a350ee76b
17 changed files with 668 additions and 104 deletions

View File

@ -173,22 +173,7 @@ auto BufferField::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIn
const auto& member = RetrieveNestedMember();
assert(std::holds_alternative<PrimitiveType>(member.type));
switch (std::get<PrimitiveType>(member.type))
{
case PrimitiveType::Bool:
return BoolData::Type();
case PrimitiveType::Float1:
return FloatData::Type();
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
return VecData::Type();
}
assert(false);
throw std::runtime_error("Unhandled primitive type");
return ShaderGraph::ToNodeDataType(std::get<PrimitiveType>(member.type));
}
QString BufferField::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
@ -260,6 +245,7 @@ std::shared_ptr<QtNodes::NodeData> BufferField::outData(QtNodes::PortIndex port)
case PrimitiveType::Float2: return std::make_shared<VecData>(2);
case PrimitiveType::Float3: return std::make_shared<VecData>(3);
case PrimitiveType::Float4: return std::make_shared<VecData>(4);
case PrimitiveType::Mat4x4: return std::make_shared<Matrix4Data>();
}
assert(false);

View File

@ -1,6 +1,8 @@
#include <ShaderNode/DataModels/InputValue.hpp>
#include <ShaderNode/ShaderGraph.hpp>
#include <ShaderNode/DataTypes/BoolData.hpp>
#include <ShaderNode/DataTypes/FloatData.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <QtWidgets/QFormLayout>
@ -115,23 +117,7 @@ Nz::ShaderNodes::ExpressionPtr InputValue::GetExpression(Nz::ShaderNodes::Expres
throw std::runtime_error("no input");
const auto& inputEntry = GetGraph().GetInput(*m_currentInputIndex);
Nz::ShaderNodes::BasicType expression = [&]
{
switch (inputEntry.type)
{
case PrimitiveType::Bool: return Nz::ShaderNodes::BasicType::Boolean;
case PrimitiveType::Float1: return Nz::ShaderNodes::BasicType::Float1;
case PrimitiveType::Float2: return Nz::ShaderNodes::BasicType::Float2;
case PrimitiveType::Float3: return Nz::ShaderNodes::BasicType::Float3;
case PrimitiveType::Float4: return Nz::ShaderNodes::BasicType::Float4;
}
assert(false);
throw std::runtime_error("Unhandled input type");
}();
return Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Input(inputEntry.name, expression));
return Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Input(inputEntry.name, ShaderGraph::ToShaderExpressionType(inputEntry.type)));
}
auto InputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType
@ -143,20 +129,7 @@ auto InputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portInd
return VecData::Type();
const auto& inputEntry = GetGraph().GetInput(*m_currentInputIndex);
switch (inputEntry.type)
{
//case InputType::Bool: return Nz::ShaderNodes::BasicType::Boolean;
case PrimitiveType::Float1:
return FloatData::Type();
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
return VecData::Type();
}
assert(false);
throw std::runtime_error("Unhandled input type");
return ShaderGraph::ToNodeDataType(inputEntry.type);
}
std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
@ -170,20 +143,45 @@ std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
const auto& inputEntry = graph.GetInput(*m_currentInputIndex);
const auto& preview = graph.GetPreviewModel();
if (inputEntry.type == PrimitiveType::Float1)
switch (inputEntry.type)
{
auto fData = std::make_shared<FloatData>();
fData->preview = preview.GetPreview(inputEntry.role, inputEntry.roleIndex);
case PrimitiveType::Bool:
{
auto bData = std::make_shared<BoolData>();
bData->preview = preview.GetPreview(inputEntry.role, inputEntry.roleIndex);
return fData;
}
else
{
auto vecData = std::make_shared<VecData>(GetComponentCount(inputEntry.type));
vecData->preview = preview.GetPreview(inputEntry.role, inputEntry.roleIndex);
return bData;
}
return vecData;
case PrimitiveType::Float1:
{
auto fData = std::make_shared<FloatData>();
fData->preview = preview.GetPreview(inputEntry.role, inputEntry.roleIndex);
return fData;
}
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
{
auto vecData = std::make_shared<VecData>(GetComponentCount(inputEntry.type));
vecData->preview = preview.GetPreview(inputEntry.role, inputEntry.roleIndex);
return vecData;
}
case PrimitiveType::Mat4x4:
{
auto matData = std::make_shared<Matrix4Data>();
//TODO: Handle preview
return matData;
}
}
assert(false);
throw std::runtime_error("Unhandled input type");
}
QtNodes::NodeValidationState InputValue::validationState() const

View File

@ -0,0 +1,37 @@
#include <ShaderNode/DataModels/Mat4BinOp.hpp>
QString Mat4Add::caption() const
{
static QString caption = "Matrix4 addition";
return caption;
}
QString Mat4Add::name() const
{
static QString name = "mat4_add";
return name;
}
QString Mat4Mul::caption() const
{
static QString caption = "Matrix4 multiplication";
return caption;
}
QString Mat4Mul::name() const
{
static QString name = "mat4_mul";
return name;
}
QString Mat4Sub::caption() const
{
static QString caption = "Matrix4 subtraction";
return caption;
}
QString Mat4Sub::name() const
{
static QString name = "mat4_sub";
return name;
}

View File

@ -0,0 +1,67 @@
#pragma once
#ifndef NAZARA_SHADERNODES_MAT4BINOP_HPP
#define NAZARA_SHADERNODES_MAT4BINOP_HPP
#include <ShaderNode/DataModels/ShaderNode.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
template<Nz::ShaderNodes::BinaryType BinOp>
class Mat4BinOp : public ShaderNode
{
public:
Mat4BinOp(ShaderGraph& graph);
~Mat4BinOp() = default;
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
unsigned int nPorts(QtNodes::PortType portType) const override;
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
QtNodes::NodeValidationState validationState() const override;
QString validationMessage() const override;
private:
bool ComputePreview(QPixmap& pixmap) override;
void UpdateOutput();
std::shared_ptr<Matrix4Data> m_lhs;
std::shared_ptr<Matrix4Data> m_rhs;
std::shared_ptr<Matrix4Data> m_output;
};
class Mat4Add : public Mat4BinOp<Nz::ShaderNodes::BinaryType::Add>
{
public:
using Mat4BinOp<Nz::ShaderNodes::BinaryType::Add>::Mat4BinOp;
QString caption() const override;
QString name() const override;
};
class Mat4Mul : public Mat4BinOp<Nz::ShaderNodes::BinaryType::Multiply>
{
public:
using Mat4BinOp<Nz::ShaderNodes::BinaryType::Multiply>::Mat4BinOp;
QString caption() const override;
QString name() const override;
};
class Mat4Sub : public Mat4BinOp<Nz::ShaderNodes::BinaryType::Substract>
{
public:
using Mat4BinOp<Nz::ShaderNodes::BinaryType::Substract>::Mat4BinOp;
QString caption() const override;
QString name() const override;
};
#include <ShaderNode/DataModels/Mat4BinOp.inl>
#endif

View File

@ -0,0 +1,131 @@
#include <ShaderNode/DataModels/Mat4BinOp.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
template<Nz::ShaderNodes::BinaryType BinOp>
Mat4BinOp<BinOp>::Mat4BinOp(ShaderGraph& graph) :
ShaderNode(graph)
{
UpdateOutput();
}
template<Nz::ShaderNodes::BinaryType BinOp>
Nz::ShaderNodes::ExpressionPtr Mat4BinOp<BinOp>::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
{
assert(count == 2);
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
constexpr BuilderType builder;
return builder(expressions[0], expressions[1]);
}
template<Nz::ShaderNodes::BinaryType BinOp>
QtNodes::NodeDataType Mat4BinOp<BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
{
assert(portIndex == 0 || portIndex == 1);
return Matrix4Data::Type();
}
template<Nz::ShaderNodes::BinaryType BinOp>
unsigned int Mat4BinOp<BinOp>::nPorts(QtNodes::PortType portType) const
{
switch (portType)
{
case QtNodes::PortType::In: return 2;
case QtNodes::PortType::Out: return 1;
}
return 0;
}
template<Nz::ShaderNodes::BinaryType BinOp>
std::shared_ptr<QtNodes::NodeData> Mat4BinOp<BinOp>::outData(QtNodes::PortIndex port)
{
assert(port == 0);
return m_output;
}
template<Nz::ShaderNodes::BinaryType BinOp>
void Mat4BinOp<BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
{
assert(index == 0 || index == 1);
std::shared_ptr<Matrix4Data> castedValue;
if (value)
{
assert(dynamic_cast<Matrix4Data*>(value.get()) != nullptr);
castedValue = std::static_pointer_cast<Matrix4Data>(value);
}
if (index == 0)
m_lhs = std::move(castedValue);
else
m_rhs = std::move(castedValue);
UpdateOutput();
}
template<Nz::ShaderNodes::BinaryType BinOp>
QtNodes::NodeValidationState Mat4BinOp<BinOp>::validationState() const
{
if (!m_lhs || !m_rhs)
return QtNodes::NodeValidationState::Error;
return QtNodes::NodeValidationState::Valid;
}
template<Nz::ShaderNodes::BinaryType BinOp>
QString Mat4BinOp<BinOp>::validationMessage() const
{
if (!m_lhs || !m_rhs)
return "Missing operands";
return QString();
}
template<Nz::ShaderNodes::BinaryType BinOp>
bool Mat4BinOp<BinOp>::ComputePreview(QPixmap& pixmap)
{
if (!m_lhs || !m_rhs)
return false;
return false;
//pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
//return true;
}
template<Nz::ShaderNodes::BinaryType BinOp>
void Mat4BinOp<BinOp>::UpdateOutput()
{
if (validationState() != QtNodes::NodeValidationState::Valid)
{
m_output = std::make_shared<Matrix4Data>();
return;
}
m_output = std::make_shared<Matrix4Data>();
/*m_output = std::make_shared<VecData>(m_lhs->componentCount);
const PreviewValues& leftPreview = m_lhs->preview;
const PreviewValues& rightPreview = m_rhs->preview;
std::size_t maxWidth = std::max(leftPreview.GetWidth(), rightPreview.GetWidth());
std::size_t maxHeight = std::max(leftPreview.GetHeight(), rightPreview.GetHeight());
// FIXME: Prevent useless copy
PreviewValues leftResized = leftPreview;
if (leftResized.GetWidth() != maxWidth || leftResized.GetHeight() != maxHeight)
leftResized = leftResized.Resized(maxWidth, maxHeight);
PreviewValues rightResized = rightPreview;
if (rightResized.GetWidth() != maxWidth || rightResized.GetHeight() != maxHeight)
rightResized = rightResized.Resized(maxWidth, maxHeight);
m_output->preview = PreviewValues(maxWidth, maxHeight);
ApplyOp(leftResized.GetData(), rightResized.GetData(), m_output->preview.GetData(), maxWidth * maxHeight);*/
Q_EMIT dataUpdated(0);
UpdatePreview();
}

View File

@ -0,0 +1,186 @@
#include <ShaderNode/DataModels/Mat4VecMul.hpp>
#include <Nazara/Renderer/ShaderNodes.hpp>
Mat4VecMul::Mat4VecMul(ShaderGraph& graph) :
ShaderNode(graph)
{
UpdateOutput();
}
Nz::ShaderNodes::ExpressionPtr Mat4VecMul::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
{
assert(count == 2);
using namespace Nz::ShaderNodes;
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
}
QString Mat4VecMul::caption() const
{
static QString caption = "Mat4/Vec multiplication";
return caption;
}
QString Mat4VecMul::name() const
{
static QString name = "mat4vec_mul";
return name;
}
QtNodes::NodeDataType Mat4VecMul::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
{
switch (portType)
{
case QtNodes::PortType::In:
{
assert(portIndex == 0 || portIndex == 1);
switch (portIndex)
{
case 0: return Matrix4Data::Type();
case 1: return VecData::Type();
}
}
case QtNodes::PortType::Out:
{
assert(portIndex == 0);
return VecData::Type();
}
}
assert(false);
throw std::runtime_error("Invalid port type");
}
unsigned int Mat4VecMul::nPorts(QtNodes::PortType portType) const
{
switch (portType)
{
case QtNodes::PortType::In: return 2;
case QtNodes::PortType::Out: return 1;
}
assert(false);
throw std::runtime_error("Invalid port type");
}
std::shared_ptr<QtNodes::NodeData> Mat4VecMul::outData(QtNodes::PortIndex port)
{
assert(port == 0);
return m_output;
}
void Mat4VecMul::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
{
assert(index == 0 || index == 1);
switch (index)
{
case 0:
{
if (value)
{
assert(dynamic_cast<Matrix4Data*>(value.get()) != nullptr);
m_lhs = std::static_pointer_cast<Matrix4Data>(value);
}
else
m_lhs.reset();
break;
}
case 1:
{
if (value)
{
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
m_rhs = std::static_pointer_cast<VecData>(value);
}
else
m_rhs.reset();
break;
}
default:
assert(false);
throw std::runtime_error("Invalid PortType");
}
UpdateOutput();
}
QtNodes::NodeValidationState Mat4VecMul::validationState() const
{
if (!m_lhs || !m_rhs)
return QtNodes::NodeValidationState::Error;
if (m_rhs->componentCount != 4)
return QtNodes::NodeValidationState::Error;
return QtNodes::NodeValidationState::Valid;
}
QString Mat4VecMul::validationMessage() const
{
if (!m_lhs || !m_rhs)
return "Missing operands";
if (m_rhs->componentCount != 4)
return QString("Expected vector with 4 components, got ") + QString::number(m_rhs->componentCount);
return QString();
}
bool Mat4VecMul::ComputePreview(QPixmap& pixmap)
{
if (validationState() != QtNodes::NodeValidationState::Valid)
return false;
pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
return true;
}
void Mat4VecMul::UpdateOutput()
{
if (validationState() != QtNodes::NodeValidationState::Valid)
{
m_output = std::make_shared<VecData>(4);
m_output->preview = PreviewValues(1, 1);
m_output->preview.Fill(Nz::Vector4f::Zero());
return;
}
m_output = std::make_shared<VecData>(4);
m_output->preview = PreviewValues(1, 1);
m_output->preview.Fill(Nz::Vector4f::Zero());
/*m_output = std::make_shared<VecData>(m_rhs->componentCount);
const PreviewValues& leftPreview = m_lhs->preview;
const PreviewValues& rightPreview = m_rhs->preview;
std::size_t maxWidth = std::max(leftPreview.GetWidth(), rightPreview.GetWidth());
std::size_t maxHeight = std::max(leftPreview.GetHeight(), rightPreview.GetHeight());
// FIXME: Prevent useless copy
PreviewValues leftResized = leftPreview;
if (leftResized.GetWidth() != maxWidth || leftResized.GetHeight() != maxHeight)
leftResized = leftResized.Resized(maxWidth, maxHeight);
PreviewValues rightResized = rightPreview;
if (rightResized.GetWidth() != maxWidth || rightResized.GetHeight() != maxHeight)
rightResized = rightResized.Resized(maxWidth, maxHeight);
m_output->preview = PreviewValues(maxWidth, maxHeight);
const Nz::Vector4f* left = leftResized.GetData();
const Nz::Vector4f* right = rightPreview.GetData();
Nz::Vector4f* output = m_output->preview.GetData();
std::size_t pixelCount = maxWidth * maxHeight;
for (std::size_t i = 0; i < pixelCount; ++i)
output[i] = left[i] * right[i];
Q_EMIT dataUpdated(0);
UpdatePreview();*/
}

View File

@ -0,0 +1,43 @@
#pragma once
#ifndef NAZARA_SHADERNODES_MAT4VECMUL_HPP
#define NAZARA_SHADERNODES_MAT4VECMUL_HPP
#include <ShaderNode/DataModels/ShaderNode.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
class Mat4VecMul : public ShaderNode
{
public:
Mat4VecMul(ShaderGraph& graph);
~Mat4VecMul() = default;
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
QString caption() const override;
QString name() const override;
unsigned int nPorts(QtNodes::PortType portType) const override;
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
QtNodes::NodeValidationState validationState() const override;
QString validationMessage() const override;
private:
bool ComputePreview(QPixmap& pixmap) override;
void UpdateOutput();
std::shared_ptr<Matrix4Data> m_lhs;
std::shared_ptr<VecData> m_rhs;
std::shared_ptr<VecData> m_output;
};
#include <ShaderNode/DataModels/VecFloatMul.inl>
#endif

View File

@ -0,0 +1 @@
#include <ShaderNode/DataModels/VecFloatMul.hpp>

View File

@ -1,6 +1,9 @@
#include <ShaderNode/DataModels/OutputValue.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <ShaderNode/ShaderGraph.hpp>
#include <ShaderNode/DataTypes/BoolData.hpp>
#include <ShaderNode/DataTypes/FloatData.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QFormLayout>
@ -62,23 +65,7 @@ Nz::ShaderNodes::ExpressionPtr OutputValue::GetExpression(Nz::ShaderNodes::Expre
throw std::runtime_error("no output");
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
Nz::ShaderNodes::BasicType expression = [&]
{
switch (outputEntry.type)
{
case PrimitiveType::Bool: return Nz::ShaderNodes::BasicType::Boolean;
case PrimitiveType::Float1: return Nz::ShaderNodes::BasicType::Float1;
case PrimitiveType::Float2: return Nz::ShaderNodes::BasicType::Float2;
case PrimitiveType::Float3: return Nz::ShaderNodes::BasicType::Float3;
case PrimitiveType::Float4: return Nz::ShaderNodes::BasicType::Float4;
}
assert(false);
throw std::runtime_error("Unhandled output type");
}();
auto output = Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Output(outputEntry.name, expression));
auto output = Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Output(outputEntry.name, ShaderGraph::ToShaderExpressionType(outputEntry.type)));
return Nz::ShaderBuilder::Assign(std::move(output), *expressions);
}
@ -92,18 +79,7 @@ QtNodes::NodeDataType OutputValue::dataType(QtNodes::PortType portType, QtNodes:
return VecData::Type();
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
switch (outputEntry.type)
{
//case InOutType::Bool: return Nz::ShaderNodes::BasicType::Boolean;
//case InOutType::Float1: return Nz::ShaderNodes::BasicType::Float1;
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
return VecData::Type();
}
assert(false);
throw std::runtime_error("Unhandled output type");
return ShaderGraph::ToNodeDataType(outputEntry.type);
}
unsigned int OutputValue::nPorts(QtNodes::PortType portType) const
@ -124,14 +100,11 @@ std::shared_ptr<QtNodes::NodeData> OutputValue::outData(QtNodes::PortIndex /*por
void OutputValue::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
{
if (!m_currentOutputIndex)
return;
assert(index == 0);
if (value)
{
assert(dynamic_cast<VecData*>(value.get()) != nullptr);
m_input = std::static_pointer_cast<VecData>(value);
}
else
m_input.reset();
m_input = std::move(value);
UpdatePreview();
}
@ -142,8 +115,23 @@ QtNodes::NodeValidationState OutputValue::validationState() const
return QtNodes::NodeValidationState::Error;
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
if (GetComponentCount(outputEntry.type) != m_input->componentCount)
return QtNodes::NodeValidationState::Error;
switch (outputEntry.type)
{
case PrimitiveType::Bool:
case PrimitiveType::Float1:
case PrimitiveType::Mat4x4:
break;
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
{
assert(dynamic_cast<VecData*>(m_input.get()) != nullptr);
const VecData& vec = static_cast<const VecData&>(*m_input);
if (GetComponentCount(outputEntry.type) != vec.componentCount)
return QtNodes::NodeValidationState::Error;
}
}
return QtNodes::NodeValidationState::Valid;
}
@ -157,10 +145,26 @@ QString OutputValue::validationMessage() const
return "Missing input";
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
std::size_t outputComponentCount = GetComponentCount(outputEntry.type);
switch (outputEntry.type)
{
case PrimitiveType::Bool:
case PrimitiveType::Float1:
case PrimitiveType::Mat4x4:
break;
if (m_input->componentCount != outputComponentCount)
return "Incompatible component count (expected " + QString::number(outputComponentCount) + ", got " + QString::number(m_input->componentCount) + ")";
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
{
assert(dynamic_cast<VecData*>(m_input.get()) != nullptr);
const VecData& vec = static_cast<const VecData&>(*m_input);
std::size_t outputComponentCount = GetComponentCount(outputEntry.type);
if (outputComponentCount != vec.componentCount)
return "Incompatible component count (expected " + QString::number(outputComponentCount) + ", got " + QString::number(vec.componentCount) + ")";
}
}
return QString();
}
@ -170,8 +174,49 @@ bool OutputValue::ComputePreview(QPixmap& pixmap)
if (!m_input)
return false;
pixmap = QPixmap::fromImage(m_input->preview.GenerateImage());
return true;
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
switch (outputEntry.type)
{
case PrimitiveType::Bool:
{
assert(dynamic_cast<BoolData*>(m_input.get()) != nullptr);
const BoolData& data = static_cast<const BoolData&>(*m_input);
pixmap = QPixmap::fromImage(data.preview.GenerateImage());
return true;
}
case PrimitiveType::Float1:
{
assert(dynamic_cast<FloatData*>(m_input.get()) != nullptr);
const FloatData& data = static_cast<const FloatData&>(*m_input);
pixmap = QPixmap::fromImage(data.preview.GenerateImage());
return true;
}
case PrimitiveType::Mat4x4:
{
//TODO
/*assert(dynamic_cast<Matrix4Data*>(m_input.get()) != nullptr);
const Matrix4Data& data = static_cast<const Matrix4Data&>(*m_input);*/
return false;
}
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
{
assert(dynamic_cast<VecData*>(m_input.get()) != nullptr);
const VecData& data = static_cast<const VecData&>(*m_input);
pixmap = QPixmap::fromImage(data.preview.GenerateImage());
return true;
}
}
return false;
}
void OutputValue::OnOutputListUpdate()

View File

@ -1,7 +1,7 @@
#pragma once
#ifndef NAZARA_SHADERNODES_FRAGMENTOUTPUT_HPP
#define NAZARA_SHADERNODES_FRAGMENTOUTPUT_HPP
#ifndef NAZARA_SHADERNODES_OUTPUTVALUE_HPP
#define NAZARA_SHADERNODES_OUTPUTVALUE_HPP
#include <ShaderNode/ShaderGraph.hpp>
#include <ShaderNode/DataModels/ShaderNode.hpp>
@ -44,7 +44,7 @@ class OutputValue : public ShaderNode
NazaraSlot(ShaderGraph, OnOutputUpdate, m_onOutputUpdateSlot);
std::optional<std::size_t> m_currentOutputIndex;
std::shared_ptr<VecData> m_input;
std::shared_ptr<QtNodes::NodeData> m_input;
std::string m_currentOutputText;
};

View File

@ -0,0 +1 @@
#include <ShaderNode/DataTypes/Matrix4Data.hpp>

View File

@ -0,0 +1,19 @@
#pragma once
#ifndef NAZARA_SHADERNODES_MATRIXDATA_HPP
#define NAZARA_SHADERNODES_MATRIXDATA_HPP
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <ShaderNode/Previews/PreviewValues.hpp>
#include <nodes/NodeData>
struct Matrix4Data : public QtNodes::NodeData
{
inline QtNodes::NodeDataType type() const override;
static inline QtNodes::NodeDataType Type();
};
#include <ShaderNode/DataTypes/Matrix4Data.inl>
#endif

View File

@ -0,0 +1,11 @@
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
inline QtNodes::NodeDataType Matrix4Data::type() const
{
return Type();
}
inline QtNodes::NodeDataType Matrix4Data::Type()
{
return { "mat4", "Matrix4x4" };
}

View File

@ -10,6 +10,7 @@ std::size_t GetComponentCount(PrimitiveType type)
case PrimitiveType::Float2: return 2;
case PrimitiveType::Float3: return 3;
case PrimitiveType::Float4: return 4;
case PrimitiveType::Mat4x4: return 16;
}
assert(false);
@ -50,6 +51,7 @@ const char* EnumToString(PrimitiveType input)
case PrimitiveType::Float2: return "Float2";
case PrimitiveType::Float3: return "Float3";
case PrimitiveType::Float4: return "Float4";
case PrimitiveType::Mat4x4: return "Mat4x4";
}
assert(false);

View File

@ -35,8 +35,9 @@ enum class PrimitiveType
Float2,
Float3,
Float4,
Mat4x4,
Max = Float4
Max = Mat4x4
};
constexpr std::size_t PrimitiveTypeCount = static_cast<std::size_t>(PrimitiveType::Max) + 1;

View File

@ -8,11 +8,18 @@
#include <ShaderNode/DataModels/SampleTexture.hpp>
#include <ShaderNode/DataModels/ShaderNode.hpp>
#include <ShaderNode/DataModels/TextureValue.hpp>
#include <ShaderNode/DataModels/Mat4BinOp.hpp>
#include <ShaderNode/DataModels/Mat4VecMul.hpp>
#include <ShaderNode/DataModels/VecBinOp.hpp>
#include <ShaderNode/DataModels/VecDot.hpp>
#include <ShaderNode/DataModels/VecFloatMul.hpp>
#include <ShaderNode/DataModels/VecValue.hpp>
#include <ShaderNode/Previews/QuadPreview.hpp>
#include <ShaderNode/DataTypes/BoolData.hpp>
#include <ShaderNode/DataTypes/FloatData.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
#include <ShaderNode/DataTypes/TextureData.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
#include <QtCore/QDebug>
#include <nodes/Node>
#include <nodes/NodeData>
@ -591,6 +598,29 @@ void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview)
OnTexturePreviewUpdate(this, textureIndex);
}
QtNodes::NodeDataType ShaderGraph::ToNodeDataType(PrimitiveType type)
{
switch (type)
{
case PrimitiveType::Bool:
return BoolData::Type();
case PrimitiveType::Float1:
return FloatData::Type();
case PrimitiveType::Float2:
case PrimitiveType::Float3:
case PrimitiveType::Float4:
return VecData::Type();
case PrimitiveType::Mat4x4:
return Matrix4Data::Type();
}
assert(false);
throw std::runtime_error("Unhandled input type");
}
Nz::ShaderExpressionType ShaderGraph::ToShaderExpressionType(PrimitiveType type)
{
switch (type)
@ -600,6 +630,7 @@ Nz::ShaderExpressionType ShaderGraph::ToShaderExpressionType(PrimitiveType type)
case PrimitiveType::Float2: return Nz::ShaderNodes::BasicType::Float2;
case PrimitiveType::Float3: return Nz::ShaderNodes::BasicType::Float3;
case PrimitiveType::Float4: return Nz::ShaderNodes::BasicType::Float4;
case PrimitiveType::Mat4x4: return Nz::ShaderNodes::BasicType::Mat4x4;
}
assert(false);
@ -629,6 +660,10 @@ std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
RegisterShaderNode<OutputValue>(*this, registry, "Outputs");
RegisterShaderNode<SampleTexture>(*this, registry, "Texture");
RegisterShaderNode<TextureValue>(*this, registry, "Texture");
RegisterShaderNode<Mat4Add>(*this, registry, "Matrix operations");
RegisterShaderNode<Mat4Mul>(*this, registry, "Matrix operations");
RegisterShaderNode<Mat4Sub>(*this, registry, "Matrix operations");
RegisterShaderNode<Mat4VecMul>(*this, registry, "Matrix operations");
RegisterShaderNode<VecAdd>(*this, registry, "Vector operations");
RegisterShaderNode<VecDiv>(*this, registry, "Vector operations");
RegisterShaderNode<VecDot>(*this, registry, "Vector operations");

View File

@ -122,6 +122,7 @@ class ShaderGraph
NazaraSignal(OnTexturePreviewUpdate, ShaderGraph*, std::size_t /*textureIndex*/);
NazaraSignal(OnTextureUpdate, ShaderGraph*, std::size_t /*textureIndex*/);
static QtNodes::NodeDataType ToNodeDataType(PrimitiveType type);
static Nz::ShaderExpressionType ToShaderExpressionType(PrimitiveType type);
static Nz::ShaderExpressionType ToShaderExpressionType(TextureType type);