diff --git a/gfx/gl.c b/gfx/gl.c index c303b7ec17..b613231753 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -81,7 +81,7 @@ static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D = NULL; static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus = NULL; static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers = NULL; -#define LOAD_SYM(sym) p##sym = ((void*)SDL_GL_GetProcAddress(#sym)) +#define LOAD_SYM(sym) if (!p##sym) p##sym = ((void*)SDL_GL_GetProcAddress(#sym)) static bool load_fbo_proc(void) { LOAD_SYM(glGenFramebuffers); @@ -1049,12 +1049,36 @@ static bool gl_focus(void *data) return (SDL_GetAppState() & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) == (SDL_APPINPUTFOCUS | SDL_APPACTIVE); } +#ifdef HAVE_XML static bool gl_xml_shader(void *data, const char *path) { - (void)data; - (void)path; + gl_t *gl = data; + gl_shader_deinit(); + +#ifdef HAVE_FBO + if (gl->fbo_inited) + { + glDeleteTextures(gl->fbo_pass, gl->fbo_texture); + pglDeleteFramebuffers(gl->fbo_pass, gl->fbo); + gl->fbo_inited = false; + } +#endif + + if (!gl_glsl_init(path)) + return false; + + // Set up render to texture. + gl_init_fbo(gl, gl->tex_w, gl->tex_h); + + // Apparently need to set viewport for passes when we aren't using FBOs. + gl_shader_use(0); + set_viewport(gl, gl->win_width, gl->win_height, false); + gl_shader_use(1); + set_viewport(gl, gl->win_width, gl->win_height, false); + return true; } +#endif const video_driver_t video_gl = { .init = gl_init, @@ -1063,7 +1087,9 @@ const video_driver_t video_gl = { .set_nonblock_state = gl_set_nonblock_state, .focus = gl_focus, .free = gl_free, +#ifdef HAVE_XML .xml_shader = gl_xml_shader, +#endif .ident = "gl" }; diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 118dd5d2d5..ca3cdb1c91 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -56,6 +56,8 @@ #define pglGetShaderInfoLog glGetShaderInfoLog #define pglGetProgramiv glGetProgramiv #define pglGetProgramInfoLog glGetProgramInfoLog +#define pglDeleteProgram glDeleteProgram +#define pglGetAttachedShaders glGetAttachedShaders #else static PFNGLCREATEPROGRAMPROC pglCreateProgram = NULL; static PFNGLUSEPROGRAMPROC pglUseProgram = NULL; @@ -74,6 +76,8 @@ static PFNGLGETSHADERIVPROC pglGetShaderiv = NULL; static PFNGLGETSHADERINFOLOGPROC pglGetShaderInfoLog = NULL; static PFNGLGETPROGRAMIVPROC pglGetProgramiv = NULL; static PFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog = NULL; +static PFNGLDELETEPROGRAMPROC pglDeleteProgram = NULL; +static PFNGLGETATTACHEDSHADERSPROC pglGetAttachedShaders = NULL; #endif #define MAX_PROGRAMS 16 @@ -440,6 +444,8 @@ bool gl_glsl_init(const char *path) pglGetShaderInfoLog = SDL_GL_GetProcAddress("glGetShaderInfoLog"); pglGetProgramiv = SDL_GL_GetProcAddress("glGetProgramiv"); pglGetProgramInfoLog = SDL_GL_GetProcAddress("glGetProgramInfoLog"); + pglDeleteProgram = SDL_GL_GetProcAddress("glDeleteProgram"); + pglGetAttachedShaders = SDL_GL_GetProcAddress("glGetAttachedShaders"); #endif SSNES_LOG("Checking GLSL shader support ...\n"); @@ -450,7 +456,8 @@ bool gl_glsl_init(const char *path) && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform2fv && pglUniform4fv - && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog; + && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog + && pglDeleteProgram && pglGetAttachedShaders; #endif if (!shader_support) @@ -507,7 +514,33 @@ bool gl_glsl_init(const char *path) } void gl_glsl_deinit(void) -{} +{ + if (glsl_enable) + { + pglUseProgram(0); + for (int i = 1; i < MAX_PROGRAMS; i++) + { + if (gl_program[i] == 0) + break; + + GLsizei count; + GLuint shaders[2]; + + pglGetAttachedShaders(gl_program[i], 2, &count, shaders); + for (GLsizei j = 0; j < count; j++) + { + pglDetachShader(gl_program[i], shaders[j]); + pglDeleteShader(shaders[j]); + } + + pglDeleteProgram(gl_program[i]); + } + } + + memset(gl_program, 0, sizeof(gl_program)); + glsl_enable = false; + active_index = 0; +} void gl_glsl_set_params(unsigned width, unsigned height, unsigned tex_width, unsigned tex_height,