@@ -140,6 +140,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unit Test", "Unit Test", "{ | |||||
EndProject | EndProject | ||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "top_shooter", "..\people\touky\top_shooter\top_shooter.vcxproj", "{EE203B88-44CF-4859-9D42-7A5F45FEDB52}" | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "top_shooter", "..\people\touky\top_shooter\top_shooter.vcxproj", "{EE203B88-44CF-4859-9D42-7A5F45FEDB52}" | ||||
EndProject | EndProject | ||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "13_shader_builder", "..\demos\tutorial\13_shader_builder.vcxproj", "{F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|ORBIS = Debug|ORBIS | 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.ActiveCfg = Release|x64 | ||||
{EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|x64.Build.0 = Release|x64 | {EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|x64.Build.0 = Release|x64 | ||||
{EE203B88-44CF-4859-9D42-7A5F45FEDB52}.Release|Xbox 360.ActiveCfg = Release|Win32 | {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 | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -846,5 +862,6 @@ Global | |||||
{FFF58874-D460-41E6-AD65-DBFEC6E47A94} = {2195FB18-53BF-48AF-96B6-9BD242924EA5} | {FFF58874-D460-41E6-AD65-DBFEC6E47A94} = {2195FB18-53BF-48AF-96B6-9BD242924EA5} | ||||
{E4DFEBF9-C310-462F-9876-7EB59C1E4D4E} = {1AFD580B-98B8-4689-B661-38C41132C60E} | {E4DFEBF9-C310-462F-9876-7EB59C1E4D4E} = {1AFD580B-98B8-4689-B661-38C41132C60E} | ||||
{EE203B88-44CF-4859-9D42-7A5F45FEDB52} = {9EA99B18-D352-47F6-BC04-A0B49CAA2772} | {EE203B88-44CF-4859-9D42-7A5F45FEDB52} = {9EA99B18-D352-47F6-BC04-A0B49CAA2772} | ||||
{F59FA82C-DDB9-4EE2-80AE-CB0E4C6567A4} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} | |||||
EndGlobalSection | EndGlobalSection | ||||
EndGlobal | EndGlobal |
@@ -235,7 +235,7 @@ public: | |||||
if (m_camera) | if (m_camera) | ||||
g_scene->PopCamera(m_camera); | g_scene->PopCamera(m_camera); | ||||
if (m_ssetup) | if (m_ssetup) | ||||
delete(m_ssetup); | |||||
delete m_ssetup; | |||||
MessageService::Destroy(); | MessageService::Destroy(); | ||||
m_controller = nullptr; | m_controller = nullptr; | ||||
@@ -585,7 +585,7 @@ public: | |||||
light_datas << LightData(m_ssetup->m_lights[i]->GetPosition(), m_ssetup->m_lights[i]->GetColor()); | light_datas << LightData(m_ssetup->m_lights[i]->GetPosition(), m_ssetup->m_lights[i]->GetColor()); | ||||
if (m_ssetup) | if (m_ssetup) | ||||
delete(m_ssetup); | |||||
delete m_ssetup; | |||||
m_ssetup = new_ssetup; | m_ssetup = new_ssetup; | ||||
m_ssetup->Startup(); | m_ssetup->Startup(); | ||||
@@ -616,7 +616,7 @@ public: | |||||
else | else | ||||
{ | { | ||||
m_ssetup->m_custom_cmd += new_ssetup->m_custom_cmd; | 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); | m_meshes.Push(em, nullptr); | ||||
} | } | ||||
else | else | ||||
delete(em); | |||||
delete em; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -773,7 +773,7 @@ public: | |||||
newtmp->ExecuteCmdStack(false); | newtmp->ExecuteCmdStack(false); | ||||
m_meshes[i].m1 = newtmp; | 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_CPPFLAGS = $(AM_CPPFLAGS) | ||||
12_voronoi_DEPENDENCIES = @LOL_DEPS@ | 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_gpudatas.Empty(); | ||||
m_vdatas.Empty(); | m_vdatas.Empty(); | ||||
if (m_ibo) | if (m_ibo) | ||||
delete(m_ibo); | |||||
delete m_ibo; | |||||
} | } | ||||
#define BUILD_VFLAG(bool_value, flag_value, check_flag) \ | #define BUILD_VFLAG(bool_value, flag_value, check_flag) \ | ||||
@@ -395,7 +395,8 @@ Shader::Shader(String const &name, | |||||
VertexUsage usage = VertexUsage::MAX; | VertexUsage usage = VertexUsage::MAX; | ||||
for (int j = 0; j < (int)VertexUsage::MAX; ++j) | 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); | usage = VertexUsage(j); | ||||
char* idx_ptr = name.C() + strlen(attribute_names[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; | 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 */ | } /* namespace lol */ | ||||
@@ -94,6 +94,11 @@ public: | |||||
return m_array.Count(); | return m_array.Count(); | ||||
} | } | ||||
inline void Empty() | |||||
{ | |||||
m_array.Empty(); | |||||
} | |||||
private: | private: | ||||
template <typename E> | template <typename E> | ||||
inline ptrdiff_t FindIndex(E const &key, uint32_t hashed) | inline ptrdiff_t FindIndex(E const &key, uint32_t hashed) | ||||
@@ -52,6 +52,44 @@ LOL_SAFE_ENUM(VertexUsage, | |||||
MAX, | 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 | struct ShaderUniform | ||||
{ | { | ||||
friend class Shader; | friend class Shader; | ||||
@@ -65,6 +103,7 @@ private: | |||||
uint32_t flags; | uint32_t flags; | ||||
}; | }; | ||||
//ShaderAttrib ---------------------------------------------------------------- | |||||
struct ShaderAttrib | struct ShaderAttrib | ||||
{ | { | ||||
friend class Shader; | friend class Shader; | ||||
@@ -80,6 +119,7 @@ private: | |||||
uint64_t m_flags; | uint64_t m_flags; | ||||
}; | }; | ||||
//TextureUniform -------------------------------------------------------------- | |||||
struct TextureUniform | struct TextureUniform | ||||
{ | { | ||||
friend class Shader; | friend class Shader; | ||||
@@ -98,6 +138,7 @@ private: | |||||
class ShaderData; | class ShaderData; | ||||
//Shader ---------------------------------------------------------------------- | |||||
class Shader : public Entity | class Shader : public Entity | ||||
{ | { | ||||
public: | public: | ||||
@@ -135,6 +176,81 @@ protected: | |||||
private: | private: | ||||
ShaderData *data; | 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 */ | } /* namespace lol */ | ||||