diff --git a/build/Lol (vs2013).sln b/build/Lol (vs2013).sln index 148b1ddd..01c83083 100644 --- a/build/Lol (vs2013).sln +++ b/build/Lol (vs2013).sln @@ -140,6 +140,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unit Test", "Unit Test", "{ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "top_shooter", "..\people\touky\top_shooter\top_shooter.vcxproj", "{EE203B88-44CF-4859-9D42-7A5F45FEDB52}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "13_shader_builder", "..\demos\tutorial\13_shader_builder.vcxproj", "{F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ORBIS = Debug|ORBIS @@ -779,6 +781,20 @@ Global {EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|x64.ActiveCfg = Release|x64 {EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|x64.Build.0 = Release|x64 {EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|Xbox 360.ActiveCfg = Release|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|ORBIS.ActiveCfg = Debug|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|PS3.ActiveCfg = Debug|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|Win32.ActiveCfg = Debug|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|Win32.Build.0 = Debug|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|x64.ActiveCfg = Debug|x64 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|x64.Build.0 = Debug|x64 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Debug|Xbox 360.ActiveCfg = Debug|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|ORBIS.ActiveCfg = Release|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|PS3.ActiveCfg = Release|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|Win32.ActiveCfg = Release|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|Win32.Build.0 = Release|Win32 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|x64.ActiveCfg = Release|x64 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|x64.Build.0 = Release|x64 + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}.Release|Xbox 360.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -846,5 +862,6 @@ Global {FFF58874-D460-41E6-AD65-DBFEC6E47A94} = {2195FB18-53BF-48AF-96B6-9BD242924EA5} {E4DFEBF9-C310-462F-9876-7EB59C1E4D4E} = {1AFD580B-98B8-4689-B661-38C41132C60E} {EE203B88-44CF-4859-9D42-7A5F45FEDB52} = {9EA99B18-D352-47F6-BC04-A0B49CAA2772} + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} EndGlobalSection EndGlobal diff --git a/demos/test/meshviewer.cpp b/demos/test/meshviewer.cpp index 6ecb5b7b..bd240281 100644 --- a/demos/test/meshviewer.cpp +++ b/demos/test/meshviewer.cpp @@ -235,7 +235,7 @@ public: if (m_camera) g_scene->PopCamera(m_camera); if (m_ssetup) - delete(m_ssetup); + delete m_ssetup; MessageService::Destroy(); m_controller = nullptr; @@ -585,7 +585,7 @@ public: light_datas << LightData(m_ssetup->m_lights[i]->GetPosition(), m_ssetup->m_lights[i]->GetColor()); if (m_ssetup) - delete(m_ssetup); + delete m_ssetup; m_ssetup = new_ssetup; m_ssetup->Startup(); @@ -616,7 +616,7 @@ public: else { m_ssetup->m_custom_cmd += new_ssetup->m_custom_cmd; - delete(new_ssetup); + delete new_ssetup; } } } @@ -639,7 +639,7 @@ public: m_meshes.Push(em, nullptr); } else - delete(em); + delete em; } } } @@ -773,7 +773,7 @@ public: newtmp->ExecuteCmdStack(false); m_meshes[i].m1 = newtmp; - delete(tmp); + delete tmp; } } } diff --git a/demos/tutorial/13_shader_builder.cpp b/demos/tutorial/13_shader_builder.cpp new file mode 100644 index 00000000..ffa8f2cb --- /dev/null +++ b/demos/tutorial/13_shader_builder.cpp @@ -0,0 +1,125 @@ +// +// Lol Engine - Graphing tutorial +// +// Copyright: (c) 2012-2013 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "loldebug.h" +#include + +using namespace lol; + +class ShaderBuilderDemo : public WorldEntity +{ +public: + ShaderBuilderDemo() + { + } + + virtual void TickGame(float seconds) + { + WorldEntity::TickGame(seconds); + } + + virtual void TickDraw(float seconds, Scene &scene) + { + WorldEntity::TickDraw(seconds, scene); + + File file; + file.Open("13_shader_builder_export.txt", FileAccess::Write); + //file.Open("13_shader_builder_export.txt", FileAccess::Read); + String code; + + ShaderBuilder builder("red_blue_green", "120"); + ShaderBlock nothing_vertex("NothingVertex"); + ShaderBlock red_pixel("RedPixel"); + ShaderBlock green_pixel("GreenPixel"); + ShaderBlock blue_pixel("BluePixel"); + + String vertex_out = Shader::GetProgramOutVariableLocal(ShaderProgram::Vertex); + String pixel_out = Shader::GetProgramOutVariableLocal(ShaderProgram::Pixel); + + String in_position = Shader::GetVariablePrefix(ShaderVariable::Attribute) + "position"; + String in_color = Shader::GetVariablePrefix(ShaderVariable::Attribute) + "color"; + String pass_color = Shader::GetVariablePrefix(ShaderVariable::Varying) + "color"; + + nothing_vertex.Add(ShaderVariable::Attribute, "vec3", "position"); + nothing_vertex.Add(ShaderVariable::Attribute, "vec4", "color"); + nothing_vertex.Add(ShaderVariable::Varying, "vec4", "color"); + nothing_vertex.Add(ShaderVariable::InOut, "vec4", vertex_out); + nothing_vertex.SetMainCode( + String(" ") + pass_color + " = " + in_color + ";\n" + + String(" ") + vertex_out + " = vec4(" + in_position + ", 0.f);\n" + ); + + red_pixel.Add(ShaderVariable::Varying, "vec4", "color"); + red_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out); + red_pixel.Add(ShaderVariable::InOut, "vec4", "ambient"); + red_pixel.SetMainCode( + String(" ") + pixel_out + " = " + pass_color + ";\n" + + String(" ") + pixel_out + ".r = 1.0;\n" + + String(" ") + "ambient = vec4(1.0);\n" + ); + + green_pixel.Add(ShaderVariable::Varying, "vec4", "color"); + green_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out); + green_pixel.Add(ShaderVariable::InOut, "vec4", "ambient"); + green_pixel.SetMainCode( + String(" ") + pixel_out + " = " + pass_color + ";\n" + + String(" ") + pixel_out + ".g = 1.0;\n" + + String(" ") + "ambient.r = 0.0;\n" + ); + + blue_pixel.Add(ShaderVariable::Varying, "vec4", "color"); + blue_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out); + blue_pixel.Add(ShaderVariable::InOut, "vec4", "ambient"); + blue_pixel.SetCustomCode( + String("void SetAmbient(inout vec4 ambient)\n{\n ambient = vec4(1.0, 1.0, 1.0, 1.0);\n}")); + blue_pixel.SetMainCode( + String(" ") + pixel_out + " = " + pass_color + ";\n" + + String(" ") + pixel_out + ".b = 1.0;\n" + + String(" ") + "SetAmbient(ambient);\n" + + String(" ") + pixel_out + " *= ambient;\n" + ); + + builder << ShaderProgram::Vertex + << ¬hing_vertex + << ShaderProgram::Pixel + << &red_pixel + << &green_pixel + << &blue_pixel; + + builder.Build(code); + + file.WriteString(code); + //code = file.ReadString(); + file.Close(); + + Shader* shader = Shader::Create(builder.GetName(), code); + Shader::Destroy(shader); + + Ticker::Shutdown(); + } +}; + +int main(int argc, char **argv) +{ + System::Init(argc, argv); + + Application app("Tutorial 13: Shader Builder", ivec2(1280, 720), 60.0f); + + new ShaderBuilderDemo(); + + app.Run(); + return EXIT_SUCCESS; +} + diff --git a/demos/tutorial/13_shader_builder.vcxproj b/demos/tutorial/13_shader_builder.vcxproj new file mode 100644 index 00000000..ec47ccd6 --- /dev/null +++ b/demos/tutorial/13_shader_builder.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + ORBIS + + + Debug + PS3 + + + Debug + Win32 + + + Debug + x64 + + + Debug + Xbox 360 + + + Release + ORBIS + + + Release + PS3 + + + Release + Win32 + + + Release + x64 + + + Release + Xbox 360 + + + + + {9e62f2fe-3408-4eae-8238-fd84238ceeda} + + + {83d3b207-c601-4025-8f41-01dedc354661} + + + {d84021ca-b233-4e0f-8a52-071b83bbccc4} + + + + + + + {F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4} + Application + Win32Proj + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/tutorial/Makefile.am b/demos/tutorial/Makefile.am index c8566a05..796b94b2 100644 --- a/demos/tutorial/Makefile.am +++ b/demos/tutorial/Makefile.am @@ -51,3 +51,7 @@ endif 12_voronoi_CPPFLAGS = $(AM_CPPFLAGS) 12_voronoi_DEPENDENCIES = @LOL_DEPS@ +13_shader_builder_SOURCES = 13_shader_builder.cpp +13_shader_builder_CPPFLAGS = $(AM_CPPFLAGS) +13_shader_builder_DEPENDENCIES = @LOL_DEPS@ + diff --git a/src/easymesh/easymeshrender.cpp b/src/easymesh/easymeshrender.cpp index 26351aad..3eb4be2b 100644 --- a/src/easymesh/easymeshrender.cpp +++ b/src/easymesh/easymeshrender.cpp @@ -186,7 +186,7 @@ GpuEasyMeshData::~GpuEasyMeshData() m_gpudatas.Empty(); m_vdatas.Empty(); if (m_ibo) - delete(m_ibo); + delete m_ibo; } #define BUILD_VFLAG(bool_value, flag_value, check_flag) \ diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index 7d696791..50e80e6c 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -395,7 +395,8 @@ Shader::Shader(String const &name, VertexUsage usage = VertexUsage::MAX; for (int j = 0; j < (int)VertexUsage::MAX; ++j) { - if (name.StartsWith(attribute_names[j])) + if (name.StartsWith(attribute_names[j]) || + name.StartsWith(String(attribute_names[j]).ToLower())) { usage = VertexUsage(j); char* idx_ptr = name.C() + strlen(attribute_names[j]); @@ -1021,5 +1022,343 @@ String ShaderData::Patch(String const &code, ShaderType type) return patched_code; } +static const String g_ret = "\n"; +static const String g_tab = " "; + +//---- +String Shader::GetVariablePrefix(const ShaderVariable variable) +{ + switch (variable.ToScalar()) + { + case ShaderVariable::Attribute: return String("in_"); + case ShaderVariable::Uniform: return String("u_"); + case ShaderVariable::Varying: return String("pass_"); + case ShaderVariable::InOut: + default: return String(); + } +} + +//---- +String Shader::GetVariableQualifier(const ShaderVariable variable) +{ + switch (variable.ToScalar()) + { + case ShaderVariable::Attribute: return String("attribute"); + case ShaderVariable::Uniform: return String("uniform"); + case ShaderVariable::Varying: return String("varying"); + case ShaderVariable::InOut: + default: return String(); + } +} + +//---- +String Shader::GetFunctionQualifier(const ShaderVariable variable, const ShaderProgram program) +{ + switch (program.ToScalar()) + { + case ShaderProgram::Geometry: + { + //TODO : L O L ---------------- + return String(); + } + case ShaderProgram::Vertex: + { + switch (variable.ToScalar()) + { + case ShaderVariable::Attribute: return String("in"); + case ShaderVariable::Uniform: return String("in"); + case ShaderVariable::Varying: return String("inout"); + case ShaderVariable::InOut: return String("inout"); + default: return String(); + } + return String(); + } + case ShaderProgram::Pixel: + { + switch (variable.ToScalar()) + { + case ShaderVariable::Attribute: return String("in"); + case ShaderVariable::Uniform: return String("in"); + case ShaderVariable::Varying: return String("in"); + case ShaderVariable::InOut: return String("inout"); + default: return String(); + } + return String(); + } + default: + { + return String(); + } + } +} + +//---- +String Shader::GetProgramQualifier(const ShaderProgram program) +{ + switch (program.ToScalar()) + { + case ShaderProgram::Geometry: return String(); //TODO : L O L ---------------- + case ShaderProgram::Vertex: return String("[vert.glsl]"); + case ShaderProgram::Pixel: return String("[frag.glsl]"); + default: return String(); + } +} + +//---- +String Shader::GetProgramOutVariable(const ShaderProgram program) +{ + switch (program.ToScalar()) + { + case ShaderProgram::Geometry: return String(); //TODO : L O L ---------------- + case ShaderProgram::Vertex: return String("gl_Position"); + case ShaderProgram::Pixel: return String("gl_FragColor"); + default: return String(); + } +} + +//---- +String Shader::GetProgramOutVariableLocal(const ShaderProgram program) +{ + switch (program.ToScalar()) + { + case ShaderProgram::Geometry: return String(); //TODO : L O L ---------------- + case ShaderProgram::Vertex: return String("out_position"); + case ShaderProgram::Pixel: return String("out_frag_color"); + default: return String(); + } +} + +//Shader Block implementation class ------------------------------------------- +void ShaderBlock::Add(const ShaderVariable parameter, String const &type, String const &name) +{ + ASSERT(!m_parameters[parameter.ToScalar()].HasKey(name)); + m_parameters[parameter.ToScalar()][name] = type; +} + +//---- +void ShaderBlock::AddCallParameters(const ShaderVariable type, map const& variables, String& result) +{ + array keys = variables.Keys(); + for (String key : keys) + { + if (result.Count() > 0) + result += ", "; + result += Shader::GetVariablePrefix(type) + key; + } +} + +//---- +void ShaderBlock::AddDefinitionParameters(const ShaderVariable type, const ShaderProgram program, map& variables, String& result) +{ + array keys = variables.Keys(); + for (String key : keys) + { + if (result.Count() > 0) + result += ", "; + result += Shader::GetFunctionQualifier(type, program) + " "; + result += variables[key]; + result += String(" "); + result += Shader::GetVariablePrefix(type); + result += key; + } +} + +//---- +void ShaderBlock::Build(const ShaderProgram program, String& call, String& function) +{ + ASSERT(m_name.Count()); + ASSERT(m_parameters[ShaderVariable::InOut].Count()); + + //Build call in main + String call_name = String("Call_") + m_name; + call = call_name + "("; + String call_parameters; + for (int i = 0; i < ShaderVariable::MAX; i++) + AddCallParameters((ShaderVariable)i, m_parameters[i], call_parameters); + call += call_parameters + ");"; + + //Build function declaration + function = String("void ") + call_name + "("; + String def_parameters; + for (int i = 0; i < ShaderVariable::MAX; i++) + AddDefinitionParameters((ShaderVariable)i, program, m_parameters[i], def_parameters); + function += def_parameters + ")" + g_ret + + "{" + g_ret + + m_code_main + ((m_code_main.EndsWith(g_ret)) ? (String()) : (g_ret)) + + "}"; +} + +//Shader Builder implementation class ----------------------------------------- +ShaderBuilder::ShaderBuilder(String const& name, String const& version) + : m_name(name), m_version(version) +{ + ASSERT(name.Count()); + ASSERT(version.Count()); +} + +//---- +ShaderBuilder::~ShaderBuilder() +{ +} + +//---- +String const& ShaderBuilder::GetName() +{ + return m_name; +} + +//---- +ShaderBuilder& ShaderBuilder::operator<<(const ShaderProgram program) +{ + m_current_program = program; + return *this; +} + +//---- +ShaderBuilder& ShaderBuilder::operator<<(ShaderBlock* block) +{ + ASSERT(m_current_program != ShaderProgram::MAX); + m_blocks[m_current_program.ToScalar()].PushUnique(block); + return *this; +} + +//---- +String ShaderBuilder::AddSlotOutVariableLocal(const ShaderProgram program) +{ + ShaderVariable var = ShaderVariable::InOut; + String result = Shader::GetProgramOutVariableLocal(program); + switch (program.ToScalar()) + { + case ShaderProgram::Geometry: + { + //TODO : L O L ---------------- + break; + } + case ShaderProgram::Vertex: + { + m_parameters[program.ToScalar()][var.ToScalar()][result] = "vec4"; + break; + } + case ShaderProgram::Pixel: + { + m_parameters[program.ToScalar()][var.ToScalar()][result] = "vec4"; + break; + } + default: + { + break; + } + } + return result; +} + +//---- +void ShaderBuilder::MergeParameters(map& variables, map& merged) +{ + array keys = variables.Keys(); + for (String key : keys) + { + bool has_key = merged.HasKey(key); + //Key exists, check the type to make sure it's the same + ASSERT(!(has_key && merged[key] != variables[key])); + + //does not exist, had it + if (!has_key) + merged[key] = variables[key]; + } +} + +//---- +void ShaderBuilder::Build(String& code) +{ + //Cleanup first + for (int prog = 0; prog < ShaderProgram::MAX; prog++) + for (int var = 0; var < ShaderVariable::MAX; var++) + m_parameters[prog][var].Empty(); + + //Start building + for (int prog = 0; prog < ShaderProgram::MAX; prog++) + { + //Add default local out in merged variables + String out_local_var = AddSlotOutVariableLocal((ShaderProgram)prog); + + if (!out_local_var.Count()) + continue; + + //Merge all variables + for (int var = 0; var < ShaderVariable::MAX; var++) + for (int block = 0; block < m_blocks[prog].Count(); block++) + MergeParameters(m_blocks[prog][block]->m_parameters[var], m_parameters[prog][var]); + + //Actually write code + code += Shader::GetProgramQualifier((ShaderProgram)prog) + g_ret; + + //Add actual code + code += String("#version ") + m_version + g_ret + g_ret; + + //Added shader variables + for (int var = 0; var < ShaderVariable::InOut; var++) + { + array keys = m_parameters[prog][var].Keys(); + if (keys.Count()) + { + code += String("//- ") + Shader::GetVariableQualifier((ShaderVariable)var) + " ----" + g_ret; + for (String key : keys) + { + code += Shader::GetVariableQualifier((ShaderVariable)var) + " "; + code += m_parameters[prog][var][key] + " " + + Shader::GetVariablePrefix((ShaderVariable)var) + key + ";" + g_ret; + } + if (var + 1 < ShaderVariable::InOut) + code += g_ret; + } + } + code += g_ret; + + //Build Blocks code and add it + array calls; + for (int block = 0; block < m_blocks[prog].Count(); block++) + { + String call; + String function; + m_blocks[prog][block]->Build(ShaderProgram(prog), call, function); + calls << call; + if (m_blocks[prog][block]->m_code_custom.Count()) + { + code += String("//- ") + m_blocks[prog][block]->GetName() + " custom code ----" + g_ret; + code += m_blocks[prog][block]->m_code_custom + g_ret + g_ret; + } + code += String("//- ") + m_blocks[prog][block]->GetName() + " main code ----" + g_ret; + code += function + g_ret + g_ret; + } + + //Added main definition + code += String("//- Main ----") + g_ret + + String("void main(void)") + g_ret + "{" + g_ret; + + //Add local variables + int var = ShaderVariable::InOut; + array keys = m_parameters[prog][var].Keys(); + for (String key : keys) + { + if (keys.Count()) + { + code += g_tab + m_parameters[prog][var][key] + " " + + Shader::GetVariablePrefix((ShaderVariable)var) + key + ";" + g_ret; + } + } + code += g_ret; + + //Add calls + code += g_tab + String("//- Calls ----") + g_ret; + for (String call : calls) + code += g_tab + call + g_ret; + code += g_ret; + + code += g_tab + Shader::GetProgramOutVariable((ShaderProgram)prog) + " = " + out_local_var + ";" + g_ret + + String("}") + g_ret + g_ret; + } +} + } /* namespace lol */ diff --git a/src/lol/base/map.h b/src/lol/base/map.h index 59532d1f..2e1b684e 100644 --- a/src/lol/base/map.h +++ b/src/lol/base/map.h @@ -94,6 +94,11 @@ public: return m_array.Count(); } + inline void Empty() + { + m_array.Empty(); + } + private: template inline ptrdiff_t FindIndex(E const &key, uint32_t hashed) diff --git a/src/lol/gpu/shader.h b/src/lol/gpu/shader.h index 86554535..c7598285 100644 --- a/src/lol/gpu/shader.h +++ b/src/lol/gpu/shader.h @@ -52,6 +52,44 @@ LOL_SAFE_ENUM(VertexUsage, MAX, ); +//Enum definitions ------------------------------------------------------------ +struct ShaderVariableBase +{ + enum Type + { + //Main shader parameters + Attribute = 0, + Uniform, + Varying, + + //Passed variables, defined as local main() variables + InOut, + + MAX + }; +protected: + static inline char const *GetDescription() { return nullptr; } + static inline char const **GetCustomString() { return nullptr; } +}; +typedef SafeEnum ShaderVariable; + +struct ShaderProgramBase +{ + enum Type + { + Geometry = 0, + Vertex, + Pixel, + + MAX + }; +protected: + static inline char const *GetDescription() { return nullptr; } + static inline char const **GetCustomString() { return nullptr; } +}; +typedef SafeEnum ShaderProgram; + +//ShaderUniform --------------------------------------------------------------- struct ShaderUniform { friend class Shader; @@ -65,6 +103,7 @@ private: uint32_t flags; }; +//ShaderAttrib ---------------------------------------------------------------- struct ShaderAttrib { friend class Shader; @@ -80,6 +119,7 @@ private: uint64_t m_flags; }; +//TextureUniform -------------------------------------------------------------- struct TextureUniform { friend class Shader; @@ -98,6 +138,7 @@ private: class ShaderData; +//Shader ---------------------------------------------------------------------- class Shader : public Entity { public: @@ -135,6 +176,81 @@ protected: private: ShaderData *data; + +public: + static String GetVariablePrefix(const ShaderVariable variable); + static String GetVariableQualifier(const ShaderVariable variable); + static String GetFunctionQualifier(const ShaderVariable variable, const ShaderProgram program); + static String GetProgramQualifier(const ShaderProgram program); + static String GetProgramOutVariable(const ShaderProgram program); + static String GetProgramOutVariableLocal(const ShaderProgram program); +}; + +//ShaderBlock ----------------------------------------------------------------- +class ShaderBlock +{ + friend class ShaderBuilder; + +protected: + String m_name; + + //-------------------------- + //map : + //-------------------------- + + //Main shader parameters + map m_parameters[ShaderVariable::MAX]; + + //Actual code + String m_code_main; + String m_code_custom; + +public: + ShaderBlock(String const& name) : m_name(name) { } + ~ShaderBlock() { } + + String const& GetName() { return m_name; } + //Sets code that will be used in the main + void SetMainCode(String const& code_main) { m_code_main = code_main; } + //Sets custom code that will be put before the main -so functions- + void SetCustomCode(String const& code_custom) { m_code_custom = code_custom; } + //Add parameter to the block + void Add(const ShaderVariable variable, String const& type, String const& name); + +protected: + void AddCallParameters(const ShaderVariable variable, map const& variables, String& result); + void AddDefinitionParameters(const ShaderVariable variable, const ShaderProgram program, map& variables, String& result); + void Build(const ShaderProgram program, String& call, String& function); +}; + +//Shaderbuilder --------------------------------------------------------------- +class ShaderBuilder +{ +protected: + String m_name; + String m_version; + ShaderProgram m_current_program = ShaderProgram::MAX; + + //Blocks + array m_blocks[ShaderProgram::MAX]; + + //Final shader parameters + map m_parameters[ShaderProgram::MAX][ShaderVariable::MAX]; + +public: + ShaderBuilder(String const& name, String const& version); + ~ShaderBuilder(); + + String const& GetName(); + ShaderBuilder& operator<<(const ShaderProgram program); + ShaderBuilder& operator<<(ShaderBlock* block); + +protected: + String AddSlotOutVariableLocal(const ShaderProgram program); + void MergeParameters(map& variables, map& merged); + +public: + void Build(String& code); }; } /* namespace lol */