Output directly to framebuffer on last pass.

This commit is contained in:
Brandon Wright 2018-05-12 18:07:23 -05:00
parent c9ed910879
commit 21dd926a5a
2 changed files with 63 additions and 48 deletions

View File

@ -227,7 +227,8 @@ S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
if (using_shaders && using_glsl_shaders) if (using_shaders && using_glsl_shaders)
{ {
glsl_shader->render (texmap, width, height, w, h, x, allocation.height - y - h); glsl_shader->render (texmap, width, height, w, h, x, allocation.height - y - h);
glViewport (x, allocation.height - y - h, w, h); gl_swap ();
return;
} }
else if (using_shaders && using_cg_shaders) else if (using_shaders && using_cg_shaders)
{ {

View File

@ -3,9 +3,8 @@
#include "shader_helpers.h" #include "shader_helpers.h"
#include "../gtk_s9x.h" #include "../gtk_s9x.h"
static const GLfloat lut_coords[8] = { 0, 0, 1, 0, 1, 1, 0, 1 }; static const GLfloat tex_coords[16] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
static const GLfloat inv_coords[8] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
static const GLfloat tex_coords[8] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
static const GLfloat mvp_ortho[16] = { 2.0f, 0.0f, 0.0f, 0.0f, static const GLfloat mvp_ortho[16] = { 2.0f, 0.0f, 0.0f, 0.0f,
0.0f, 2.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
@ -523,7 +522,7 @@ bool GLSLShader::load_shader (char *filename)
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, lut_coords); glTexCoordPointer(2, GL_FLOAT, 0, tex_coords);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
register_uniforms(); register_uniforms();
@ -591,46 +590,56 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
/* set size of output texture /* set size of output texture
*/ */
glBindTexture(GL_TEXTURE_2D, pass[i].texture); if (!lastpass)
if (pass[i].srgb)
{ {
glEnable(GL_FRAMEBUFFER_SRGB); glBindTexture(GL_TEXTURE_2D, pass[i].texture);
glTexImage2D(GL_TEXTURE_2D, if (pass[i].srgb)
0, {
GL_SRGB8_ALPHA8, glEnable(GL_FRAMEBUFFER_SRGB);
(unsigned int) pass[i].width,
(unsigned int) pass[i].height, glTexImage2D(GL_TEXTURE_2D,
0, 0,
GL_RGBA, GL_SRGB8_ALPHA8,
GL_UNSIGNED_INT_8_8_8_8, (unsigned int) pass[i].width,
NULL); (unsigned int) pass[i].height,
0,
GL_RGBA,
GL_UNSIGNED_INT_8_8_8_8,
NULL);
}
else
{
glTexImage2D(GL_TEXTURE_2D,
0,
(pass[i].fp ? GL_RGBA32F : GL_RGBA),
(unsigned int) pass[i].width,
(unsigned int) pass[i].height,
0,
GL_RGBA,
(pass[i].fp ? GL_FLOAT : GL_UNSIGNED_INT_8_8_8_8),
NULL);
}
glViewport(0, 0, pass[i].width, pass[i].height);
// set up framebuffer and attach output texture
glBindFramebuffer(GL_FRAMEBUFFER, pass[i].fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
pass[i].texture,
0);
} }
else else
{ {
glTexImage2D(GL_TEXTURE_2D, /* output to the screen */
0, glBindFramebuffer(GL_FRAMEBUFFER, 0);
(pass[i].fp ? GL_RGBA32F : GL_RGBA), glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
(unsigned int) pass[i].width,
(unsigned int) pass[i].height,
0,
GL_RGBA,
(pass[i].fp ? GL_FLOAT : GL_UNSIGNED_INT_8_8_8_8),
NULL);
} }
// viewport determines the area we render into the output texture // viewport determines the area we render into the output texture
glViewport(0, 0, pass[i].width, pass[i].height);
// set up framebuffer and attach output texture
glBindFramebuffer(GL_FRAMEBUFFER, pass[i].fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
pass[i].texture,
0);
// set up input texture (output of previous pass) and apply filter settings // set up input texture (output of previous pass) and apply filter settings
@ -705,16 +714,9 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
NULL); NULL);
} }
glBindTexture(GL_TEXTURE_2D, pass.back().texture); glBindTexture(GL_TEXTURE_2D, orig);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
pass.back().filter == GLSL_UNDEFINED ? (gui_config->bilinear_filter ? GL_LINEAR : GL_NEAREST) : pass.back().filter);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
pass.back().filter == GLSL_UNDEFINED ? (gui_config->bilinear_filter ? GL_LINEAR : GL_NEAREST) : pass.back().filter);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pass.back().width); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pass.back().width);
glTexCoordPointer(2, GL_FLOAT, 0, inv_coords); glTexCoordPointer(2, GL_FLOAT, 0, tex_coords + 8);
} }
void GLSLShader::register_uniforms () void GLSLShader::register_uniforms ()
@ -814,6 +816,10 @@ void GLSLShader::register_uniforms ()
void GLSLShader::set_shader_vars (int p) void GLSLShader::set_shader_vars (int p)
{ {
unsigned int texunit = 0; unsigned int texunit = 0;
unsigned int offset = 0;
if (p == pass.size() - 1)
offset = 8;
GLSLUniforms *u = &pass[p].unif; GLSLUniforms *u = &pass[p].unif;
GLint mvp = glGetUniformLocation (pass[p].program, "MVPMatrix"); GLint mvp = glGetUniformLocation (pass[p].program, "MVPMatrix");
@ -834,6 +840,13 @@ void GLSLShader::set_shader_vars (int p)
/* We use non-power-of-two textures, /* We use non-power-of-two textures,
* so no need to mess with input size/texture size */ * so no need to mess with input size/texture size */
#define setTexCoords(attr) \ #define setTexCoords(attr) \
if (attr > -1) \
{ \
glEnableVertexAttribArray(attr); \
glVertexAttribPointer(attr, 2, GL_FLOAT, GL_FALSE, 0, ((float *) NULL) + offset); \
vaos.push_back (attr); \
}
#define setTexCoordsNoOffset(attr) \
if (attr > -1) \ if (attr > -1) \
{ \ { \
glEnableVertexAttribArray(attr); \ glEnableVertexAttribArray(attr); \
@ -842,7 +855,7 @@ void GLSLShader::set_shader_vars (int p)
} }
glBindBuffer (GL_ARRAY_BUFFER, vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (GLfloat) * 8, tex_coords, GL_STATIC_DRAW); glBufferData (GL_ARRAY_BUFFER, sizeof (GLfloat) * 16, tex_coords, GL_STATIC_DRAW);
float inputSize[2] = { (float) pass[p - 1].width, (float) pass[p - 1].height }; float inputSize[2] = { (float) pass[p - 1].width, (float) pass[p - 1].height };
float outputSize[2] = { (float) pass[p].width, (float) pass[p].height }; float outputSize[2] = { (float) pass[p].width, (float) pass[p].height };
@ -860,7 +873,8 @@ void GLSLShader::set_shader_vars (int p)
setTexCoords (u->TexCoord); setTexCoords (u->TexCoord);
setTexCoords (u->LUTTexCoord); setTexCoords (u->LUTTexCoord);
setTexCoords (u->VertexCoord); setTexCoordsNoOffset (u->VertexCoord);
/* ORIG parameter /* ORIG parameter
*/ */
float orig_videoSize[2] = { (float) pass[0].width, (float) pass[0].height }; float orig_videoSize[2] = { (float) pass[0].width, (float) pass[0].height };