Merge branch 'master' into vulkan
This commit is contained in:
451
src/Nazara/Renderer/GlslWriter.cpp
Normal file
451
src/Nazara/Renderer/GlslWriter.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/GlslWriter.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
GlslWriter::GlslWriter() :
|
||||
m_currentFunction(nullptr),
|
||||
m_currentState(nullptr),
|
||||
m_glslVersion(110)
|
||||
{
|
||||
}
|
||||
|
||||
String GlslWriter::Generate(const ShaderAst::StatementPtr& node)
|
||||
{
|
||||
State state;
|
||||
m_currentState = &state;
|
||||
CallOnExit onExit([this]()
|
||||
{
|
||||
m_currentState = nullptr;
|
||||
});
|
||||
|
||||
// Register global variables (uniforms, varying, ..)
|
||||
node->Register(*this);
|
||||
|
||||
// Header
|
||||
Append("#version ");
|
||||
AppendLine(String::Number(m_glslVersion));
|
||||
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
|
||||
entryPoint.node = node;
|
||||
entryPoint.retType = ShaderAst::ExpressionType::Void;
|
||||
|
||||
AppendFunction(entryPoint);
|
||||
|
||||
return state.stream;
|
||||
}
|
||||
|
||||
void GlslWriter::RegisterFunction(const String& name, ShaderAst::StatementPtr statement, std::initializer_list<ShaderAst::NamedVariablePtr> parameters, ShaderAst::ExpressionType retType)
|
||||
{
|
||||
Function func;
|
||||
func.retType = retType;
|
||||
func.name = name;
|
||||
func.node = std::move(statement);
|
||||
func.parameters.assign(parameters);
|
||||
|
||||
m_functions[name] = std::move(func);
|
||||
}
|
||||
|
||||
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::Builtin: //< Only there to make compiler happy
|
||||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
bool found = false;
|
||||
for (const auto& varPtr : m_currentFunction->parameters)
|
||||
{
|
||||
if (varPtr->name == name)
|
||||
{
|
||||
found = true;
|
||||
if (varPtr->type != type)
|
||||
{
|
||||
//TODO: AstParseError
|
||||
throw std::runtime_error("Function uses parameter \"" + name + "\" with a different type than specified in the function arguments");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
//TODO: AstParseError
|
||||
throw std::runtime_error("Function has no parameter \"" + name + "\"");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderAst::VariableType::Uniform:
|
||||
m_currentState->uniforms.insert(std::make_pair(type, name));
|
||||
break;
|
||||
|
||||
case ShaderAst::VariableType::Variable:
|
||||
{
|
||||
if (m_currentFunction)
|
||||
m_currentFunction->variables.insert(std::make_pair(type, name));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlslWriter::SetGlslVersion(unsigned int version)
|
||||
{
|
||||
m_glslVersion = version;
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::NodePtr& node)
|
||||
{
|
||||
node->Visit(*this);
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::AssignOp& node)
|
||||
{
|
||||
Write(node.variable);
|
||||
|
||||
switch (node.op)
|
||||
{
|
||||
case ShaderAst::AssignType::Simple:
|
||||
Append(" = ");
|
||||
break;
|
||||
}
|
||||
|
||||
Write(node.right);
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::Branch& node)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& statement : node.condStatements)
|
||||
{
|
||||
if (!first)
|
||||
Append("else ");
|
||||
|
||||
Append("if (");
|
||||
Write(statement.condition);
|
||||
AppendLine(")");
|
||||
|
||||
EnterScope();
|
||||
Write(statement.statement);
|
||||
LeaveScope();
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (node.elseStatement)
|
||||
{
|
||||
AppendLine("else");
|
||||
|
||||
EnterScope();
|
||||
Write(node.elseStatement);
|
||||
LeaveScope();
|
||||
}
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::BinaryOp& node)
|
||||
{
|
||||
Write(node.left);
|
||||
|
||||
switch (node.op)
|
||||
{
|
||||
case ShaderAst::BinaryType::Add:
|
||||
Append(" + ");
|
||||
break;
|
||||
case ShaderAst::BinaryType::Substract:
|
||||
Append(" - ");
|
||||
break;
|
||||
case ShaderAst::BinaryType::Multiply:
|
||||
Append(" * ");
|
||||
break;
|
||||
case ShaderAst::BinaryType::Divide:
|
||||
Append(" / ");
|
||||
break;
|
||||
case ShaderAst::BinaryType::Equality:
|
||||
Append(" == ");
|
||||
break;
|
||||
}
|
||||
|
||||
Write(node.right);
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::BuiltinVariable& node)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case ShaderAst::ExpressionType::Boolean:
|
||||
Append((node.values.bool1) ? "true" : "false");
|
||||
break;
|
||||
|
||||
case ShaderAst::ExpressionType::Float1:
|
||||
Append(String::Format("%F", node.values.vec1));
|
||||
break;
|
||||
|
||||
case ShaderAst::ExpressionType::Float2:
|
||||
Append(String::Format("vec2(%F, %F)", node.values.vec2.x, node.values.vec2.y));
|
||||
break;
|
||||
|
||||
case ShaderAst::ExpressionType::Float3:
|
||||
Append(String::Format("vec3(%F, %F, %F)", node.values.vec3.x, node.values.vec3.y, node.values.vec3.z));
|
||||
break;
|
||||
|
||||
case ShaderAst::ExpressionType::Float4:
|
||||
Append(String::Format("vec4(%F, %F, %F, %F)", node.values.vec4.x, node.values.vec4.y, node.values.vec4.z, node.values.vec4.w));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("Unhandled expression type");
|
||||
}
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::ExpressionStatement& node)
|
||||
{
|
||||
Write(node.expression);
|
||||
Append(";");
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::NamedVariable& node)
|
||||
{
|
||||
Append(node.name);
|
||||
}
|
||||
|
||||
void GlslWriter::Write(const ShaderAst::StatementBlock& node)
|
||||
{
|
||||
bool first = true;
|
||||
for (const ShaderAst::StatementPtr& statement : node.statements)
|
||||
{
|
||||
if (!first)
|
||||
AppendLine();
|
||||
|
||||
Write(statement);
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case ShaderAst::BuiltinEntry::VertexPosition:
|
||||
Append("gl_Position");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GlslWriter::Append(ShaderAst::ExpressionType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ShaderAst::ExpressionType::Boolean:
|
||||
Append("bool");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Float1:
|
||||
Append("float");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Float2:
|
||||
Append("vec2");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Float3:
|
||||
Append("vec3");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Float4:
|
||||
Append("vec4");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Mat4x4:
|
||||
Append("mat4");
|
||||
break;
|
||||
case ShaderAst::ExpressionType::Void:
|
||||
Append("void");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GlslWriter::Append(const String& txt)
|
||||
{
|
||||
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
|
||||
|
||||
m_currentState->stream << txt;
|
||||
}
|
||||
|
||||
void GlslWriter::AppendCommentSection(const String& section)
|
||||
{
|
||||
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
|
||||
|
||||
String stars((section.GetSize() < 33) ? (36 - section.GetSize()) / 2 : 3, '*');
|
||||
m_currentState->stream << "/*" << stars << ' ' << section << ' ' << stars << "*/";
|
||||
AppendLine();
|
||||
}
|
||||
|
||||
void GlslWriter::AppendFunction(Function& func)
|
||||
{
|
||||
NazaraAssert(!m_currentFunction, "A function is already being processed");
|
||||
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
|
||||
|
||||
m_currentFunction = &func;
|
||||
CallOnExit onExit([this] ()
|
||||
{
|
||||
m_currentFunction = nullptr;
|
||||
});
|
||||
|
||||
func.node->Register(*this);
|
||||
|
||||
Append(func.retType);
|
||||
|
||||
m_currentState->stream << ' ';
|
||||
Append(func.name);
|
||||
|
||||
m_currentState->stream << '(';
|
||||
for (std::size_t i = 0; i < func.parameters.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
m_currentState->stream << ", ";
|
||||
|
||||
Append(func.parameters[i]->type);
|
||||
m_currentState->stream << ' ';
|
||||
Append(func.parameters[i]->name);
|
||||
}
|
||||
m_currentState->stream << ")\n";
|
||||
|
||||
EnterScope();
|
||||
{
|
||||
DeclareVariables(func.variables);
|
||||
|
||||
Write(func.node);
|
||||
}
|
||||
LeaveScope();
|
||||
}
|
||||
|
||||
void GlslWriter::AppendLine(const String& txt)
|
||||
{
|
||||
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
|
||||
|
||||
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(section);
|
||||
|
||||
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");
|
||||
|
||||
m_currentState->indentLevel++;
|
||||
AppendLine("{");
|
||||
}
|
||||
|
||||
void GlslWriter::LeaveScope()
|
||||
{
|
||||
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
|
||||
|
||||
m_currentState->indentLevel--;
|
||||
AppendLine();
|
||||
AppendLine("}");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
auto impl = Renderer::GetRendererImpl()->CreateRenderWindowImpl();
|
||||
if (!impl->Create(surface.get(), Vector2ui(GetWidth(), GetHeight()), m_parameters))
|
||||
if (!impl->Create(surface.get(), GetSize(), m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create render window implementation: " + Error::GetLastError());
|
||||
return false;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <Nazara/Core/Directory.hpp>
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Platform/Platform.hpp>
|
||||
#include <Nazara/Utility/AbstractBuffer.hpp>
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
@@ -29,6 +30,12 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Platform::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize Platform module");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_moduleReferenceCounter++;
|
||||
|
||||
CallOnExit onExit(Renderer::Uninitialize);
|
||||
@@ -124,6 +131,7 @@ namespace Nz
|
||||
NazaraNotice("Uninitialized: Renderer module");
|
||||
|
||||
// Free module dependencies
|
||||
Platform::Uninitialize();
|
||||
Utility::Uninitialize();
|
||||
}
|
||||
|
||||
|
||||
196
src/Nazara/Renderer/ShaderAst.cpp
Normal file
196
src/Nazara/Renderer/ShaderAst.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2016 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/ShaderAst.hpp>
|
||||
#include <Nazara/Renderer/ShaderWriter.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz { namespace ShaderAst
|
||||
{
|
||||
void ExpressionStatement::Register(ShaderWriter& visitor)
|
||||
{
|
||||
expression->Register(visitor);
|
||||
}
|
||||
|
||||
void ExpressionStatement::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
void ConditionalStatement::Register(ShaderWriter& visitor)
|
||||
{
|
||||
if (visitor.IsConditionEnabled(conditionName))
|
||||
statement->Register(visitor);
|
||||
}
|
||||
|
||||
void ConditionalStatement::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
if (visitor.IsConditionEnabled(conditionName))
|
||||
statement->Visit(visitor);
|
||||
}
|
||||
|
||||
|
||||
void StatementBlock::Register(ShaderWriter& visitor)
|
||||
{
|
||||
for (auto& statementPtr : statements)
|
||||
statementPtr->Register(visitor);
|
||||
}
|
||||
|
||||
void StatementBlock::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
ExpressionType Variable::GetExpressionType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
void NamedVariable::Register(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.RegisterVariable(kind, name, type);
|
||||
}
|
||||
|
||||
void NamedVariable::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
void BuiltinVariable::Register(ShaderWriter& visitor)
|
||||
{
|
||||
}
|
||||
|
||||
void BuiltinVariable::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
ExpressionType AssignOp::GetExpressionType() const
|
||||
{
|
||||
return variable->GetExpressionType();
|
||||
}
|
||||
|
||||
void AssignOp::Register(ShaderWriter& visitor)
|
||||
{
|
||||
variable->Register(visitor);
|
||||
right->Register(visitor);
|
||||
}
|
||||
|
||||
void AssignOp::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
ExpressionType BinaryOp::GetExpressionType() const
|
||||
{
|
||||
ShaderAst::ExpressionType exprType = ShaderAst::ExpressionType::Void;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case ShaderAst::BinaryType::Add:
|
||||
case ShaderAst::BinaryType::Divide:
|
||||
case ShaderAst::BinaryType::Multiply:
|
||||
case ShaderAst::BinaryType::Substract:
|
||||
exprType = left->GetExpressionType();
|
||||
break;
|
||||
|
||||
case ShaderAst::BinaryType::Equality:
|
||||
exprType = ExpressionType::Boolean;
|
||||
}
|
||||
|
||||
NazaraAssert(exprType != ShaderAst::ExpressionType::Void, "Unhandled builtin");
|
||||
|
||||
return exprType;
|
||||
}
|
||||
|
||||
void BinaryOp::Register(ShaderWriter& visitor)
|
||||
{
|
||||
left->Register(visitor);
|
||||
right->Register(visitor);
|
||||
}
|
||||
|
||||
void BinaryOp::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
void Branch::Register(ShaderWriter& visitor)
|
||||
{
|
||||
for (ConditionalStatement& statement : condStatements)
|
||||
{
|
||||
statement.condition->Register(visitor);
|
||||
statement.statement->Register(visitor);
|
||||
}
|
||||
|
||||
if (elseStatement)
|
||||
elseStatement->Register(visitor);
|
||||
}
|
||||
|
||||
void Branch::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
visitor.Write(*this);
|
||||
}
|
||||
|
||||
|
||||
ExpressionType Constant::GetExpressionType() const
|
||||
{
|
||||
return exprType;
|
||||
}
|
||||
|
||||
void Constant::Register(ShaderWriter&)
|
||||
{
|
||||
}
|
||||
|
||||
void Constant::Visit(ShaderWriter& visitor)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/Nazara/Renderer/ShaderWriter.cpp
Normal file
24
src/Nazara/Renderer/ShaderWriter.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/ShaderWriter.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ShaderWriter::~ShaderWriter() = default;
|
||||
|
||||
void ShaderWriter::EnableCondition(const String& name, bool cond)
|
||||
{
|
||||
if (cond)
|
||||
m_conditions.insert(name);
|
||||
else
|
||||
m_conditions.erase(name);
|
||||
}
|
||||
|
||||
bool ShaderWriter::IsConditionEnabled(const String & name) const
|
||||
{
|
||||
return m_conditions.count(name) != 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user