Add filter attributes.

This commit is contained in:
Themaister 2011-03-14 21:28:30 +01:00
parent f870080497
commit 01cf24f15f
5 changed files with 100 additions and 8 deletions

View File

@ -263,6 +263,22 @@ static inline unsigned gl_shader_num(void)
return num;
}
static inline bool gl_shader_filter_type(unsigned num, bool *smooth)
{
bool valid = false;
#ifdef HAVE_CG
if (!valid)
valid = gl_cg_filter_type(num, smooth);
#endif
#ifdef HAVE_XML
if (!valid)
valid = gl_glsl_filter_type(num, smooth);
#endif
return valid;
}
///////////////////
//////////////// Message rendering
@ -290,7 +306,7 @@ static inline void gl_init_font(gl_t *gl, const char *font_path, unsigned font_s
static void gl_init_fbo(gl_t *gl, unsigned width, unsigned height)
{
if (!g_settings.video.render_to_texture)
if (!g_settings.video.render_to_texture && gl_shader_num() <= 1)
return;
if (!load_fbo_proc())
@ -317,20 +333,26 @@ static void gl_init_fbo(gl_t *gl, unsigned width, unsigned height)
glGenTextures(gl->fbo_pass, gl->fbo_texture);
void *tmp = calloc(gl->fbo_width * gl->fbo_height, sizeof(uint32_t));
GLuint base_filt = g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST;
for (int i = 0; i < gl->fbo_pass; i++)
{
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GLuint filter_type = base_filt;
bool smooth;
if (gl_shader_filter_type(i + 2, &smooth))
filter_type = smooth ? GL_LINEAR : GL_NEAREST;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_type);
glTexImage2D(GL_TEXTURE_2D,
0, GL_RGBA, gl->fbo_width, gl->fbo_height, 0, GL_RGBA,
GL_UNSIGNED_INT_8_8_8_8, tmp);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST);
free(tmp);
glBindTexture(GL_TEXTURE_2D, 0);
@ -719,10 +741,11 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
set_viewport(gl, gl->win_width, gl->win_height, false);
if (video->smooth)
gl->tex_filter = GL_LINEAR;
bool force_smooth;
if (gl_shader_filter_type(1, &force_smooth))
gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST;
else
gl->tex_filter = GL_NEAREST;
gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST;
gl->texture_type = video->rgb32 ? GL_RGBA : GL_BGRA;
gl->texture_fmt = video->rgb32 ? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_SHORT_1_5_5_5_REV;
@ -745,6 +768,7 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
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_MAG_FILTER, gl->tex_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter);

View File

@ -200,3 +200,11 @@ unsigned gl_cg_num(void)
else
return 0;
}
bool gl_cg_filter_type(unsigned index, bool *smooth)
{
(void)index;
(void)smooth;
// We don't really care since .cg doesn't have those kinds of semantics by itself ...
return false;
}

View File

@ -35,4 +35,6 @@ void gl_cg_use(unsigned index);
unsigned gl_cg_num(void);
bool gl_cg_filter_type(unsigned index, bool *smooth);
#endif

View File

@ -77,8 +77,16 @@ static PFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog = NULL;
#define MAX_PROGRAMS 16
enum filter_type
{
SSNES_GL_NOFORCE,
SSNES_GL_LINEAR,
SSNES_GL_NEAREST
};
static bool glsl_enable = false;
static GLuint gl_program[MAX_PROGRAMS] = {0};
static enum filter_type gl_filter_type[MAX_PROGRAMS] = {SSNES_GL_NOFORCE};
static unsigned gl_num_programs = 0;
static unsigned active_index = 0;
@ -86,6 +94,7 @@ struct shader_program
{
char *vertex;
char *fragment;
enum filter_type filter;
};
static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size)
@ -154,6 +163,27 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
else if (strcmp((const char*)cur->name, "fragment") == 0)
{
prog[num].fragment = strdup((const char*)content);
// Check if shader forces a certain texture filtering.
xmlChar *attr = xmlGetProp(cur, (const xmlChar*)"filter");
if (attr)
{
if (strcmp((const char*)attr, "nearest") == 0)
{
prog[num].filter = SSNES_GL_NEAREST;
SSNES_LOG("XML: Shader forces GL_NEAREST.\n");
}
else if (strcmp((const char*)attr, "linear") == 0)
{
prog[num].filter = SSNES_GL_LINEAR;
SSNES_LOG("XML: Shader forces GL_LINEAR.\n");
}
else
SSNES_WARN("XML: Invalid property for filter.\n");
}
else
prog[num].filter = SSNES_GL_NOFORCE;
num++;
}
}
@ -297,6 +327,9 @@ bool gl_glsl_init(const char *path)
return false;
}
for (unsigned i = 0; i < num_progs; i++)
gl_filter_type[i + 1] = progs[i].filter;
compile_programs(&gl_program[1], progs, num_progs);
// SSNES custom two-pass with two different files.
@ -364,3 +397,26 @@ unsigned gl_glsl_num(void)
{
return gl_num_programs;
}
bool gl_glsl_filter_type(unsigned index, bool *smooth)
{
if (!glsl_enable)
return false;
switch (gl_filter_type[index])
{
case SSNES_GL_NOFORCE:
return false;
case SSNES_GL_NEAREST:
*smooth = false;
return true;
case SSNES_GL_LINEAR:
*smooth = true;
return true;
default:
return false;
}
}

View File

@ -35,4 +35,6 @@ void gl_glsl_use(unsigned index);
unsigned gl_glsl_num(void);
bool gl_glsl_filter_type(unsigned index, bool *smooth);
#endif