From 708ff015cdc29c37ef77aa28a1adc769d0b3cbae Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Wed, 29 Mar 2023 00:49:11 +0200 Subject: [PATCH] include catmull-rom shader and make it the default in case no shader files were found --- inc/openglshader.h | 150 +++++++++++++++++++++++++++++++++++++++++++++ src/render_ogl.c | 34 +++++----- 2 files changed, 170 insertions(+), 14 deletions(-) diff --git a/inc/openglshader.h b/inc/openglshader.h index 58bea87..f23bfdd 100644 --- a/inc/openglshader.h +++ b/inc/openglshader.h @@ -127,4 +127,154 @@ const char PASSTHROUGH_FRAG_SHADER_CORE[] = " FragColor = texel;\n" "}\n"; +/* +// Bicubic Catmull-Rom 9 taps (Fast) - ported by Hyllian - 2020 +// The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae +// Ported from code: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 +// Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16. +// See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details +// ATENTION: This code only work using LINEAR filter sampling set on Retroarch! +*/ + +const char CATMULL_ROM_FRAG_SHADER[] = + "#version 130\n" + "out mediump vec4 FragColor;\n" + "uniform int FrameDirection;\n" + "uniform int FrameCount;\n" + "uniform vec2 OutputSize;\n" + "uniform vec2 TextureSize;\n" + "uniform vec2 InputSize;\n" + "uniform sampler2D Texture;\n" + "in vec4 TEX0;\n" + "\n" + "#define Source Texture\n" + "#define vTexCoord TEX0.xy\n" + "\n" + "#define SourceSize vec4(TextureSize, 1.0 / TextureSize)\n" + "#define outsize vec4(OutputSize, 1.0 / OutputSize)\n" + "\n" + "#define mul(c,d) (d*c)\n" + "\n" + "void main()\n" + "{\n" + " vec2 samplePos = vTexCoord * SourceSize.xy;\n" + " vec2 texPos1 = floor(samplePos - 0.5) + 0.5;\n" + "\n" + " vec2 f = samplePos - texPos1;\n" + "\n" + " vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f));\n" + " vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f);\n" + " vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f));\n" + " vec2 w3 = f * f * (-0.5 + 0.5 * f);\n" + " //vec2 w3 = 1.0 - w0 - w1 - w2;\n" + "\n" + " vec2 w12 = w1 + w2;\n" + " vec2 offset12 = w2 / (w1 + w2);\n" + "\n" + " vec2 texPos0 = texPos1 - 1.;\n" + " vec2 texPos3 = texPos1 + 2.;\n" + " vec2 texPos12 = texPos1 + offset12;\n" + "\n" + " texPos0 *= SourceSize.zw;\n" + " texPos3 *= SourceSize.zw;\n" + " texPos12 *= SourceSize.zw;\n" + "\n" + " vec4 c00 = texture(Source, vec2(texPos0.x, texPos0.y));\n" + " vec4 c10 = texture(Source, vec2(texPos12.x, texPos0.y));\n" + " vec4 c20 = texture(Source, vec2(texPos3.x, texPos0.y));\n" + "\n" + " vec4 c01 = texture(Source, vec2(texPos0.x, texPos12.y));\n" + " vec4 c11 = texture(Source, vec2(texPos12.x, texPos12.y));\n" + " vec4 c21 = texture(Source, vec2(texPos3.x, texPos12.y));\n" + "\n" + " vec4 c02 = texture(Source, vec2(texPos0.x, texPos3.y));\n" + " vec4 c12 = texture(Source, vec2(texPos12.x, texPos3.y));\n" + " vec4 c22 = texture(Source, vec2(texPos3.x, texPos3.y));\n" + "\n" + " vec4 c1, c2, c3, wx, wy = vec4(0.,0.,0.,0.);\n" + "\n" + " vec4 dummy = vec4(0.,0.,0.,1.);\n" + "\n" + " wx = vec4(w0.x, w12.x, w3.x, 1.0);\n" + " wy = vec4(w0.y, w12.y, w3.y, 1.0);\n" + "\n" + " c1 = vec4(mul(wx, mat4(c00, c10, c20, dummy)));\n" + " c2 = vec4(mul(wx, mat4(c01, c11, c21, dummy)));\n" + " c3 = vec4(mul(wx, mat4(c02, c12, c22, dummy)));\n" + "\n" + " FragColor = mul(wy, mat4(c1, c2, c3, dummy));\n" + "}\n"; + + +const char CATMULL_ROM_FRAG_SHADER_CORE[] = + "#version 150\n" + "out mediump vec4 FragColor;\n" + "uniform int FrameDirection;\n" + "uniform int FrameCount;\n" + "uniform vec2 OutputSize;\n" + "uniform vec2 TextureSize;\n" + "uniform vec2 InputSize;\n" + "uniform sampler2D Texture;\n" + "in vec4 TEX0;\n" + "\n" + "#define Source Texture\n" + "#define vTexCoord TEX0.xy\n" + "\n" + "#define SourceSize vec4(TextureSize, 1.0 / TextureSize)\n" + "#define outsize vec4(OutputSize, 1.0 / OutputSize)\n" + "\n" + "#define mul(c,d) (d*c)\n" + "\n" + "void main()\n" + "{\n" + " vec2 samplePos = vTexCoord * SourceSize.xy;\n" + " vec2 texPos1 = floor(samplePos - 0.5) + 0.5;\n" + "\n" + " vec2 f = samplePos - texPos1;\n" + "\n" + " vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f));\n" + " vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f);\n" + " vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f));\n" + " vec2 w3 = f * f * (-0.5 + 0.5 * f);\n" + " //vec2 w3 = 1.0 - w0 - w1 - w2;\n" + "\n" + " vec2 w12 = w1 + w2;\n" + " vec2 offset12 = w2 / (w1 + w2);\n" + "\n" + " vec2 texPos0 = texPos1 - 1.;\n" + " vec2 texPos3 = texPos1 + 2.;\n" + " vec2 texPos12 = texPos1 + offset12;\n" + "\n" + " texPos0 *= SourceSize.zw;\n" + " texPos3 *= SourceSize.zw;\n" + " texPos12 *= SourceSize.zw;\n" + "\n" + " vec4 c00 = texture(Source, vec2(texPos0.x, texPos0.y));\n" + " vec4 c10 = texture(Source, vec2(texPos12.x, texPos0.y));\n" + " vec4 c20 = texture(Source, vec2(texPos3.x, texPos0.y));\n" + "\n" + " vec4 c01 = texture(Source, vec2(texPos0.x, texPos12.y));\n" + " vec4 c11 = texture(Source, vec2(texPos12.x, texPos12.y));\n" + " vec4 c21 = texture(Source, vec2(texPos3.x, texPos12.y));\n" + "\n" + " vec4 c02 = texture(Source, vec2(texPos0.x, texPos3.y));\n" + " vec4 c12 = texture(Source, vec2(texPos12.x, texPos3.y));\n" + " vec4 c22 = texture(Source, vec2(texPos3.x, texPos3.y));\n" + "\n" + " vec4 c1, c2, c3, wx, wy = vec4(0.,0.,0.,0.);\n" + "\n" + " vec4 dummy = vec4(0.,0.,0.,1.);\n" + "\n" + " wx = vec4(w0.x, w12.x, w3.x, 1.0);\n" + " wy = vec4(w0.y, w12.y, w3.y, 1.0);\n" + "\n" + " c1 = vec4(mul(wx, mat4(c00, c10, c20, dummy)));\n" + " c2 = vec4(mul(wx, mat4(c01, c11, c21, dummy)));\n" + " c3 = vec4(mul(wx, mat4(c02, c12, c22, dummy)));\n" + "\n" + " FragColor = mul(wy, mat4(c1, c2, c3, dummy));\n" + "}\n"; + + + #endif diff --git a/src/render_ogl.c b/src/render_ogl.c index 652b2c9..19c943c 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -165,25 +165,31 @@ static void ogl_build_programs() _snprintf(shader_path, sizeof(shader_path) - 1, "%s%s", g_config.game_path, g_ddraw->shader); } - if (GetFileAttributes(shader_path) != INVALID_FILE_ATTRIBUTES) + /* detect common upscaling shaders and disable them if no upscaling is required */ + + BOOL is_upscaler = + strstr(g_ddraw->shader, "catmull-rom-bilinear.glsl") != NULL || + strstr(g_ddraw->shader, "lanczos2-sharp.glsl") != NULL || + strstr(g_ddraw->shader, "xbr-lv2-noblend.glsl") != NULL || + strstr(g_ddraw->shader, "xbrz-freescale.glsl") != NULL; + + if (!is_upscaler || + g_ddraw->render.viewport.width != g_ddraw->width || + g_ddraw->render.viewport.height != g_ddraw->height) { - /* detect common upscaling shaders and disable them if no upscaling is required */ + g_ogl.scale_program = oglu_build_program_from_file(shader_path, wglCreateContextAttribsARB != NULL); - BOOL is_upscaler = - strstr(g_ddraw->shader, "catmull-rom-bilinear.glsl") != NULL || - strstr(g_ddraw->shader, "lanczos2-sharp.glsl") != NULL || - strstr(g_ddraw->shader, "xbr-lv2-noblend.glsl") != NULL || - strstr(g_ddraw->shader, "xbrz-freescale.glsl") != NULL; - - if (is_upscaler && - g_ddraw->render.viewport.width == g_ddraw->width && - g_ddraw->render.viewport.height == g_ddraw->height) + if (!g_ogl.scale_program) { - shader_path[0] = 0; + g_ogl.scale_program = oglu_build_program(PASSTHROUGH_VERT_SHADER, CATMULL_ROM_FRAG_SHADER); + + if (!g_ogl.scale_program) + { + g_ogl.scale_program = + oglu_build_program(PASSTHROUGH_VERT_SHADER_CORE, CATMULL_ROM_FRAG_SHADER_CORE); + } } } - - g_ogl.scale_program = oglu_build_program_from_file(shader_path, wglCreateContextAttribsARB != NULL); } else {