mirror of https://github.com/snes9xgit/snes9x.git
Clean up some stuff. Add LUT features to glsl shaders.
This commit is contained in:
parent
bdcec7e4b5
commit
3b01b57162
|
@ -11,6 +11,7 @@
|
||||||
#include "gtk_display.h"
|
#include "gtk_display.h"
|
||||||
#include "gtk_display_driver_opengl.h"
|
#include "gtk_display_driver_opengl.h"
|
||||||
|
|
||||||
|
#include "shaders/shader_helpers.h"
|
||||||
#include "shaders/CGLCG.h"
|
#include "shaders/CGLCG.h"
|
||||||
|
|
||||||
S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver (Snes9xWindow *window,
|
S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver (Snes9xWindow *window,
|
||||||
|
@ -346,6 +347,10 @@ S9xOpenGLDisplayDriver::update_texture_size (int width, int height)
|
||||||
int
|
int
|
||||||
S9xOpenGLDisplayDriver::pbos_available (void)
|
S9xOpenGLDisplayDriver::pbos_available (void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (gl_version_at_least (2, 1))
|
||||||
|
return 1;
|
||||||
|
|
||||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||||
|
|
||||||
if (!extensions)
|
if (!extensions)
|
||||||
|
@ -367,7 +372,27 @@ S9xOpenGLDisplayDriver::shaders_available (void)
|
||||||
if (!extensions)
|
if (!extensions)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (strstr (extensions, "fragment_program"))
|
if (strstr (extensions, "fragment_program") ||
|
||||||
|
strstr (extensions, "fragment_shader"))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int npot_available (void)
|
||||||
|
{
|
||||||
|
if (gl_version_at_least (2, 0))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strstr (extensions, "non_power_of_two") ||
|
||||||
|
strstr (extensions, "npot"))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -381,14 +406,13 @@ S9xOpenGLDisplayDriver::load_shaders (const char *shader_file)
|
||||||
xmlDoc *xml_doc = NULL;
|
xmlDoc *xml_doc = NULL;
|
||||||
xmlNodePtr node = NULL;
|
xmlNodePtr node = NULL;
|
||||||
char *fragment = NULL, *vertex = NULL;
|
char *fragment = NULL, *vertex = NULL;
|
||||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
|
||||||
|
|
||||||
int length = strlen (shader_file);
|
int length = strlen (shader_file);
|
||||||
|
|
||||||
if ((length > 6 && !strcasecmp(shader_file + length - 6, ".glslp")) ||
|
if ((length > 6 && !strcasecmp(shader_file + length - 6, ".glslp")) ||
|
||||||
(length > 5 && !strcasecmp(shader_file + length - 5, ".glsl")))
|
(length > 5 && !strcasecmp(shader_file + length - 5, ".glsl")))
|
||||||
{
|
{
|
||||||
if (shaders_available() && strstr(extensions, "non_power_of_two"))
|
if (shaders_available() && npot_available())
|
||||||
{
|
{
|
||||||
glsl_shader = new GLSLShader;
|
glsl_shader = new GLSLShader;
|
||||||
if (glsl_shader->load_shader ((char *) shader_file))
|
if (glsl_shader->load_shader ((char *) shader_file))
|
||||||
|
@ -557,7 +581,7 @@ S9xOpenGLDisplayDriver::opengl_defaults (void)
|
||||||
texture_height = scaled_max_height;
|
texture_height = scaled_max_height;
|
||||||
dyn_resizing = TRUE;
|
dyn_resizing = TRUE;
|
||||||
}
|
}
|
||||||
else if (strstr (extensions, "GL_ARB_texture_non_power_of_two"))
|
else if (npot_available ())
|
||||||
{
|
{
|
||||||
dyn_resizing = TRUE;
|
dyn_resizing = TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,25 @@ static int scale_string_to_enum(const char *string, bool last)
|
||||||
return GLSL_SOURCE;
|
return GLSL_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wrap_mode_string_to_enum(const char *string)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(string, "repeat"))
|
||||||
|
{
|
||||||
|
return GL_REPEAT;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp(string, "clamp_to_edge"))
|
||||||
|
{
|
||||||
|
return GL_CLAMP_TO_EDGE;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp(string, "clamp"))
|
||||||
|
{
|
||||||
|
return GL_CLAMP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return GL_CLAMP_TO_BORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GLSLShader::load_shader_file (char *filename)
|
bool GLSLShader::load_shader_file (char *filename)
|
||||||
{
|
{
|
||||||
ConfigFile conf;
|
ConfigFile conf;
|
||||||
|
@ -148,8 +167,24 @@ bool GLSLShader::load_shader_file (char *filename)
|
||||||
sprintf(key, "::frame_count_mod%u", i);
|
sprintf(key, "::frame_count_mod%u", i);
|
||||||
pass.frame_count_mod = conf.GetInt(key, 0);
|
pass.frame_count_mod = conf.GetInt(key, 0);
|
||||||
|
|
||||||
sprintf(key, "::float_framebuffer%u", i);
|
if (float_texture_available ())
|
||||||
pass.fp = conf.GetBool(key);
|
{
|
||||||
|
sprintf(key, "::float_framebuffer%u", i);
|
||||||
|
pass.fp = conf.GetBool(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pass.fp = false;
|
||||||
|
|
||||||
|
if (srgb_available ())
|
||||||
|
{
|
||||||
|
sprintf(key, "::srgb_framebuffer%u", i);
|
||||||
|
pass.srgb = conf.GetBool(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pass.srgb = false;
|
||||||
|
|
||||||
|
sprintf(key, "::alias%u", i);
|
||||||
|
strcpy(pass.alias, conf.GetString(key, ""));
|
||||||
|
|
||||||
this->pass.push_back(pass);
|
this->pass.push_back(pass);
|
||||||
}
|
}
|
||||||
|
@ -165,8 +200,21 @@ bool GLSLShader::load_shader_file (char *filename)
|
||||||
sprintf(key, "::%s", id);
|
sprintf(key, "::%s", id);
|
||||||
strcpy(lut.id, id);
|
strcpy(lut.id, id);
|
||||||
strcpy(lut.filename, conf.GetString(key, ""));
|
strcpy(lut.filename, conf.GetString(key, ""));
|
||||||
|
|
||||||
|
sprintf(key, "::%s_wrap_mode", id);
|
||||||
|
lut.wrap_mode = wrap_mode_string_to_enum (conf.GetString (key, ""));
|
||||||
|
|
||||||
|
sprintf(key, "::%s_mipmap", id);
|
||||||
|
lut.mipmap = conf.GetBool (key);
|
||||||
|
|
||||||
sprintf(key, "::%s_linear", id);
|
sprintf(key, "::%s_linear", id);
|
||||||
lut.filter = (conf.GetBool(key, false)) ? GL_LINEAR : GL_NEAREST;
|
lut.filter = (conf.GetBool(key, false)) ? GL_LINEAR : GL_NEAREST;
|
||||||
|
|
||||||
|
if (lut.mipmap)
|
||||||
|
{
|
||||||
|
lut.filter = (lut.filter == GL_LINEAR) ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST;
|
||||||
|
}
|
||||||
|
|
||||||
this->lut.push_back(lut);
|
this->lut.push_back(lut);
|
||||||
|
|
||||||
id = strtok(NULL, ";");
|
id = strtok(NULL, ";");
|
||||||
|
@ -192,7 +240,11 @@ static void strip_parameter_pragmas(char *buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint compile_shader (char *program, const char *defines, GLuint type, GLuint *out)
|
static GLuint compile_shader (char *program,
|
||||||
|
const char *aliases,
|
||||||
|
const char *defines,
|
||||||
|
GLuint type,
|
||||||
|
GLuint *out)
|
||||||
{
|
{
|
||||||
char info_log[1024];
|
char info_log[1024];
|
||||||
char *ptr = program;
|
char *ptr = program;
|
||||||
|
@ -211,6 +263,7 @@ static GLuint compile_shader (char *program, const char *defines, GLuint type, G
|
||||||
}
|
}
|
||||||
|
|
||||||
complete_program += version;
|
complete_program += version;
|
||||||
|
complete_program += aliases;
|
||||||
complete_program += defines;
|
complete_program += defines;
|
||||||
complete_program += ptr;
|
complete_program += ptr;
|
||||||
|
|
||||||
|
@ -235,6 +288,7 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
{
|
{
|
||||||
char shader_path[PATH_MAX];
|
char shader_path[PATH_MAX];
|
||||||
char temp[PATH_MAX];
|
char temp[PATH_MAX];
|
||||||
|
std::string aliases = "";
|
||||||
GLint status;
|
GLint status;
|
||||||
char log[1024];
|
char log[1024];
|
||||||
|
|
||||||
|
@ -251,6 +305,20 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
if (!load_shader_file(filename))
|
if (!load_shader_file(filename))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (unsigned int i = 1; i < pass.size(); i++)
|
||||||
|
{
|
||||||
|
if (pass[i].alias && *pass[i].alias)
|
||||||
|
{
|
||||||
|
aliases += "#define ";
|
||||||
|
aliases += pass[i].alias;
|
||||||
|
aliases += " Pass";
|
||||||
|
aliases += std::to_string(i - 1);
|
||||||
|
aliases += "Texture\n";
|
||||||
|
printf ("%s\n", aliases.c_str());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
for (unsigned int i = 1; i < pass.size(); i++)
|
for (unsigned int i = 1; i < pass.size(); i++)
|
||||||
{
|
{
|
||||||
GLSLPass *p = &pass[i];
|
GLSLPass *p = &pass[i];
|
||||||
|
@ -268,7 +336,8 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
strip_parameter_pragmas(contents);
|
strip_parameter_pragmas(contents);
|
||||||
|
|
||||||
if (!compile_shader (contents,
|
if (!compile_shader (contents,
|
||||||
"#define VERTEX\n", // #define PARAMETER_UNIFORM\n",
|
"#define VERTEX\n",// #define PARAMETER_UNIFORM\n",
|
||||||
|
aliases.c_str(),
|
||||||
GL_VERTEX_SHADER,
|
GL_VERTEX_SHADER,
|
||||||
&vertex_shader) || !vertex_shader)
|
&vertex_shader) || !vertex_shader)
|
||||||
{
|
{
|
||||||
|
@ -278,6 +347,7 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
|
|
||||||
if (!compile_shader (contents,
|
if (!compile_shader (contents,
|
||||||
"#define FRAGMENT\n", // #define PARAMETER_UNIFORM\n",
|
"#define FRAGMENT\n", // #define PARAMETER_UNIFORM\n",
|
||||||
|
aliases.c_str(),
|
||||||
GL_FRAGMENT_SHADER,
|
GL_FRAGMENT_SHADER,
|
||||||
&fragment_shader) || !fragment_shader)
|
&fragment_shader) || !fragment_shader)
|
||||||
{
|
{
|
||||||
|
@ -325,8 +395,8 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
*/
|
*/
|
||||||
glGenTextures(1, &l->texture);
|
glGenTextures(1, &l->texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, l->texture);
|
glBindTexture(GL_TEXTURE_2D, l->texture);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, l->wrap_mode);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, l->wrap_mode);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, l->filter);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, l->filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, l->filter);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, l->filter);
|
||||||
|
|
||||||
|
@ -384,6 +454,9 @@ bool GLSLShader::load_shader (char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l->mipmap)
|
||||||
|
glGenerateMipmap (GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
@ -456,15 +529,32 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
|
||||||
*/
|
*/
|
||||||
glBindTexture(GL_TEXTURE_2D, pass[i].texture);
|
glBindTexture(GL_TEXTURE_2D, pass[i].texture);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
if (pass[i].srgb)
|
||||||
0,
|
{
|
||||||
(pass[i].fp ? GL_RGBA32F : GL_RGBA),
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// 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);
|
glViewport(0, 0, pass[i].width, pass[i].height);
|
||||||
|
@ -500,6 +590,11 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
|
||||||
/* reset client states enabled during setShaderVars
|
/* reset client states enabled during setShaderVars
|
||||||
*/
|
*/
|
||||||
clear_shader_vars();
|
clear_shader_vars();
|
||||||
|
|
||||||
|
if (pass[i].srgb)
|
||||||
|
{
|
||||||
|
glDisable (GL_FRAMEBUFFER_SRGB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disable framebuffer
|
/* disable framebuffer
|
||||||
|
|
|
@ -56,11 +56,13 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
|
char alias[256];
|
||||||
int scale_type_x;
|
int scale_type_x;
|
||||||
int scale_type_y;
|
int scale_type_y;
|
||||||
float scale_x;
|
float scale_x;
|
||||||
float scale_y;
|
float scale_y;
|
||||||
bool fp;
|
bool fp;
|
||||||
|
bool srgb;
|
||||||
int frame_count_mod;
|
int frame_count_mod;
|
||||||
unsigned int frame_count;
|
unsigned int frame_count;
|
||||||
|
|
||||||
|
@ -82,6 +84,8 @@ typedef struct
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
GLuint filter;
|
GLuint filter;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
GLuint wrap_mode;
|
||||||
|
bool mipmap;
|
||||||
} GLSLLut;
|
} GLSLLut;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -28,6 +28,53 @@ static void gl_error_callback( GLenum source,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gl_version_at_least (int maj, int min)
|
||||||
|
{
|
||||||
|
static int major_version = -1;
|
||||||
|
static int minor_version = -1;
|
||||||
|
|
||||||
|
if (major_version < 0 || minor_version < 0)
|
||||||
|
{
|
||||||
|
glGetIntegerv (GL_MAJOR_VERSION, &major_version);
|
||||||
|
glGetIntegerv (GL_MINOR_VERSION, &minor_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maj > major_version)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (maj == major_version && min >= minor_version)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool srgb_available (void)
|
||||||
|
{
|
||||||
|
if (gl_version_at_least (3, 0))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||||
|
|
||||||
|
if (strstr (extensions, "texture_sRGB") &&
|
||||||
|
strstr (extensions, "framebuffer_sRGB"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool float_texture_available (void)
|
||||||
|
{
|
||||||
|
if (gl_version_at_least (3, 2))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||||
|
|
||||||
|
if (strstr (extensions, "texture_float"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void glLogErrors (void)
|
void glLogErrors (void)
|
||||||
{
|
{
|
||||||
glEnable (GL_DEBUG_OUTPUT);
|
glEnable (GL_DEBUG_OUTPUT);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef __IMAGE_FILE_FORMATS_H
|
#ifndef __SHADER_HELPERS_H
|
||||||
#define __IMAGE_FILE_FORMATS_H
|
#define __SHADER_HELPERS_H
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
@ -41,4 +41,8 @@ bool loadTGA(const char* filename, STGA& tgaFile);
|
||||||
|
|
||||||
void glLogErrors (void);
|
void glLogErrors (void);
|
||||||
|
|
||||||
#endif // __IMAGE_FILE_FORMATS_H
|
bool srgb_available (void);
|
||||||
|
bool float_texture_available (void);
|
||||||
|
bool gl_version_at_least (int maj, int min);
|
||||||
|
|
||||||
|
#endif // __SHADER_HELPERS_H
|
||||||
|
|
Loading…
Reference in New Issue