Merge pull request #1440 from Sonicadvance1/attributeless-workaround

Implements PP shader system using attribute workaround.
This commit is contained in:
Ryan Houdek
2014-10-30 12:46:40 -06:00
5 changed files with 67 additions and 21 deletions

View File

@ -11,12 +11,22 @@
#include "VideoBackends/OGL/PostProcessing.h"
#include "VideoBackends/OGL/ProgramShaderCache.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h"
namespace OGL
{
static char s_vertex_workaround_shader[] =
"in vec4 rawpos;\n"
"out vec2 uv0;\n"
"uniform vec4 src_rect;\n"
"void main(void) {\n"
" gl_Position = vec4(rawpos.xy, 0.0, 1.0);\n"
" uv0 = rawpos.zw * src_rect.zw + src_rect.xy;\n"
"}\n";
static char s_vertex_shader[] =
"out vec2 uv0;\n"
"uniform vec4 src_rect;\n"
@ -29,12 +39,26 @@ static char s_vertex_shader[] =
OpenGLPostProcessing::OpenGLPostProcessing()
{
CreateHeader();
m_attribute_workaround = DriverDetails::HasBug(DriverDetails::BUG_BROKENATTRIBUTELESS);
if (m_attribute_workaround)
{
glGenBuffers(1, &m_attribute_vbo);
glGenVertexArrays(1, &m_attribute_vao);
}
m_initialized = false;
}
OpenGLPostProcessing::~OpenGLPostProcessing()
{
m_shader.Destroy();
if (m_attribute_workaround)
{
glDeleteBuffers(1, &m_attribute_vbo);
glDeleteVertexArrays(1, &m_attribute_vao);
}
}
void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle dst,
@ -46,6 +70,9 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
glViewport(dst.left, dst.bottom, dst.GetWidth(), dst.GetHeight());
if (m_attribute_workaround)
glBindVertexArray(m_attribute_vao);
m_shader.Bind();
glUniform4f(m_uniform_resolution, (float)src_width, (float)src_height, 1.0f / (float)src_width, 1.0f / (float)src_height);
@ -150,13 +177,18 @@ void OpenGLPostProcessing::ApplyShader()
code = LoadShaderOptions(code);
const char* vertex_shader = s_vertex_shader;
if (m_attribute_workaround)
vertex_shader = s_vertex_workaround_shader;
// and compile it
if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str()))
if (!ProgramShaderCache::CompileShader(m_shader, vertex_shader, code.c_str()))
{
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str());
code = LoadShaderOptions(default_shader);
ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str());
ProgramShaderCache::CompileShader(m_shader, vertex_shader, code.c_str());
}
// read uniform locations
@ -164,6 +196,23 @@ void OpenGLPostProcessing::ApplyShader()
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
m_uniform_src_rect = glGetUniformLocation(m_shader.glprogid, "src_rect");
if (m_attribute_workaround)
{
GLfloat vertices[] = {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
-1.f, 1.f, 0.f, 1.f,
1.f, 1.f, 1.f, 1.f,
};
glBindBuffer(GL_ARRAY_BUFFER, m_attribute_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(m_attribute_vao);
glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 4, GL_FLOAT, 0, 0, nullptr);
}
for (const auto& it : m_config.GetOptions())
{
std::string glsl_name = "option_" + it.first;