summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/PostProcessing.cpp
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-07-29 11:57:02 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2014-08-13 01:05:15 -0500
commitcced3b4a18b5116a715bb2bfc40f3f6c47165640 (patch)
tree819d2fbf76bfa07abfb1e652b578c27484b84151 /Source/Core/VideoBackends/OGL/PostProcessing.cpp
parentb8a21b37446e80b2c6a249933babe9acae9e618e (diff)
Change OpenGL's post processing to use the new VideoCommon PP object.
Let's OpenGL's PostProcessing namespace be changed to a class inheriting from VideoCommon's PostProcessing class.
Diffstat (limited to 'Source/Core/VideoBackends/OGL/PostProcessing.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/PostProcessing.cpp202
1 files changed, 137 insertions, 65 deletions
diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.cpp b/Source/Core/VideoBackends/OGL/PostProcessing.cpp
index 06a15b07cc..dee133ed03 100644
--- a/Source/Core/VideoBackends/OGL/PostProcessing.cpp
+++ b/Source/Core/VideoBackends/OGL/PostProcessing.cpp
@@ -4,6 +4,7 @@
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
+#include "Common/StringUtil.h"
#include "VideoBackends/OGL/FramebufferManager.h"
#include "VideoBackends/OGL/GLUtil.h"
@@ -16,20 +17,6 @@
namespace OGL
{
-namespace PostProcessing
-{
-
-static std::string s_currentShader;
-static SHADER s_shader;
-static bool s_enable;
-
-static u32 s_width;
-static u32 s_height;
-static GLuint s_fbo;
-static GLuint s_texture;
-
-static GLuint s_uniform_resolution;
-
static char s_vertex_shader[] =
"out vec2 uv0;\n"
"void main(void) {\n"
@@ -38,7 +25,7 @@ static char s_vertex_shader[] =
" uv0 = rawpos;\n"
"}\n";
-void Init()
+OpenGLPostProcessing::OpenGLPostProcessing()
{
m_enable = false;
m_width = 0;
@@ -51,98 +38,151 @@ void Init()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glBindFramebuffer(GL_FRAMEBUFFER, s_fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_texture, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
FramebufferManager::SetFramebuffer(0);
+
+ CreateHeader();
}
-void Shutdown()
+OpenGLPostProcessing::~OpenGLPostProcessing()
{
m_shader.Destroy();
- glDeleteFramebuffers(1, &s_fbo);
- glDeleteTextures(1, &s_texture);
+ glDeleteFramebuffers(1, &m_fbo);
+ glDeleteTextures(1, &m_texture);
}
-void ReloadShader()
+void OpenGLPostProcessing::BindTargetFramebuffer()
{
- s_currentShader = "";
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_enable ? m_fbo : 0);
}
-void BindTargetFramebuffer ()
+void OpenGLPostProcessing::BlitToScreen()
{
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_enable ? s_fbo : 0);
-}
-
-void BlitToScreen()
-{
- if (!s_enable) return;
+ if (!m_enable) return;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- glViewport(0, 0, s_width, s_height);
+ glViewport(0, 0, m_width, m_height);
- s_shader.Bind();
+ m_shader.Bind();
glUniform4f(m_uniform_resolution, (float)m_width, (float)m_height, 1.0f/(float)m_width, 1.0f/(float)m_height);
glUniform1ui(m_uniform_time, (GLuint)m_timer.GetTimeElapsed());
- glUniform4f(s_uniform_resolution, (float)s_width, (float)s_height, 1.0f/(float)s_width, 1.0f/(float)s_height);
+ if (m_config.IsDirty())
+ {
+ for (auto& it : m_config.GetOptions())
+ {
+ if (it.second.m_dirty)
+ {
+ switch (it.second.m_type)
+ {
+ case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_BOOL:
+ glUniform1i(m_uniform_bindings[it.first], it.second.m_bool_value);
+ break;
+ case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER:
+ switch (it.second.m_integer_values.size())
+ {
+ case 1:
+ glUniform1i(m_uniform_bindings[it.first], it.second.m_integer_values[0]);
+ break;
+ case 2:
+ glUniform2i(m_uniform_bindings[it.first],
+ it.second.m_integer_values[0],
+ it.second.m_integer_values[1]);
+ break;
+ case 3:
+ glUniform3i(m_uniform_bindings[it.first],
+ it.second.m_integer_values[0],
+ it.second.m_integer_values[1],
+ it.second.m_integer_values[2]);
+ break;
+ case 4:
+ glUniform4i(m_uniform_bindings[it.first],
+ it.second.m_integer_values[0],
+ it.second.m_integer_values[1],
+ it.second.m_integer_values[2],
+ it.second.m_integer_values[3]);
+ break;
+ }
+ break;
+ case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT:
+ switch (it.second.m_float_values.size())
+ {
+ case 1:
+ glUniform1f(m_uniform_bindings[it.first], it.second.m_float_values[0]);
+ break;
+ case 2:
+ glUniform2f(m_uniform_bindings[it.first],
+ it.second.m_float_values[0],
+ it.second.m_float_values[1]);
+ break;
+ case 3:
+ glUniform3f(m_uniform_bindings[it.first],
+ it.second.m_float_values[0],
+ it.second.m_float_values[1],
+ it.second.m_float_values[2]);
+ break;
+ case 4:
+ glUniform4f(m_uniform_bindings[it.first],
+ it.second.m_float_values[0],
+ it.second.m_float_values[1],
+ it.second.m_float_values[2],
+ it.second.m_float_values[3]);
+ break;
+ }
+ break;
+ }
+ it.second.m_dirty = false;
+ }
+ }
+ m_config.SetDirty(false);
+ }
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, s_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-/* glBindFramebuffer(GL_READ_FRAMEBUFFER, s_fbo);
-
- glBlitFramebuffer(rc.left, rc.bottom, rc.right, rc.top,
- rc.left, rc.bottom, rc.right, rc.top,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);*/
}
-void Update ( u32 width, u32 height )
+void OpenGLPostProcessing::Update(u32 width, u32 height)
{
ApplyShader();
- if (s_enable && (width != s_width || height != s_height)) {
- s_width = width;
- s_height = height;
+ if (m_enable && (width != m_width || height != m_height))
+ {
+ m_width = width;
+ m_height = height;
// alloc texture for framebuffer
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, s_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
}
-void ApplyShader()
+void OpenGLPostProcessing::ApplyShader()
{
// shader didn't changed
- if (s_currentShader == g_ActiveConfig.sPostProcessingShader) return;
- s_currentShader = g_ActiveConfig.sPostProcessingShader;
- s_enable = false;
- s_shader.Destroy();
+ if (m_config.GetShader() == g_ActiveConfig.sPostProcessingShader) return;
+
+ m_enable = false;
+ m_shader.Destroy();
+ m_uniform_bindings.clear();
// shader disabled
if (g_ActiveConfig.sPostProcessingShader == "") return;
// so need to compile shader
+ std::string code = m_config.LoadShader();
- // loading shader code
- std::string code;
- std::string path = File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".glsl";
- if (!File::Exists(path))
- {
- // Fallback to shared user dir
- path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + g_ActiveConfig.sPostProcessingShader + ".glsl";
- }
- if (!File::ReadFileToString(path, code)) {
- ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str());
- return;
- }
+ if (code == "") return;
+
+ code = LoadShaderOptions(code);
// and compile it
- if (!ProgramShaderCache::CompileShader(s_shader, s_vertex_shader, code.c_str())) {
- ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
+ if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str())) {
+ ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str());
return;
}
@@ -150,7 +190,7 @@ void ApplyShader()
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
- for (const auto& it : m_options)
+ for (const auto& it : m_config.GetOptions())
{
std::string glsl_name = "option_" + it.first;
m_uniform_bindings[it.first] = glGetUniformLocation(m_shader.glprogid, glsl_name.c_str());
@@ -225,6 +265,38 @@ void OpenGLPostProcessing::CreateHeader()
"#define OptionEnabled(x) (option_#x != 0)\n";
}
-} // namespace
+std::string OpenGLPostProcessing::LoadShaderOptions(const std::string& code)
+{
+ std::string glsl_options = "";
+ m_uniform_bindings.clear();
+
+ 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());
+ }
+ else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
+ {
+ u32 count = it.second.m_integer_values.size();
+ if (count == 1)
+ glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
+ else
+ glsl_options += StringFromFormat("uniform int%d option_%s;\n", count, it.first.c_str());
+ }
+ else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT)
+ {
+ u32 count = it.second.m_float_values.size();
+ if (count == 1)
+ glsl_options += StringFromFormat("uniform float option_%s;\n", it.first.c_str());
+ else
+ glsl_options += StringFromFormat("uniform float%d option_%s;\n", count, it.first.c_str());
+ }
+
+ m_uniform_bindings[it.first] = 0;
+ }
+
+ return m_glsl_header + glsl_options + code;
+}
} // namespace OGL