From a4b5b110ec3e30a47ea3c2ea724e3d708841546d Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 16:33:55 +0200 Subject: [PATCH 1/3] Don't perform a filter mode change if the new mode is the same as the previous one. --- port/src/video.c | 1 + 1 file changed, 1 insertion(+) diff --git a/port/src/video.c b/port/src/video.c index 3befff9fb..63be72f54 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -218,6 +218,7 @@ void videoSetMaximizeWindow(s32 fs) void videoSetTextureFilter(u32 filter) { if (filter > FILTER_THREE_POINT) filter = FILTER_THREE_POINT; + if (texFilter == filter) return; texFilter = filter; gfx_set_texture_filter((enum FilteringMode)filter); } From a60880ef807547a8885caee1ff3d28df9929eb1a Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 17:09:00 +0200 Subject: [PATCH 2/3] Three point and shader improvements - Fixed blurry menu background being unfiltered when three point is enabled. - Some shader code refactor to reduce the amount of __APPLE__ defines: use the SAMPLE_TEX macro to sample textures. - Detach shaders before deleting them. --- port/fast3d/gfx_opengl.cpp | 91 ++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 0f9ee081b..2080bfddb 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -55,7 +55,7 @@ static std::vector framebuffers; static size_t current_framebuffer; static float current_noise_scale; static FilteringMode current_filter_mode = FILTER_LINEAR; -static bool current_linear_filters[2] = {false, false}; +static bool current_textures_linear_filter[2] = {false, false}; static GLenum gl_mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE; @@ -97,10 +97,10 @@ static void gfx_opengl_set_uniforms(struct ShaderProgram* prg) { glUniform1f(prg->noise_scale_location, current_noise_scale); } if (prg->three_point_filter_locations[0] >= 0) { - glUniform1i(prg->three_point_filter_locations[0], current_linear_filters[0]); + glUniform1i(prg->three_point_filter_locations[0], current_textures_linear_filter[0]); } if (prg->three_point_filter_locations[1] >= 0) { - glUniform1i(prg->three_point_filter_locations[1], current_linear_filters[1]); + glUniform1i(prg->three_point_filter_locations[1], current_textures_linear_filter[1]); } } @@ -394,27 +394,14 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);"); append_line(fs_buf, &fs_len, "}"); - if (cc_features.opt_blur) { - // blur filter, used for menu backgrounds - // used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it - // used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers - append_line(fs_buf, &fs_len, R"( - lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 tsize, in int three_point_filter) { - lowp vec4 cw = vec4(0.0); - for (int i = 0; i < 16; ++i) { - vec2 xy = vec2(float(i & 3), float(i >> 2)); - lowp float w = 0.009947 - length(xy) * 0.001; - cw += vec4(texture2D(t, uv + (vec2(-1.5) + xy) / tsize).rgb * w, w); - } - return vec4(cw.rgb / cw.a, 1.0); - })" - ); - } else if (current_filter_mode == FILTER_THREE_POINT) { #if __APPLE__ - append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize)"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); #else - append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); #endif + + if (current_filter_mode == FILTER_THREE_POINT) { + append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) SAMPLE_TEX(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); @@ -423,21 +410,43 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}"); - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); -#if __APPLE__ - append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture(tex, uv);"); -#else - append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture2D(tex, uv);"); -#endif + } + + if (cc_features.opt_blur) { + // blur filter, used for menu backgrounds + // used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it + // used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers + + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, "lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); + else + append_line(fs_buf, &fs_len, "lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 texSize) {"); + + append_line(fs_buf, &fs_len, " lowp vec4 cw = vec4(0.0);"); + append_line(fs_buf, &fs_len, " for (int i = 0; i < 16; ++i) {"); + append_line(fs_buf, &fs_len, " vec2 xy = vec2(float(i & 3), float(i >> 2));"); + append_line(fs_buf, &fs_len, " lowp float w = 0.009947 - length(xy) * 0.001;"); + append_line(fs_buf, &fs_len, " vec2 scaled_uv = uv + (vec2(-1.5) + xy) / texSize;"); + + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, " lowp vec4 tex = mix(SAMPLE_TEX(t, scaled_uv), filter3point(t, scaled_uv, texSize), three_point_filter);"); + else + append_line(fs_buf, &fs_len, " lowp vec4 tex = SAMPLE_TEX(t, scaled_uv);"); + + append_line(fs_buf, &fs_len, " cw += vec4(tex.rgb * w, w);"); + append_line(fs_buf, &fs_len, " }"); + append_line(fs_buf, &fs_len, " return vec4(cw.rgb / cw.a, 1.0);"); append_line(fs_buf, &fs_len, "}"); } else { - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); -#if __APPLE__ - append_line(fs_buf, &fs_len, " return texture(tex, uv);"); -#else - append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); -#endif - append_line(fs_buf, &fs_len, "}"); + if (current_filter_mode == FILTER_THREE_POINT) { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); + append_line(fs_buf, &fs_len, " return mix(SAMPLE_TEX(tex, uv), filter3point(tex, uv, texSize), three_point_filter);"); + append_line(fs_buf, &fs_len, "}"); + } else { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, " return SAMPLE_TEX(tex, uv);"); + append_line(fs_buf, &fs_len, "}"); + } } #if __APPLE__ @@ -480,7 +489,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad if (current_filter_mode == FILTER_THREE_POINT) fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); else - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, 0);\n", i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); } } @@ -503,12 +512,12 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, ";"); if (c == 0) { - append_str(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); + append_line(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); } } - append_str(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); - append_str(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); + append_line(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); + append_line(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); // TODO discard if alpha is 0? if (cc_features.opt_fog) { if (cc_features.opt_alpha) { @@ -593,6 +602,8 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); + glDetachShader(shader_program, vertex_shader); + glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); @@ -703,7 +714,7 @@ static void gfx_opengl_select_texture(int tile, GLuint texture_id, bool linear_f glActiveTexture(GL_TEXTURE0 + tile); glBindTexture(GL_TEXTURE_2D, texture_id); - current_linear_filters[tile] = linear_filter; + current_textures_linear_filter[tile] = linear_filter; } static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height) { @@ -1143,6 +1154,8 @@ void gfx_opengl_select_texture_fb(int fb_id) { // glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, framebuffers[fb_id].clrbuf); + + current_textures_linear_filter[0] = true; } void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top, bool flip_y, bool use_back) { From 9cd978a7a9cd0b916a10e6cf68453f08c1ce78b5 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 19:11:33 +0200 Subject: [PATCH 3/3] Removed more APPLE checks. --- port/fast3d/gfx_opengl.cpp | 184 ++++++++++++++----------------------- 1 file changed, 71 insertions(+), 113 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 2080bfddb..a13bb540f 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -242,138 +242,114 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad size_t num_floats = 4; // Vertex shader + #ifdef __APPLE__ append_line(vs_buf, &vs_len, "#version 410 core"); - append_line(vs_buf, &vs_len, "in vec4 aVtxPos;"); + append_line(vs_buf, &vs_len, "#define INPUT in"); + append_line(vs_buf, &vs_len, "#define OUTPUT out"); #else append_line(vs_buf, &vs_len, "#version 110"); - append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;"); + append_line(vs_buf, &vs_len, "#define INPUT attribute"); + append_line(vs_buf, &vs_len, "#define OUTPUT varying"); #endif + + append_line(vs_buf, &vs_len, "INPUT vec4 aVtxPos;"); + for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in vec2 aTexCoord%d;\n", i); - vs_len += sprintf(vs_buf + vs_len, "out vec2 vTexCoord%d;\n", i); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute vec2 aTexCoord%d;\n", i); - vs_len += sprintf(vs_buf + vs_len, "varying vec2 vTexCoord%d;\n", i); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT vec2 aTexCoord%d;\n", i); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT vec2 vTexCoord%d;\n", i); num_floats += 2; for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); - vs_len += sprintf(vs_buf + vs_len, "out float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); - vs_len += sprintf(vs_buf + vs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); num_floats += 1; } } } } if (cc_features.opt_fog) { -#ifdef __APPLE__ - append_line(vs_buf, &vs_len, "in vec4 aFog;"); - append_line(vs_buf, &vs_len, "out vec4 vFog;"); -#else - append_line(vs_buf, &vs_len, "attribute vec4 aFog;"); - append_line(vs_buf, &vs_len, "varying vec4 vFog;"); -#endif + append_line(vs_buf, &vs_len, "INPUT vec4 aFog;"); + append_line(vs_buf, &vs_len, "OUTPUT vec4 vFog;"); num_floats += 4; } if (cc_features.opt_grayscale) { -#ifdef __APPLE__ - append_line(vs_buf, &vs_len, "in vec4 aGrayscaleColor;"); - append_line(vs_buf, &vs_len, "out vec4 vGrayscaleColor;"); -#else - append_line(vs_buf, &vs_len, "attribute vec4 aGrayscaleColor;"); - append_line(vs_buf, &vs_len, "varying vec4 vGrayscaleColor;"); -#endif + append_line(vs_buf, &vs_len, "INPUT vec4 aGrayscaleColor;"); + append_line(vs_buf, &vs_len, "OUTPUT vec4 vGrayscaleColor;"); num_floats += 4; } for (int i = 0; i < cc_features.num_inputs; i++) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); - vs_len += sprintf(vs_buf + vs_len, "out vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); - vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); num_floats += cc_features.opt_alpha ? 4 : 3; } + append_line(vs_buf, &vs_len, "void main() {"); for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { - vs_len += sprintf(vs_buf + vs_len, "vTexCoord%d = aTexCoord%d;\n", i, i); + vs_len += sprintf(vs_buf + vs_len, " vTexCoord%d = aTexCoord%d;\n", i, i); for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { - vs_len += sprintf(vs_buf + vs_len, "vTexClamp%s%d = aTexClamp%s%d;\n", j == 0 ? "S" : "T", i, + vs_len += sprintf(vs_buf + vs_len, " vTexClamp%s%d = aTexClamp%s%d;\n", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); } } } } if (cc_features.opt_fog) { - append_line(vs_buf, &vs_len, "vFog = aFog;"); + append_line(vs_buf, &vs_len, " vFog = aFog;"); } if (cc_features.opt_grayscale) { - append_line(vs_buf, &vs_len, "vGrayscaleColor = aGrayscaleColor;"); + append_line(vs_buf, &vs_len, " vGrayscaleColor = aGrayscaleColor;"); } for (int i = 0; i < cc_features.num_inputs; i++) { - vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1); + vs_len += sprintf(vs_buf + vs_len, " vInput%d = aInput%d;\n", i + 1, i + 1); } - append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;"); + append_line(vs_buf, &vs_len, " gl_Position = aVtxPos;"); append_line(vs_buf, &vs_len, "}"); // Fragment shader + #ifdef __APPLE__ append_line(fs_buf, &fs_len, "#version 410 core"); + append_line(fs_buf, &fs_len, "#define INPUT in"); + append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR outColor"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); #else append_line(fs_buf, &fs_len, "#version 130"); + append_line(fs_buf, &fs_len, "#define INPUT varying"); + append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR gl_FragColor"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); #endif + + // Reference approach to color wrapping as per GLideN64 + // Return wrapped value of x in interval [low, high) + append_line(fs_buf, &fs_len, "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low)"); + + append_line(fs_buf, &fs_len, "#define TEX_OFFSET(tex, uv, texSize, off) SAMPLE_TEX(tex, uv - (off)/texSize)"); + // append_line(fs_buf, &fs_len, "precision mediump float;"); for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in vec2 vTexCoord%d;\n", i); -#else - fs_len += sprintf(fs_buf + fs_len, "varying vec2 vTexCoord%d;\n", i); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT vec2 vTexCoord%d;\n", i); for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#else - fs_len += sprintf(fs_buf + fs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); } } } } if (cc_features.opt_fog) { -#ifdef __APPLE__ - append_line(fs_buf, &fs_len, "in vec4 vFog;"); -#else - append_line(fs_buf, &fs_len, "varying vec4 vFog;"); -#endif + append_line(fs_buf, &fs_len, "INPUT vec4 vFog;"); } if (cc_features.opt_grayscale) { -#ifdef __APPLE__ - append_line(fs_buf, &fs_len, "in vec4 vGrayscaleColor;"); -#else - append_line(fs_buf, &fs_len, "varying vec4 vGrayscaleColor;"); -#endif + append_line(fs_buf, &fs_len, "INPUT vec4 vGrayscaleColor;"); } for (int i = 0; i < cc_features.num_inputs; i++) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#else - fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); } if (cc_features.used_textures[0]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); @@ -394,20 +370,13 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);"); append_line(fs_buf, &fs_len, "}"); -#if __APPLE__ - append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); -#else - append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); -#endif - if (current_filter_mode == FILTER_THREE_POINT) { - append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) SAMPLE_TEX(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); - append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(offset);"); - append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));"); - append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); + append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(tex, texCoord, texSize, offset);"); + append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(tex, texCoord, texSize, vec2(offset.x - sign(offset.x), offset.y));"); + append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(tex, texCoord, texSize, vec2(offset.x, offset.y - sign(offset.y)));"); append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}"); } @@ -455,47 +424,43 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, "void main() {"); - // Reference approach to color wrapping as per GLideN64 - // Return wrapped value of x in interval [low, high) - append_line(fs_buf, &fs_len, "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low)"); - for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; - fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); + fs_len += sprintf(fs_buf + fs_len, " vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); if (!s && !t) { - fs_len += sprintf(fs_buf + fs_len, "vec2 vTexCoordAdj%d = vTexCoord%d;\n", i, i); + fs_len += sprintf(fs_buf + fs_len, " vec2 vTexCoordAdj%d = vTexCoord%d;\n", i, i); } else { if (s && t) { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = clamp(vTexCoord%d, 0.5 / texSize%d, " + " vec2 vTexCoordAdj%d = clamp(vTexCoord%d, 0.5 / texSize%d, " "vec2(vTexClampS%d, vTexClampT%d));\n", i, i, i, i, i); } else if (s) { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = vec2(clamp(vTexCoord%d.s, 0.5 / " + " vec2 vTexCoordAdj%d = vec2(clamp(vTexCoord%d.s, 0.5 / " "texSize%d.s, vTexClampS%d), vTexCoord%d.t);\n", i, i, i, i, i); } else { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, " + " vec2 vTexCoordAdj%d = vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, " "0.5 / texSize%d.t, vTexClampT%d));\n", i, i, i, i, i); } } if (current_filter_mode == FILTER_THREE_POINT) - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, " vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); else - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, " vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); } } - append_line(fs_buf, &fs_len, cc_features.opt_alpha ? "vec4 texel;" : "vec3 texel;"); + append_line(fs_buf, &fs_len, cc_features.opt_alpha ? " vec4 texel;" : " vec3 texel;"); for (int c = 0; c < (cc_features.opt_2cyc ? 2 : 1); c++) { - append_str(fs_buf, &fs_len, "texel = "); + append_str(fs_buf, &fs_len, " texel = "); if (!cc_features.color_alpha_same[c] && cc_features.opt_alpha) { append_str(fs_buf, &fs_len, "vec4("); append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][0], @@ -512,55 +477,48 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, ";"); if (c == 0) { - append_line(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); + append_line(fs_buf, &fs_len, " texel = WRAP(texel, -1.01, 1.01);"); } } - append_line(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); - append_line(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); + append_line(fs_buf, &fs_len, " texel = WRAP(texel, -0.51, 1.51);"); + append_line(fs_buf, &fs_len, " texel = clamp(texel, 0.0, 1.0);"); // TODO discard if alpha is 0? if (cc_features.opt_fog) { if (cc_features.opt_alpha) { - append_line(fs_buf, &fs_len, "texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);"); + append_line(fs_buf, &fs_len, " texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);"); } else { - append_line(fs_buf, &fs_len, "texel = mix(texel, vFog.rgb, vFog.a);"); + append_line(fs_buf, &fs_len, " texel = mix(texel, vFog.rgb, vFog.a);"); } } if (cc_features.opt_texture_edge && cc_features.opt_alpha) { - append_line(fs_buf, &fs_len, "if (texel.a > 0.19) texel.a = 1.0; else discard;"); + append_line(fs_buf, &fs_len, " if (texel.a > 0.19) texel.a = 1.0; else discard;"); } if (cc_features.opt_alpha && cc_features.opt_noise) { append_line(fs_buf, &fs_len, - "texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))) + " + " texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))) + " "texel.a, 0.0, 1.0));"); } if (cc_features.opt_grayscale) { - append_line(fs_buf, &fs_len, "float intensity = (texel.r + texel.g + texel.b) / 3.0;"); - append_line(fs_buf, &fs_len, "vec3 new_texel = vGrayscaleColor.rgb * intensity;"); - append_line(fs_buf, &fs_len, "texel.rgb = mix(texel.rgb, new_texel, vGrayscaleColor.a);"); + append_line(fs_buf, &fs_len, " float intensity = (texel.r + texel.g + texel.b) / 3.0;"); + append_line(fs_buf, &fs_len, " vec3 new_texel = vGrayscaleColor.rgb * intensity;"); + append_line(fs_buf, &fs_len, " texel.rgb = mix(texel.rgb, new_texel, vGrayscaleColor.a);"); } if (cc_features.opt_alpha) { if (cc_features.opt_alpha_threshold) { - append_line(fs_buf, &fs_len, "if (texel.a < 8.0 / 256.0) discard;"); + append_line(fs_buf, &fs_len, " if (texel.a < 8.0 / 256.0) discard;"); } if (cc_features.opt_invisible) { - append_line(fs_buf, &fs_len, "texel.a = 0.0;"); + append_line(fs_buf, &fs_len, " texel.a = 0.0;"); } -#if __APPLE__ - append_line(fs_buf, &fs_len, "outColor = texel;"); -#else - append_line(fs_buf, &fs_len, "gl_FragColor = texel;"); -#endif + + append_line(fs_buf, &fs_len, " OUTPUT_COLOR = texel;"); } else { -#if __APPLE__ - append_line(fs_buf, &fs_len, "outColor = vec4(texel, 1.0);"); -#else - append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);"); -#endif + append_line(fs_buf, &fs_len, " OUTPUT_COLOR = vec4(texel, 1.0);"); } append_line(fs_buf, &fs_len, "}");