diff --git a/include/Nazara/Renderer/GlslWriter.hpp b/include/Nazara/Renderer/GlslWriter.hpp index ce9d46420..21153c6be 100644 --- a/include/Nazara/Renderer/GlslWriter.hpp +++ b/include/Nazara/Renderer/GlslWriter.hpp @@ -42,6 +42,7 @@ namespace Nz void Write(const ShaderAst::NamedVariable& node) override; void Write(const ShaderAst::NodePtr& node) override; void Write(const ShaderAst::StatementBlock& node) override; + void Write(const ShaderAst::SwizzleOp& node) override; private: struct Function; diff --git a/include/Nazara/Renderer/ShaderAst.hpp b/include/Nazara/Renderer/ShaderAst.hpp index c88fc10df..0435c32ee 100644 --- a/include/Nazara/Renderer/ShaderAst.hpp +++ b/include/Nazara/Renderer/ShaderAst.hpp @@ -54,6 +54,14 @@ namespace Nz Void // void }; + enum class SwizzleComponent + { + First, + Second, + Third, + Fourth + }; + enum class VariableType { Builtin, @@ -139,6 +147,19 @@ namespace Nz VariableType kind; }; + + class NAZARA_RENDERER_API BuiltinVariable : public Variable + { + public: + inline BuiltinVariable(BuiltinEntry variable, ExpressionType varType); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + BuiltinEntry var; + }; + + class NamedVariable; using NamedVariablePtr = std::shared_ptr; @@ -154,17 +175,6 @@ namespace Nz Nz::String name; }; - class NAZARA_RENDERER_API BuiltinVariable : public Variable - { - public: - inline BuiltinVariable(BuiltinEntry variable, ExpressionType varType); - - void Register(ShaderWriter& visitor) override; - void Visit(ShaderWriter& visitor) override; - - BuiltinEntry var; - }; - ////////////////////////////////////////////////////////////////////////// class NAZARA_RENDERER_API AssignOp : public Expression @@ -250,6 +260,20 @@ namespace Nz Vector4f vec4; } values; }; + + class NAZARA_RENDERER_API SwizzleOp : public Expression + { + public: + inline SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list swizzleComponents); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + std::array components; + std::size_t componentCount; + ExpressionPtr expression; + }; } } diff --git a/include/Nazara/Renderer/ShaderAst.inl b/include/Nazara/Renderer/ShaderAst.inl index 4587ca87c..b23078f0a 100644 --- a/include/Nazara/Renderer/ShaderAst.inl +++ b/include/Nazara/Renderer/ShaderAst.inl @@ -24,7 +24,7 @@ namespace Nz return 4; case ExpressionType::Mat4x4: - return 16; + return 4; default: return 1; @@ -38,9 +38,11 @@ namespace Nz case ExpressionType::Float2: case ExpressionType::Float3: case ExpressionType::Float4: - case ExpressionType::Mat4x4: return ExpressionType::Float1; + case ExpressionType::Mat4x4: + return ExpressionType::Float4; + default: return type; } @@ -63,18 +65,18 @@ namespace Nz { } - inline NamedVariable::NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType) : - Variable(varKind, varType), - name(varName) - { - } - inline BuiltinVariable::BuiltinVariable(BuiltinEntry variable, ExpressionType varType) : Variable(VariableType::Builtin, varType), var(variable) { } + inline NamedVariable::NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType) : + Variable(varKind, varType), + name(varName) + { + } + inline AssignOp::AssignOp(AssignType Op, VariablePtr Var, ExpressionPtr Right) : op(Op), variable(std::move(Var)), @@ -197,6 +199,28 @@ namespace Nz { values.vec4 = value; } + + inline SwizzleOp::SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list swizzleComponents) : + componentCount(swizzleComponents.size()), + expression(expressionPtr) + { + if (componentCount > 4) + throw std::runtime_error("Cannot swizzle more than four elements"); + + switch (expressionPtr->GetExpressionType()) + { + case ExpressionType::Float1: + case ExpressionType::Float2: + case ExpressionType::Float3: + case ExpressionType::Float4: + break; + + default: + throw std::runtime_error("Cannot swizzle this type"); + } + + std::copy(swizzleComponents.begin(), swizzleComponents.end(), components.begin()); + } } } diff --git a/include/Nazara/Renderer/ShaderBuilder.hpp b/include/Nazara/Renderer/ShaderBuilder.hpp index feca4b72b..0cfefca7e 100644 --- a/include/Nazara/Renderer/ShaderBuilder.hpp +++ b/include/Nazara/Renderer/ShaderBuilder.hpp @@ -65,6 +65,7 @@ namespace Nz { namespace ShaderBuilder constexpr BinOpBuilder Multiply; constexpr VarBuilder Output; constexpr VarBuilder Parameter; + constexpr GenBuilder Swizzle; constexpr BinOpBuilder Substract; constexpr VarBuilder Uniform; constexpr VarBuilder Variable; diff --git a/include/Nazara/Renderer/ShaderWriter.hpp b/include/Nazara/Renderer/ShaderWriter.hpp index 3c17bf936..35baf3959 100644 --- a/include/Nazara/Renderer/ShaderWriter.hpp +++ b/include/Nazara/Renderer/ShaderWriter.hpp @@ -36,6 +36,7 @@ namespace Nz virtual void Write(const ShaderAst::NamedVariable& node) = 0; virtual void Write(const ShaderAst::NodePtr& node) = 0; virtual void Write(const ShaderAst::StatementBlock& node) = 0; + virtual void Write(const ShaderAst::SwizzleOp& node) = 0; }; } diff --git a/src/Nazara/Renderer/GlslWriter.cpp b/src/Nazara/Renderer/GlslWriter.cpp index 1c856f8eb..074082165 100644 --- a/src/Nazara/Renderer/GlslWriter.cpp +++ b/src/Nazara/Renderer/GlslWriter.cpp @@ -278,6 +278,34 @@ namespace Nz } } + void GlslWriter::Write(const ShaderAst::SwizzleOp& node) + { + Write(node.expression); + Append("."); + + for (std::size_t i = 0; i < node.componentCount; ++i) + { + switch (node.components[i]) + { + case ShaderAst::SwizzleComponent::First: + Append("x"); + break; + + case ShaderAst::SwizzleComponent::Second: + Append("y"); + break; + + case ShaderAst::SwizzleComponent::Third: + Append("z"); + break; + + case ShaderAst::SwizzleComponent::Fourth: + Append("w"); + break; + } + } + } + void GlslWriter::Append(ShaderAst::BuiltinEntry builtin) { switch (builtin) diff --git a/src/Nazara/Renderer/ShaderAst.cpp b/src/Nazara/Renderer/ShaderAst.cpp index 08e2189f1..71b4b27cf 100644 --- a/src/Nazara/Renderer/ShaderAst.cpp +++ b/src/Nazara/Renderer/ShaderAst.cpp @@ -163,5 +163,21 @@ namespace Nz { namespace ShaderAst { visitor.Write(*this); } + + + ExpressionType ShaderAst::SwizzleOp::GetExpressionType() const + { + return GetComponentType(expression->GetExpressionType()); + } + + void SwizzleOp::Register(ShaderWriter& visitor) + { + expression->Register(visitor); + } + + void SwizzleOp::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } } }