mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
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:
parent
b8a21b3744
commit
cced3b4a18
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
#include "VideoBackends/OGL/FramebufferManager.h"
|
#include "VideoBackends/OGL/FramebufferManager.h"
|
||||||
#include "VideoBackends/OGL/GLUtil.h"
|
#include "VideoBackends/OGL/GLUtil.h"
|
||||||
@ -16,20 +17,6 @@
|
|||||||
namespace OGL
|
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[] =
|
static char s_vertex_shader[] =
|
||||||
"out vec2 uv0;\n"
|
"out vec2 uv0;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
@ -38,7 +25,7 @@ static char s_vertex_shader[] =
|
|||||||
" uv0 = rawpos;\n"
|
" uv0 = rawpos;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
void Init()
|
OpenGLPostProcessing::OpenGLPostProcessing()
|
||||||
{
|
{
|
||||||
m_enable = false;
|
m_enable = false;
|
||||||
m_width = 0;
|
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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
||||||
|
CreateHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
OpenGLPostProcessing::~OpenGLPostProcessing()
|
||||||
{
|
{
|
||||||
m_shader.Destroy();
|
m_shader.Destroy();
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &s_fbo);
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
glDeleteTextures(1, &s_texture);
|
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);
|
if (!m_enable) return;
|
||||||
}
|
|
||||||
|
|
||||||
void BlitToScreen()
|
|
||||||
{
|
|
||||||
if (!s_enable) return;
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
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);
|
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());
|
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);
|
glActiveTexture(GL_TEXTURE0+9);
|
||||||
glBindTexture(GL_TEXTURE_2D, s_texture);
|
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
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();
|
ApplyShader();
|
||||||
|
|
||||||
if (s_enable && (width != s_width || height != s_height)) {
|
if (m_enable && (width != m_width || height != m_height))
|
||||||
s_width = width;
|
{
|
||||||
s_height = height;
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
|
||||||
// alloc texture for framebuffer
|
// alloc texture for framebuffer
|
||||||
glActiveTexture(GL_TEXTURE0+9);
|
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);
|
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
|
// shader didn't changed
|
||||||
if (s_currentShader == g_ActiveConfig.sPostProcessingShader) return;
|
if (m_config.GetShader() == g_ActiveConfig.sPostProcessingShader) return;
|
||||||
s_currentShader = g_ActiveConfig.sPostProcessingShader;
|
|
||||||
s_enable = false;
|
m_enable = false;
|
||||||
s_shader.Destroy();
|
m_shader.Destroy();
|
||||||
|
m_uniform_bindings.clear();
|
||||||
|
|
||||||
// shader disabled
|
// shader disabled
|
||||||
if (g_ActiveConfig.sPostProcessingShader == "") return;
|
if (g_ActiveConfig.sPostProcessingShader == "") return;
|
||||||
|
|
||||||
// so need to compile shader
|
// so need to compile shader
|
||||||
|
std::string code = m_config.LoadShader();
|
||||||
|
|
||||||
// loading shader code
|
if (code == "") return;
|
||||||
std::string code;
|
|
||||||
std::string path = File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".glsl";
|
code = LoadShaderOptions(code);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and compile it
|
// and compile it
|
||||||
if (!ProgramShaderCache::CompileShader(s_shader, s_vertex_shader, code.c_str())) {
|
if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str())) {
|
||||||
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +190,7 @@ void ApplyShader()
|
|||||||
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
|
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
|
||||||
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
|
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;
|
std::string glsl_name = "option_" + it.first;
|
||||||
m_uniform_bindings[it.first] = glGetUniformLocation(m_shader.glprogid, glsl_name.c_str());
|
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";
|
"#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
|
} // namespace OGL
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "VideoBackends/OGL/GLUtil.h"
|
#include "VideoBackends/OGL/GLUtil.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/PostProcessing.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
|
@ -641,6 +641,9 @@ void Renderer::Shutdown()
|
|||||||
delete s_pfont;
|
delete s_pfont;
|
||||||
s_pfont = nullptr;
|
s_pfont = nullptr;
|
||||||
s_ShowEFBCopyRegions.Destroy();
|
s_ShowEFBCopyRegions.Destroy();
|
||||||
|
|
||||||
|
delete m_post_processor;
|
||||||
|
m_post_processor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Init()
|
void Renderer::Init()
|
||||||
@ -649,6 +652,8 @@ void Renderer::Init()
|
|||||||
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
||||||
s_MSAASamples);
|
s_MSAASamples);
|
||||||
|
|
||||||
|
m_post_processor = new OpenGLPostProcessing();
|
||||||
|
|
||||||
s_pfont = new RasterFont();
|
s_pfont = new RasterFont();
|
||||||
|
|
||||||
ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions,
|
ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions,
|
||||||
@ -1331,7 +1336,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||||||
|
|
||||||
ResetAPIState();
|
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);
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
TargetRectangle flipped_trc = GetTargetRectangle();
|
TargetRectangle flipped_trc = GetTargetRectangle();
|
||||||
|
|
||||||
@ -1354,7 +1359,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
// Render to the real/postprocessing buffer now.
|
// Render to the real/postprocessing buffer now.
|
||||||
PostProcessing::BindTargetFramebuffer();
|
m_post_processor->BindTargetFramebuffer();
|
||||||
|
|
||||||
// draw each xfb source
|
// draw each xfb source
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
|
||||||
@ -1413,7 +1418,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||||||
FramebufferManager::ResolveAndGetRenderTarget(rc);
|
FramebufferManager::ResolveAndGetRenderTarget(rc);
|
||||||
|
|
||||||
// Render to the real/postprocessing buffer now. (resolve have changed this in msaa mode)
|
// 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
|
// always the non-msaa fbo
|
||||||
GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
|
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);
|
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
PostProcessing::BlitToScreen();
|
m_post_processor->BlitToScreen();
|
||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
@ -210,7 +210,6 @@ void VideoBackend::Video_Prepare()
|
|||||||
VertexShaderManager::Init();
|
VertexShaderManager::Init();
|
||||||
PixelShaderManager::Init();
|
PixelShaderManager::Init();
|
||||||
ProgramShaderCache::Init();
|
ProgramShaderCache::Init();
|
||||||
PostProcessing::Init();
|
|
||||||
g_texture_cache = new TextureCache();
|
g_texture_cache = new TextureCache();
|
||||||
g_sampler_cache = new SamplerCache();
|
g_sampler_cache = new SamplerCache();
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
@ -250,7 +249,6 @@ void VideoBackend::Video_Cleanup() {
|
|||||||
g_sampler_cache = nullptr;
|
g_sampler_cache = nullptr;
|
||||||
delete g_texture_cache;
|
delete g_texture_cache;
|
||||||
g_texture_cache = nullptr;
|
g_texture_cache = nullptr;
|
||||||
PostProcessing::Shutdown();
|
|
||||||
ProgramShaderCache::Shutdown();
|
ProgramShaderCache::Shutdown();
|
||||||
VertexShaderManager::Shutdown();
|
VertexShaderManager::Shutdown();
|
||||||
PixelShaderManager::Shutdown();
|
PixelShaderManager::Shutdown();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user