OGL: Use struct for post-processing shader options

This removes the need for token pasting, which isn't supported in GLSL
ES. Shouldn't cause any issues unless people are using reserved keywords
as option names.
This commit is contained in:
Stenzek 2017-04-16 13:17:10 +10:00
parent a389ae0711
commit e370f6a82a
2 changed files with 21 additions and 14 deletions

View File

@ -131,8 +131,9 @@ void OpenGLPostProcessing::ApplyShader()
m_uniform_bindings.clear();
// load shader code
std::string code = m_config.LoadShader();
code = LoadShaderOptions(code);
std::string main_code = m_config.LoadShader();
std::string options_code = LoadShaderOptions();
std::string code = m_glsl_header + options_code + main_code;
// and compile it
if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code))
@ -151,7 +152,7 @@ void OpenGLPostProcessing::ApplyShader()
for (const auto& it : m_config.GetOptions())
{
std::string glsl_name = "option_" + it.first;
std::string glsl_name = "options." + it.first;
m_uniform_bindings[it.first] = glGetUniformLocation(m_shader.glprogid, glsl_name.c_str());
}
m_initialized = true;
@ -225,45 +226,51 @@ void OpenGLPostProcessing::CreateHeader()
"\tocol0 = color;\n"
"}\n"
"#define GetOption(x) (option_##x)\n"
"#define OptionEnabled(x) (option_##x != 0)\n";
"#define GetOption(x) (options.x)\n"
"#define OptionEnabled(x) (options.x != 0)\n";
}
std::string OpenGLPostProcessing::LoadShaderOptions(const std::string& code)
std::string OpenGLPostProcessing::LoadShaderOptions()
{
std::string glsl_options = "";
m_uniform_bindings.clear();
if (m_config.GetOptions().empty())
return "";
std::string glsl_options = "struct Options\n{\n";
for (const auto& it : m_config.GetOptions())
{
if (it.second.m_type ==
PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_BOOL)
{
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
glsl_options += StringFromFormat("int %s;\n", it.first.c_str());
}
else if (it.second.m_type ==
PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
{
u32 count = static_cast<u32>(it.second.m_integer_values.size());
if (count == 1)
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
glsl_options += StringFromFormat("int %s;\n", it.first.c_str());
else
glsl_options += StringFromFormat("uniform int%d option_%s;\n", count, it.first.c_str());
glsl_options += StringFromFormat("int%d %s;\n", count, it.first.c_str());
}
else if (it.second.m_type ==
PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT)
{
u32 count = static_cast<u32>(it.second.m_float_values.size());
if (count == 1)
glsl_options += StringFromFormat("uniform float option_%s;\n", it.first.c_str());
glsl_options += StringFromFormat("float %s;\n", it.first.c_str());
else
glsl_options += StringFromFormat("uniform float%d option_%s;\n", count, it.first.c_str());
glsl_options += StringFromFormat("float%d %s;\n", count, it.first.c_str());
}
m_uniform_bindings[it.first] = 0;
}
return m_glsl_header + glsl_options + code;
glsl_options += "};\n";
glsl_options += "uniform Options options;\n";
return glsl_options;
}
} // namespace OGL

View File

@ -38,7 +38,7 @@ private:
std::unordered_map<std::string, GLuint> m_uniform_bindings;
void CreateHeader();
std::string LoadShaderOptions(const std::string& code);
std::string LoadShaderOptions();
};
} // namespace