diff --git a/include/Nazara/Renderer/GlslWriter.hpp b/include/Nazara/Renderer/GlslWriter.hpp index d7229f1d9..d423286db 100644 --- a/include/Nazara/Renderer/GlslWriter.hpp +++ b/include/Nazara/Renderer/GlslWriter.hpp @@ -41,6 +41,7 @@ namespace Nz unsigned int glMajorVersion = 3; unsigned int glMinorVersion = 0; bool glES = false; + bool flipYPosition = false; }; private: diff --git a/include/Nazara/Renderer/ShaderAstCloner.hpp b/include/Nazara/Renderer/ShaderAstCloner.hpp index ff1f9c5a4..c8b61b02c 100644 --- a/include/Nazara/Renderer/ShaderAstCloner.hpp +++ b/include/Nazara/Renderer/ShaderAstCloner.hpp @@ -28,7 +28,7 @@ namespace Nz ShaderAstCloner& operator=(const ShaderAstCloner&) = default; ShaderAstCloner& operator=(ShaderAstCloner&&) = default; - private: + protected: ShaderNodes::ExpressionPtr CloneExpression(const ShaderNodes::ExpressionPtr& expr); ShaderNodes::StatementPtr CloneStatement(const ShaderNodes::StatementPtr& statement); ShaderNodes::VariablePtr CloneVariable(const ShaderNodes::VariablePtr& statement); @@ -62,6 +62,7 @@ namespace Nz ShaderNodes::StatementPtr PopStatement(); ShaderNodes::VariablePtr PopVariable(); + private: std::vector m_expressionStack; std::vector m_statementStack; std::vector m_variableStack; diff --git a/src/Nazara/OpenGLRenderer/OpenGLShaderStage.cpp b/src/Nazara/OpenGLRenderer/OpenGLShaderStage.cpp index 07f6de975..7f6e92a34 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLShaderStage.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLShaderStage.cpp @@ -45,6 +45,7 @@ namespace Nz { return context.IsExtensionSupported(std::string(ext)); }; + env.flipYPosition = true; GlslWriter writer; writer.SetEnv(env); diff --git a/src/Nazara/Renderer/GlslWriter.cpp b/src/Nazara/Renderer/GlslWriter.cpp index 3d651a84f..f851a3aa0 100644 --- a/src/Nazara/Renderer/GlslWriter.cpp +++ b/src/Nazara/Renderer/GlslWriter.cpp @@ -5,12 +5,44 @@ #include #include #include +#include +#include #include #include #include namespace Nz { + namespace + { + struct AstAdapter : ShaderAstCloner + { + void Visit(ShaderNodes::AssignOp& node) override + { + if (!flipYPosition) + return ShaderAstCloner::Visit(node); + + if (node.left->GetType() != ShaderNodes::NodeType::Identifier) + return ShaderAstCloner::Visit(node); + + const auto& identifier = static_cast(*node.left); + if (identifier.var->GetType() != ShaderNodes::VariableType::BuiltinVariable) + return ShaderAstCloner::Visit(node); + + const auto& builtinVar = static_cast(*identifier.var); + if (builtinVar.entry != ShaderNodes::BuiltinEntry::VertexPosition) + return ShaderAstCloner::Visit(node); + + auto fixYConstant = ShaderBuilder::Constant(Nz::Vector4f(1.f, -1.f, 1.f, 1.f)); + auto mulFix = ShaderBuilder::Multiply(CloneExpression(node.right), fixYConstant); + + PushExpression(ShaderNodes::AssignOp::Build(node.op, CloneExpression(node.left), mulFix)); + } + + bool flipYPosition = false; + }; + } + GlslWriter::GlslWriter() : m_currentState(nullptr) { @@ -237,7 +269,10 @@ namespace Nz EnterScope(); { - Visit(func.statement); + AstAdapter adapter; + adapter.flipYPosition = m_environment.flipYPosition; + + Visit(adapter.Clone(func.statement)); } LeaveScope(); }