| @@ -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 | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,125 @@ | |||
| // | |||
| // Lol Engine - Graphing tutorial | |||
| // | |||
| // Copyright: (c) 2012-2013 Sam Hocevar <sam@hocevar.net> | |||
| // 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 <lol/engine.h> | |||
| #include "loldebug.h" | |||
| #include <cstdio> | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,79 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <ItemGroup Label="ProjectConfigurations"> | |||
| <ProjectConfiguration Include="Debug|ORBIS"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>ORBIS</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|PS3"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>PS3</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|Win32"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|x64"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|Xbox 360"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>Xbox 360</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|ORBIS"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>ORBIS</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|PS3"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>PS3</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|Win32"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|x64"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|Xbox 360"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>Xbox 360</Platform> | |||
| </ProjectConfiguration> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="$(SolutionDir)\..\src\lolcore.vcxproj"> | |||
| <Project>{9e62f2fe-3408-4eae-8238-fd84238ceeda}</Project> | |||
| </ProjectReference> | |||
| <ProjectReference Include="$(SolutionDir)\..\src\bullet\lolbullet.vcxproj"> | |||
| <Project>{83d3b207-c601-4025-8f41-01dedc354661}</Project> | |||
| </ProjectReference> | |||
| <ProjectReference Include="$(SolutionDir)\..\src\lua\lollua.vcxproj"> | |||
| <Project>{d84021ca-b233-4e0f-8a52-071b83bbccc4}</Project> | |||
| </ProjectReference> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ClCompile Include="13_shader_builder.cpp" /> | |||
| </ItemGroup> | |||
| <PropertyGroup Label="Globals"> | |||
| <ProjectGuid>{F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}</ProjectGuid> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <Keyword>Win32Proj</Keyword> | |||
| </PropertyGroup> | |||
| <Import Project="$(SolutionDir)\msbuild\lol.config.props" /> | |||
| <ImportGroup Label="ExtensionSettings"> | |||
| <Import Project="$(SolutionDir)\msbuild\lolfx.props" /> | |||
| </ImportGroup> | |||
| <ImportGroup Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| <Import Project="$(SolutionDir)\msbuild\lol.vars.props" /> | |||
| </ImportGroup> | |||
| <PropertyGroup Label="UserMacros" /> | |||
| <Import Project="$(SolutionDir)\msbuild\lol.rules.props" /> | |||
| <ItemDefinitionGroup /> | |||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||
| <ImportGroup Label="ExtensionTargets"> | |||
| <Import Project="$(SolutionDir)\msbuild\lolfx.targets" /> | |||
| </ImportGroup> | |||
| </Project> | |||
| @@ -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@ | |||
| @@ -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) \ | |||
| @@ -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<String, String> const& variables, String& result) | |||
| { | |||
| array<String> 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<String, String>& variables, String& result) | |||
| { | |||
| array<String> 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<String, String>& variables, map<String, String>& merged) | |||
| { | |||
| array<String> 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<String> 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<String> 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<String> 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 */ | |||
| @@ -94,6 +94,11 @@ public: | |||
| return m_array.Count(); | |||
| } | |||
| inline void Empty() | |||
| { | |||
| m_array.Empty(); | |||
| } | |||
| private: | |||
| template <typename E> | |||
| inline ptrdiff_t FindIndex(E const &key, uint32_t hashed) | |||
| @@ -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<ShaderVariableBase> 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<ShaderProgramBase> 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 : <var_name, var_type> | |||
| //-------------------------- | |||
| //Main shader parameters | |||
| map<String, String> 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<String, String> const& variables, String& result); | |||
| void AddDefinitionParameters(const ShaderVariable variable, const ShaderProgram program, map<String, String>& 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<ShaderBlock*> m_blocks[ShaderProgram::MAX]; | |||
| //Final shader parameters | |||
| map<String, String> 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<String, String>& variables, map<String, String>& merged); | |||
| public: | |||
| void Build(String& code); | |||
| }; | |||
| } /* namespace lol */ | |||