@@ -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 */ | |||