~ fragment shaders can set new combos on rare occasions, so updated shader compiler to reflect this possibility

~ also updated shader passes to ensure it takes this into account

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2021-08-08 07:41:12 +02:00
parent 65a26c2b16
commit b4a6dc9bcd
3 changed files with 65 additions and 44 deletions

View File

@ -44,9 +44,9 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
this->m_fragShader = new Render::Shaders::Compiler (
this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false
);
// register vertex shader
// register vertex shader, combos come from the fragment as it can sometimes define them
this->m_vertShader = new Render::Shaders::Compiler (
this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false
this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex, this->m_fragShader->getCombos (), false
);
this->setupTextures ();
// initialize material data and compile shader used for this pass

View File

@ -2,6 +2,7 @@
#include <iostream>
#include <fstream>
#include <string>
#include <utility>
// filesystem
#include <WallpaperEngine/FileSystem/FileSystem.h>
@ -20,8 +21,8 @@ using namespace WallpaperEngine::Core;
namespace WallpaperEngine::Render::Shaders
{
Compiler::Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, const std::map<std::string, int>& combos, bool recursive) :
m_combos (combos),
Compiler::Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive) :
m_combos (std::move(combos)),
m_recursive (recursive),
m_type (type),
m_file (file),
@ -29,43 +30,7 @@ namespace WallpaperEngine::Render::Shaders
m_errorInfo (""),
m_context (context)
{
// begin with an space so it gets ignored properly on parse
if (this->m_recursive == false)
{
// compatibility layer for OpenGL shaders
this->m_content = "#version 120\n"
"#define highp\n"
"#define mediump\n"
"#define lowp\n"
"#define mul(x, y) (y * x)\n"
"#define frac fract\n"
"#define CAST2(x) (vec2(x))\n"
"#define CAST3(x) (vec3(x))\n"
"#define CAST4(x) (vec4(x))\n"
"#define CAST3X3(x) (mat3(x))\n"
"#define saturate(x) (clamp(x, 0.0, 1.0))\n"
"#define texSample2D texture2D\n"
"#define texSample2DLod texture2DLod\n"
"#define texture2DLod texture2D\n"
"#define atan2 atan\n"
"#define ddx dFdx\n"
"#define ddy(x) dFdy(-(x))\n"
"#define GLSL 1\n\n";
auto cur = this->m_combos.begin ();
auto end = this->m_combos.end ();
for (; cur != end; cur ++)
{
this->m_content += "#define " + (*cur).first + " " + std::to_string ((*cur).second) + "\n";
}
}
else
{
this->m_content = "";
}
this->m_content.append (WallpaperEngine::FileSystem::loadFullFile (file));
this->m_content =WallpaperEngine::FileSystem::loadFullFile (file);
}
bool Compiler::peekString(std::string str, std::string::const_iterator& it)
@ -471,13 +436,49 @@ namespace WallpaperEngine::Render::Shaders
}
}
std::string finalCode;
if (this->m_recursive == false)
{
// add the opengl compatibility at the top
finalCode = "#version 120\n"
"#define highp\n"
"#define mediump\n"
"#define lowp\n"
"#define mul(x, y) (y * x)\n"
"#define frac fract\n"
"#define CAST2(x) (vec2(x))\n"
"#define CAST3(x) (vec3(x))\n"
"#define CAST4(x) (vec4(x))\n"
"#define CAST3X3(x) (mat3(x))\n"
"#define saturate(x) (clamp(x, 0.0, 1.0))\n"
"#define texSample2D texture2D\n"
"#define texSample2DLod texture2DLod\n"
"#define texture2DLod texture2D\n"
"#define atan2 atan\n"
"#define ddx dFdx\n"
"#define ddy(x) dFdy(-(x))\n"
"#define GLSL 1\n\n";
// add combo values
auto cur = this->m_combos.begin ();
auto end = this->m_combos.end ();
for (; cur != end; cur ++)
{
finalCode += "#define " + (*cur).first + " " + std::to_string ((*cur).second) + "\n";
}
}
finalCode += this->m_compiledContent;
if (this->m_recursive == false)
{
std::cout << "======================== COMPILED SHADER " << this->m_file.c_str () << " ========================" << std::endl;
std::cout << this->m_compiledContent << std::endl;
}
return this->m_compiledContent;
return finalCode;
#undef BREAK_IF_ERROR
}
@ -563,6 +564,17 @@ namespace WallpaperEngine::Render::Shaders
}
else if (type == "sampler2D")
{
// samplers can have special requirements, check what sampler we're working with and create definitions
// if needed
auto combo = data.find ("combo");
if (combo != data.end ())
{
// TODO: CHECK WHAT TEXTURE THIS REFERS TO
// add the new combo to the list
this->m_combos.insert (std::make_pair<std::string, int> (*combo, 1));
}
// samplers are not saved, we can ignore them for now
return;
}
@ -600,6 +612,11 @@ namespace WallpaperEngine::Render::Shaders
return this->m_parameters;
}
const std::map <std::string, int>& Compiler::getCombos () const
{
return this->m_combos;
}
std::map<std::string, std::string> Compiler::sVariableReplacement =
{
// attribute vec3 a_position

View File

@ -52,7 +52,7 @@ namespace WallpaperEngine::Render::Shaders
* @param combos Settings for the shader
* @param recursive Whether the compiler should add base definitions or not
*/
Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, const std::map<std::string, int>& combos, bool recursive = false);
Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive = false);
/**
* Performs the actual pre-compilation/pre-processing over the shader files
* This step is kinda big, replaces variables names on sVariableReplacement,
@ -74,6 +74,10 @@ namespace WallpaperEngine::Render::Shaders
* @return The list of parameters available for this shader with their default values
*/
const std::vector <Variables::CShaderVariable*>& getParameters () const;
/**
* @return The list of combos available for this shader after compilation
*/
const std::map <std::string, int>& getCombos () const;
private:
/**
@ -220,7 +224,7 @@ namespace WallpaperEngine::Render::Shaders
/**
* The combos the shader should be generated with
*/
const std::map <std::string, int>& m_combos;
std::map <std::string, int> m_combos;
/**
* Whether this compilation is a recursive one or not
*/