Renderer/ShaderAst: Add Cast node

This commit is contained in:
Lynix 2017-01-06 00:49:24 +01:00
parent a84391cf08
commit 2a57af9896
8 changed files with 124 additions and 0 deletions

View File

@ -36,6 +36,7 @@ namespace Nz
void Write(const ShaderAst::Branch& node) override;
void Write(const ShaderAst::BinaryOp& node) override;
void Write(const ShaderAst::BuiltinVariable& node) override;
void Write(const ShaderAst::Cast& node) override;
void Write(const ShaderAst::Constant& node) override;
void Write(const ShaderAst::ExpressionStatement& node) override;
void Write(const ShaderAst::NamedVariable& node) override;

View File

@ -14,6 +14,7 @@
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <array>
#include <memory>
namespace Nz
@ -76,6 +77,9 @@ namespace Nz
virtual void Register(ShaderWriter& visitor) = 0;
virtual void Visit(ShaderWriter& visitor) = 0;
static inline unsigned int GetComponentCount(ExpressionType type);
static inline ExpressionType GetComponentType(ExpressionType type);
};
class Statement;
@ -209,6 +213,19 @@ namespace Nz
StatementPtr elseStatement;
};
class NAZARA_RENDERER_API Cast : public Expression
{
public:
inline Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
ExpressionType exprType;
std::array<ExpressionPtr, 4> expressions;
};
class NAZARA_RENDERER_API Constant : public Expression
{
public:

View File

@ -10,6 +10,38 @@ namespace Nz
{
namespace ShaderAst
{
inline unsigned int Node::GetComponentCount(ExpressionType type)
{
switch (type)
{
case ExpressionType::Float2:
return 2;
case ExpressionType::Float3:
return 3;
case ExpressionType::Float4:
return 4;
default:
return 1;
}
}
inline ExpressionType Node::GetComponentType(ExpressionType type)
{
switch (type)
{
case ExpressionType::Float2:
case ExpressionType::Float3:
case ExpressionType::Float4:
return ExpressionType::Float1;
default:
return type;
}
}
inline ExpressionStatement::ExpressionStatement(ExpressionPtr expr) :
expression(std::move(expr))
{
@ -62,6 +94,25 @@ namespace Nz
elseStatement = std::move(falseStatement);
}
inline Cast::Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second, ExpressionPtr third, ExpressionPtr fourth) :
exprType(castTo),
expressions({first, second, third, fourth})
{
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");
}
inline Constant::Constant(float value) :
exprType(ExpressionType::Float1)
{

View File

@ -58,6 +58,8 @@ namespace Nz { namespace ShaderBuilder
constexpr BinOpBuilder<ShaderAst::BinaryType::Substract> Substract;
constexpr VarBuilder<ShaderAst::VariableType::Uniform> Uniform;
constexpr VarBuilder<ShaderAst::VariableType::Variable> Variable;
template<ShaderAst::ExpressionType Type, typename... Args> std::shared_ptr<ShaderAst::Cast> Cast(Args&&... args);
} }
#include <Nazara/Renderer/ShaderBuilder.inl>

View File

@ -48,6 +48,12 @@ namespace Nz { namespace ShaderBuilder
{
return std::make_shared<ShaderAst::NamedVariable>(type, std::forward<Args>(args)...);
}
template<ShaderAst::ExpressionType Type, typename... Args>
std::shared_ptr<ShaderAst::Cast> Cast(Args&&... args)
{
return std::make_shared<ShaderAst::Cast>(Type, std::forward<Args>(args)...);
}
} }
#include <Nazara/Renderer/DebugOff.hpp>

View File

@ -30,6 +30,7 @@ namespace Nz
virtual void Write(const ShaderAst::Branch& node) = 0;
virtual void Write(const ShaderAst::BinaryOp& node) = 0;
virtual void Write(const ShaderAst::BuiltinVariable& node) = 0;
virtual void Write(const ShaderAst::Cast& node) = 0;
virtual void Write(const ShaderAst::Constant& node) = 0;
virtual void Write(const ShaderAst::ExpressionStatement& node) = 0;
virtual void Write(const ShaderAst::NamedVariable& node) = 0;

View File

@ -198,6 +198,28 @@ namespace Nz
Append(node.var);
}
void GlslWriter::Write(const ShaderAst::Cast& node)
{
Append(node.exprType);
Append("(");
unsigned int i = 0;
unsigned int requiredComponents = ShaderAst::Node::GetComponentCount(node.exprType);
while (requiredComponents > 0)
{
if (i != 0)
m_currentState->stream << ", ";
const auto& exprPtr = node.expressions[i++];
NazaraAssert(exprPtr, "Invalid expression");
Write(exprPtr);
requiredComponents -= ShaderAst::Node::GetComponentCount(exprPtr->GetExpressionType());
}
Append(")");
}
void GlslWriter::Write(const ShaderAst::Constant& node)
{
switch (node.exprType)

View File

@ -139,5 +139,29 @@ namespace Nz { namespace ShaderAst
{
visitor.Write(*this);
}
ExpressionType Cast::GetExpressionType() const
{
return exprType;
}
void Cast::Register(ShaderWriter& visitor)
{
auto it = expressions.begin();
(*it)->Register(visitor);
for (; it != expressions.end(); ++it)
{
if (!*it)
break;
(*it)->Register(visitor);
}
}
void Cast::Visit(ShaderWriter& visitor)
{
visitor.Write(*this);
}
}
}