Browse Source

Added ShaderBuilder

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
cb7a99bac3
9 changed files with 692 additions and 7 deletions
  1. +17
    -0
      build/Lol (vs2013).sln
  2. +5
    -5
      demos/test/meshviewer.cpp
  3. +125
    -0
      demos/tutorial/13_shader_builder.cpp
  4. +79
    -0
      demos/tutorial/13_shader_builder.vcxproj
  5. +4
    -0
      demos/tutorial/Makefile.am
  6. +1
    -1
      src/easymesh/easymeshrender.cpp
  7. +340
    -1
      src/gpu/shader.cpp
  8. +5
    -0
      src/lol/base/map.h
  9. +116
    -0
      src/lol/gpu/shader.h

+ 17
- 0
build/Lol (vs2013).sln View File

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

+ 5
- 5
demos/test/meshviewer.cpp View File

@@ -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;
}
}
}


+ 125
- 0
demos/tutorial/13_shader_builder.cpp View File

@@ -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
<< &nothing_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;
}


+ 79
- 0
demos/tutorial/13_shader_builder.vcxproj View File

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

+ 4
- 0
demos/tutorial/Makefile.am View File

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


+ 1
- 1
src/easymesh/easymeshrender.cpp View File

@@ -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) \


+ 340
- 1
src/gpu/shader.cpp View File

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


+ 5
- 0
src/lol/base/map.h View File

@@ -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)


+ 116
- 0
src/lol/gpu/shader.h View File

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


Loading…
Cancel
Save