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_driver_opengl.h"
|
||||
|
||||
#include "shaders/shader_helpers.h"
|
||||
#include "shaders/CGLCG.h"
|
||||
|
||||
S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver (Snes9xWindow *window,
|
||||
|
@ -346,6 +347,10 @@ S9xOpenGLDisplayDriver::update_texture_size (int width, int height)
|
|||
int
|
||||
S9xOpenGLDisplayDriver::pbos_available (void)
|
||||
{
|
||||
|
||||
if (gl_version_at_least (2, 1))
|
||||
return 1;
|
||||
|
||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||
|
||||
if (!extensions)
|
||||
|
@ -367,7 +372,27 @@ S9xOpenGLDisplayDriver::shaders_available (void)
|
|||
if (!extensions)
|
||||
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;
|
||||
}
|
||||
|
@ -381,14 +406,13 @@ S9xOpenGLDisplayDriver::load_shaders (const char *shader_file)
|
|||
xmlDoc *xml_doc = NULL;
|
||||
xmlNodePtr node = NULL;
|
||||
char *fragment = NULL, *vertex = NULL;
|
||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||
|
||||
int length = strlen (shader_file);
|
||||
|
||||
if ((length > 6 && !strcasecmp(shader_file + length - 6, ".glslp")) ||
|
||||
(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;
|
||||
if (glsl_shader->load_shader ((char *) shader_file))
|
||||
|
@ -557,7 +581,7 @@ S9xOpenGLDisplayDriver::opengl_defaults (void)
|
|||
texture_height = scaled_max_height;
|
||||
dyn_resizing = TRUE;
|
||||
}
|
||||
else if (strstr (extensions, "GL_ARB_texture_non_power_of_two"))
|
||||
else if (npot_available ())
|
||||
{
|
||||
dyn_resizing = TRUE;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,25 @@ static int scale_string_to_enum(const char *string, bool last)
|
|||
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)
|
||||
{
|
||||
ConfigFile conf;
|
||||
|
@ -148,8 +167,24 @@ bool GLSLShader::load_shader_file (char *filename)
|
|||
sprintf(key, "::frame_count_mod%u", i);
|
||||
pass.frame_count_mod = conf.GetInt(key, 0);
|
||||
|
||||
if (float_texture_available ())
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -165,8 +200,21 @@ bool GLSLShader::load_shader_file (char *filename)
|
|||
sprintf(key, "::%s", id);
|
||||
strcpy(lut.id, id);
|
||||
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);
|
||||
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);
|
||||
|
||||
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 *ptr = program;
|
||||
|
@ -211,6 +263,7 @@ static GLuint compile_shader (char *program, const char *defines, GLuint type, G
|
|||
}
|
||||
|
||||
complete_program += version;
|
||||
complete_program += aliases;
|
||||
complete_program += defines;
|
||||
complete_program += ptr;
|
||||
|
||||
|
@ -235,6 +288,7 @@ bool GLSLShader::load_shader (char *filename)
|
|||
{
|
||||
char shader_path[PATH_MAX];
|
||||
char temp[PATH_MAX];
|
||||
std::string aliases = "";
|
||||
GLint status;
|
||||
char log[1024];
|
||||
|
||||
|
@ -251,6 +305,20 @@ bool GLSLShader::load_shader (char *filename)
|
|||
if (!load_shader_file(filename))
|
||||
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++)
|
||||
{
|
||||
GLSLPass *p = &pass[i];
|
||||
|
@ -268,7 +336,8 @@ bool GLSLShader::load_shader (char *filename)
|
|||
strip_parameter_pragmas(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,
|
||||
&vertex_shader) || !vertex_shader)
|
||||
{
|
||||
|
@ -278,6 +347,7 @@ bool GLSLShader::load_shader (char *filename)
|
|||
|
||||
if (!compile_shader (contents,
|
||||
"#define FRAGMENT\n", // #define PARAMETER_UNIFORM\n",
|
||||
aliases.c_str(),
|
||||
GL_FRAGMENT_SHADER,
|
||||
&fragment_shader) || !fragment_shader)
|
||||
{
|
||||
|
@ -325,8 +395,8 @@ bool GLSLShader::load_shader (char *filename)
|
|||
*/
|
||||
glGenTextures(1, &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_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, l->wrap_mode);
|
||||
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_MIN_FILTER, l->filter);
|
||||
|
||||
|
@ -384,6 +454,9 @@ bool GLSLShader::load_shader (char *filename)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l->mipmap)
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
@ -456,6 +529,22 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
|
|||
*/
|
||||
glBindTexture(GL_TEXTURE_2D, pass[i].texture);
|
||||
|
||||
if (pass[i].srgb)
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_SRGB8_ALPHA8,
|
||||
(unsigned int) pass[i].width,
|
||||
(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),
|
||||
|
@ -463,8 +552,9 @@ void GLSLShader::render(GLuint &orig, int width, int height, int viewport_width,
|
|||
(unsigned int) pass[i].height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_INT_8_8_8_8,
|
||||
(pass[i].fp ? GL_FLOAT : GL_UNSIGNED_INT_8_8_8_8),
|
||||
NULL);
|
||||
}
|
||||
|
||||
// viewport determines the area we render into the output texture
|
||||
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
|
||||
*/
|
||||
clear_shader_vars();
|
||||
|
||||
if (pass[i].srgb)
|
||||
{
|
||||
glDisable (GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
}
|
||||
|
||||
/* disable framebuffer
|
||||
|
|
|
@ -56,11 +56,13 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
char filename[PATH_MAX];
|
||||
char alias[256];
|
||||
int scale_type_x;
|
||||
int scale_type_y;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
bool fp;
|
||||
bool srgb;
|
||||
int frame_count_mod;
|
||||
unsigned int frame_count;
|
||||
|
||||
|
@ -82,6 +84,8 @@ typedef struct
|
|||
char filename[PATH_MAX];
|
||||
GLuint filter;
|
||||
GLuint texture;
|
||||
GLuint wrap_mode;
|
||||
bool mipmap;
|
||||
} GLSLLut;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -28,6 +28,53 @@ static void gl_error_callback( GLenum source,
|
|||
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)
|
||||
{
|
||||
glEnable (GL_DEBUG_OUTPUT);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __IMAGE_FILE_FORMATS_H
|
||||
#define __IMAGE_FILE_FORMATS_H
|
||||
#ifndef __SHADER_HELPERS_H
|
||||
#define __SHADER_HELPERS_H
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
|
@ -41,4 +41,8 @@ bool loadTGA(const char* filename, STGA& tgaFile);
|
|||
|
||||
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