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.
This commit is contained in:
Ryan Houdek 2014-07-29 11:57:02 -05:00
parent b8a21b3744
commit cced3b4a18
4 changed files with 148 additions and 71 deletions

View File

@ -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);
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D, s_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);*/
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);
}
void Update ( u32 width, u32 height )
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D, m_texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
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

View File

@ -8,6 +8,8 @@
#include <unordered_map>
#include "VideoBackends/OGL/GLUtil.h"
#include "VideoCommon/PostProcessing.h"
#include "VideoCommon/VideoCommon.h"
namespace OGL

View File

@ -641,6 +641,9 @@ void Renderer::Shutdown()
delete s_pfont;
s_pfont = nullptr;
s_ShowEFBCopyRegions.Destroy();
delete m_post_processor;
m_post_processor = nullptr;
}
void Renderer::Init()
@ -649,6 +652,8 @@ void Renderer::Init()
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples);
m_post_processor = new OpenGLPostProcessing();
s_pfont = new RasterFont();
ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions,
@ -1331,7 +1336,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
ResetAPIState();
PostProcessing::Update(s_backbuffer_width, s_backbuffer_height);
m_post_processor->Update(s_backbuffer_width, s_backbuffer_height);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
TargetRectangle flipped_trc = GetTargetRectangle();
@ -1354,7 +1359,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
if (g_ActiveConfig.bUseXFB)
{
// Render to the real/postprocessing buffer now.
PostProcessing::BindTargetFramebuffer();
m_post_processor->BindTargetFramebuffer();
// draw each xfb source
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
@ -1413,7 +1418,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
FramebufferManager::ResolveAndGetRenderTarget(rc);
// Render to the real/postprocessing buffer now. (resolve have changed this in msaa mode)
PostProcessing::BindTargetFramebuffer();
m_post_processor->BindTargetFramebuffer();
// always the non-msaa fbo
GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
@ -1424,7 +1429,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
PostProcessing::BlitToScreen();
m_post_processor->BlitToScreen();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

View File

@ -210,7 +210,6 @@ void VideoBackend::Video_Prepare()
VertexShaderManager::Init();
PixelShaderManager::Init();
ProgramShaderCache::Init();
PostProcessing::Init();
g_texture_cache = new TextureCache();
g_sampler_cache = new SamplerCache();
Renderer::Init();
@ -250,7 +249,6 @@ void VideoBackend::Video_Cleanup() {
g_sampler_cache = nullptr;
delete g_texture_cache;
g_texture_cache = nullptr;
PostProcessing::Shutdown();
ProgramShaderCache::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown();