ShaderEditor: Add VecFloatMul
This commit is contained in:
parent
80527dec3e
commit
463b540739
|
|
@ -0,0 +1,183 @@
|
||||||
|
#include <ShaderNode/DataModels/VecFloatMul.hpp>
|
||||||
|
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||||
|
|
||||||
|
VecFloatMul::VecFloatMul(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::ShaderAst::ExpressionPtr VecFloatMul::GetExpression(Nz::ShaderAst::ExpressionPtr* expressions, std::size_t count) const
|
||||||
|
{
|
||||||
|
assert(count == 2);
|
||||||
|
using namespace Nz::ShaderAst;
|
||||||
|
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecFloatMul::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Float/vector multiplication";
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecFloatMul::name() const
|
||||||
|
{
|
||||||
|
static QString name = "vecfloat_mul";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeDataType VecFloatMul::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
switch (portIndex)
|
||||||
|
{
|
||||||
|
case 0: return FloatData::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 VecFloatMul::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> VecFloatMul::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
assert(port == 0);
|
||||||
|
return m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecFloatMul::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
{
|
||||||
|
assert(index == 0 || index == 1);
|
||||||
|
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<FloatData*>(value.get()) != nullptr);
|
||||||
|
|
||||||
|
m_lhs = std::static_pointer_cast<FloatData>(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 VecFloatMul::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecFloatMul::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return "Missing operands";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VecFloatMul::ComputePreview(QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pixmap = QPixmap::fromImage(m_output->preview);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecFloatMul::UpdateOutput()
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
{
|
||||||
|
m_output = std::make_shared<VecData>(4);
|
||||||
|
m_output->preview = QImage(1, 1, QImage::Format_RGBA8888);
|
||||||
|
m_output->preview.fill(QColor::fromRgb(0, 0, 0, 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output = std::make_shared<VecData>(m_rhs->componentCount);
|
||||||
|
|
||||||
|
const QImage& leftPreview = m_lhs->preview;
|
||||||
|
const QImage& rightPreview = m_rhs->preview;
|
||||||
|
int maxWidth = std::max(leftPreview.width(), rightPreview.width());
|
||||||
|
int maxHeight = std::max(leftPreview.height(), rightPreview.height());
|
||||||
|
|
||||||
|
// Exploit COW
|
||||||
|
QImage leftResized = leftPreview;
|
||||||
|
if (leftResized.width() != maxWidth || leftResized.height() != maxHeight)
|
||||||
|
leftResized = leftResized.scaled(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
QImage rightResized = rightPreview;
|
||||||
|
if (rightResized.width() != maxWidth || rightResized.height() != maxHeight)
|
||||||
|
rightResized = rightResized.scaled(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
m_output->preview = QImage(maxWidth, maxHeight, QImage::Format_RGBA8888);
|
||||||
|
|
||||||
|
const uchar* left = leftResized.constBits();
|
||||||
|
const uchar* right = rightPreview.constBits();
|
||||||
|
uchar* output = m_output->preview.bits();
|
||||||
|
|
||||||
|
std::size_t pixelCount = maxWidth * maxHeight * 4;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_VECFLOATMUL_HPP
|
||||||
|
#define NAZARA_SHADERNODES_VECFLOATMUL_HPP
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
|
class VecFloatMul : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VecFloatMul(ShaderGraph& graph);
|
||||||
|
~VecFloatMul() = default;
|
||||||
|
|
||||||
|
Nz::ShaderAst::ExpressionPtr GetExpression(Nz::ShaderAst::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<FloatData> m_lhs;
|
||||||
|
std::shared_ptr<VecData> m_rhs;
|
||||||
|
std::shared_ptr<VecData> m_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/VecFloatMul.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include <ShaderNode/DataModels/VecFloatMul.hpp>
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <ShaderNode/DataModels/TextureValue.hpp>
|
#include <ShaderNode/DataModels/TextureValue.hpp>
|
||||||
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
||||||
#include <ShaderNode/DataModels/VecDot.hpp>
|
#include <ShaderNode/DataModels/VecDot.hpp>
|
||||||
|
#include <ShaderNode/DataModels/VecFloatMul.hpp>
|
||||||
#include <ShaderNode/DataModels/VecValue.hpp>
|
#include <ShaderNode/DataModels/VecValue.hpp>
|
||||||
#include <ShaderNode/Previews/QuadPreview.hpp>
|
#include <ShaderNode/Previews/QuadPreview.hpp>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
@ -402,6 +403,7 @@ std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
||||||
RegisterShaderNode<VecAdd>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecAdd>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<VecDiv>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecDiv>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<VecDot>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecDot>(*this, registry, "Vector operations");
|
||||||
|
RegisterShaderNode<VecFloatMul>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<VecMul>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecMul>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<VecSub>(*this, registry, "Vector operations");
|
RegisterShaderNode<VecSub>(*this, registry, "Vector operations");
|
||||||
RegisterShaderNode<Vec2Value>(*this, registry, "Constants");
|
RegisterShaderNode<Vec2Value>(*this, registry, "Constants");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue