diff --git a/include/Nazara/Renderer/GlslWriter.hpp b/include/Nazara/Renderer/GlslWriter.hpp index 39a557040..bbd485dc1 100644 --- a/include/Nazara/Renderer/GlslWriter.hpp +++ b/include/Nazara/Renderer/GlslWriter.hpp @@ -44,20 +44,24 @@ namespace Nz private: struct Function; + using VariableContainer = std::set>; void Append(ShaderAst::Builtin builtin); void Append(ShaderAst::ExpressionType type); void Append(const String& txt); void AppendCommentSection(const String& section); void AppendFunction(Function& func); - void AppendLine(const Nz::String& txt = Nz::String()); + void AppendLine(const String& txt = String()); + + void DeclareVariables(const VariableContainer& variables, const String& keyword = String(), const String& section = String()); void EnterScope(); void LeaveScope(); + struct Function { - std::set> variables; + VariableContainer variables; std::vector parameters; ShaderAst::ExpressionType retType; ShaderAst::StatementPtr node; @@ -66,7 +70,9 @@ namespace Nz struct State { - std::set> m_uniforms; + VariableContainer inputs; + VariableContainer outputs; + VariableContainer uniforms; StringStream stream; unsigned int indentLevel = 0; }; diff --git a/include/Nazara/Renderer/ShaderAst.hpp b/include/Nazara/Renderer/ShaderAst.hpp index c32d3af9f..87c00548e 100644 --- a/include/Nazara/Renderer/ShaderAst.hpp +++ b/include/Nazara/Renderer/ShaderAst.hpp @@ -55,9 +55,11 @@ namespace Nz enum class VariableType { Builtin, + Input, + Output, Parameter, - Variable, - Uniform + Uniform, + Variable }; ////////////////////////////////////////////////////////////////////////// diff --git a/include/Nazara/Renderer/ShaderBuilder.hpp b/include/Nazara/Renderer/ShaderBuilder.hpp index 5bf2dcaff..04394328e 100644 --- a/include/Nazara/Renderer/ShaderBuilder.hpp +++ b/include/Nazara/Renderer/ShaderBuilder.hpp @@ -50,6 +50,8 @@ namespace Nz { namespace ShaderBuilder constexpr GenBuilder Branch; constexpr GenBuilder Constant; constexpr GenBuilder ExprStatement; + constexpr VarBuilder Input; + constexpr VarBuilder Output; constexpr VarBuilder Parameter; constexpr VarBuilder Uniform; constexpr VarBuilder Variable; diff --git a/src/Nazara/Renderer/GlslWriter.cpp b/src/Nazara/Renderer/GlslWriter.cpp index 63a1ad488..34a8cb867 100644 --- a/src/Nazara/Renderer/GlslWriter.cpp +++ b/src/Nazara/Renderer/GlslWriter.cpp @@ -31,23 +31,10 @@ namespace Nz AppendLine(String::Number(m_glslVersion)); AppendLine(); - // Uniforms - if (!state.m_uniforms.empty()) - { - AppendCommentSection("Uniforms"); - AppendLine(); - - for (const auto& pair : state.m_uniforms) - { - Append("uniform "); - Append(pair.first); - Append(" "); - Append(pair.second); - AppendLine(";"); - } - - AppendLine(); - } + // Global variables (uniforms, input and outputs) + DeclareVariables(state.uniforms, "uniform", "Uniforms"); + DeclareVariables(state.inputs, "in", "Inputs"); + DeclareVariables(state.outputs, "out", "Outputs"); Function entryPoint; entryPoint.name = "main"; //< GLSL has only one entry point name possible @@ -73,9 +60,18 @@ namespace Nz void GlslWriter::RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) { NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + NazaraAssert(kind != ShaderAst::VariableType::Builtin, "Builtin variables should not be registered"); switch (kind) { + case ShaderAst::VariableType::Input: + m_currentState->inputs.insert(std::make_pair(type, name)); + break; + + case ShaderAst::VariableType::Output: + m_currentState->outputs.insert(std::make_pair(type, name)); + break; + case ShaderAst::VariableType::Parameter: { if (m_currentFunction) @@ -105,7 +101,7 @@ namespace Nz } case ShaderAst::VariableType::Uniform: - m_currentState->m_uniforms.insert(std::make_pair(type, name)); + m_currentState->uniforms.insert(std::make_pair(type, name)); break; case ShaderAst::VariableType::Variable: @@ -320,15 +316,7 @@ namespace Nz EnterScope(); { - for (const auto& pair : func.variables) - { - Append(pair.first); - Append(" "); - Append(pair.second); - AppendLine(";"); - } - - AppendLine(); + DeclareVariables(func.variables); Write(func.node); } @@ -342,6 +330,34 @@ namespace Nz m_currentState->stream << txt << '\n' << String(m_currentState->indentLevel, '\t'); } + void GlslWriter::DeclareVariables(const VariableContainer& variables, const String& keyword, const String& section) + { + if (!variables.empty()) + { + if (!section.IsEmpty()) + { + AppendCommentSection("Uniforms"); + AppendLine(); + } + + for (const auto& pair : variables) + { + if (!keyword.IsEmpty()) + { + Append(keyword); + Append(" "); + } + + Append(pair.first); + Append(" "); + Append(pair.second); + AppendLine(";"); + } + + AppendLine(); + } + } + void GlslWriter::EnterScope() { NazaraAssert(m_currentState, "This function should only be called while processing an AST");