Make linear/tripoint filters switchable without restart

This commit is contained in:
Agent X 2024-04-03 20:25:51 -04:00
parent 95d0977df5
commit 2f69079e8e
3 changed files with 30 additions and 32 deletions

View file

@ -128,8 +128,8 @@ FAST = "Fast"
ACCURATE = "Accurate" ACCURATE = "Accurate"
INTERPOLATION = "Interpolation" INTERPOLATION = "Interpolation"
NEAREST = "Nearest" NEAREST = "Nearest"
LINEAR = "Linear" LINEAR = "Bilinear"
TRIPOINT = "Tripoint" TRIPOINT = "Trilinear"
FILTERING = "Filtering" FILTERING = "Filtering"
D0P5X = "0.5x" D0P5X = "0.5x"
D1X = "1x" D1X = "1x"
@ -201,8 +201,8 @@ BOUNCY_BOUNDS_ON_CAP = "ON (Capped)"
BOUNCY_BOUNDS_ON = "ON" BOUNCY_BOUNDS_ON = "ON"
BOUNCY_BOUNDS_OFF = "OFF" BOUNCY_BOUNDS_OFF = "OFF"
BOUNCY_LEVEL_BOUNDS = "Bouncy Level Bounds" BOUNCY_LEVEL_BOUNDS = "Bouncy Level Bounds"
AMOUNT_OF_PLAYERS = "Amount of players" AMOUNT_OF_PLAYERS = "Amount Of Players"
PAUSE_ANYWHERE = "Pause anywhere" PAUSE_ANYWHERE = "Pause Anywhere"
[HOST] [HOST]
SERVER_TITLE = "SERVER" SERVER_TITLE = "SERVER"

View file

@ -1,6 +1,6 @@
-- name: Arena -- name: Arena
-- description: A arena-shooter inspired game mode with custom weapons and levels.\nSeven gamemodes in one, three custom stages, five weapons. -- description: A arena-shooter inspired game mode with custom weapons and levels.\nSeven gamemodes in one, three custom stages, five weapons.
-- incompatible: gamemode arena light -- incompatible: gamemode arena
-- deluxe: true -- deluxe: true
if SM64COOPDX_VERSION == nil then return end if SM64COOPDX_VERSION == nil then return end

View file

@ -50,7 +50,7 @@ struct ShaderProgram {
bool used_textures[2]; bool used_textures[2];
uint8_t num_floats; uint8_t num_floats;
GLint attrib_locations[7]; GLint attrib_locations[7];
GLint uniform_locations[6]; GLint uniform_locations[7];
uint8_t attrib_sizes[7]; uint8_t attrib_sizes[7];
uint8_t num_attribs; uint8_t num_attribs;
bool used_noise; bool used_noise;
@ -96,6 +96,7 @@ static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
static inline void gfx_opengl_set_shader_uniforms(struct ShaderProgram *prg) { static inline void gfx_opengl_set_shader_uniforms(struct ShaderProgram *prg) {
if (prg->used_noise) { glUniform1f(prg->uniform_locations[4], (float)frame_count); } if (prg->used_noise) { glUniform1f(prg->uniform_locations[4], (float)frame_count); }
if (prg->used_lightmap) { glUniform3f(prg->uniform_locations[5], gVertexColor[0] / 255.0f, gVertexColor[1] / 255.0f, gVertexColor[2] / 255.0f); } if (prg->used_lightmap) { glUniform3f(prg->uniform_locations[5], gVertexColor[0] / 255.0f, gVertexColor[1] / 255.0f, gVertexColor[2] / 255.0f); }
glUniform1i(prg->uniform_locations[6], configFiltering);
} }
static inline void gfx_opengl_set_texture_uniforms(struct ShaderProgram *prg, const int tile) { static inline void gfx_opengl_set_texture_uniforms(struct ShaderProgram *prg, const int tile) {
@ -341,30 +342,23 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
// 3 point texture filtering // 3 point texture filtering
// Original author: ArthurCarvalho // Original author: ArthurCarvalho
// Slightly modified GLSL implementation by twinaphex, mupen64plus-libretro project. // Modified GLSL implementation by twinaphex, mupen64plus-libretro project.
if (ccf.used_textures[0] || ccf.used_textures[1]) { if (ccf.used_textures[0] || ccf.used_textures[1]) {
if (configFiltering == 2) { append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(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, "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, " 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, " 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 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 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 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, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "}"); append_line(fs_buf, &fs_len, "vec4 sampleTex(in sampler2D tex, in vec2 uv, in vec2 texSize, in bool dofilter, in int filter) {");
append_line(fs_buf, &fs_len, "vec4 sampleTex(in sampler2D tex, in vec2 uv, in vec2 texSize, in bool dofilter) {"); append_line(fs_buf, &fs_len, " if (dofilter && filter == 2)");
append_line(fs_buf, &fs_len, "if (dofilter)"); append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);");
append_line(fs_buf, &fs_len, "return filter3point(tex, uv, texSize);"); append_line(fs_buf, &fs_len, " else");
append_line(fs_buf, &fs_len, "else"); append_line(fs_buf, &fs_len, " return texture2D(tex, uv);");
append_line(fs_buf, &fs_len, "return texture2D(tex, uv);"); append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "}");
} else {
append_line(fs_buf, &fs_len, "vec4 sampleTex(in sampler2D tex, in vec2 uv, in vec2 texSize, in bool dofilter) {");
append_line(fs_buf, &fs_len, "return texture2D(tex, uv);");
append_line(fs_buf, &fs_len, "}");
}
} }
if ((opt_alpha && opt_dither) || ccf.do_noise) { if ((opt_alpha && opt_dither) || ccf.do_noise) {
@ -380,6 +374,8 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
append_line(fs_buf, &fs_len, "uniform vec3 uLightmapColor;"); append_line(fs_buf, &fs_len, "uniform vec3 uLightmapColor;");
} }
append_line(fs_buf, &fs_len, "uniform int uFilter;");
append_line(fs_buf, &fs_len, "void main() {"); append_line(fs_buf, &fs_len, "void main() {");
if ((opt_alpha && opt_dither) || ccf.do_noise) { if ((opt_alpha && opt_dither) || ccf.do_noise) {
@ -387,15 +383,15 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
} }
if (ccf.used_textures[0]) { if (ccf.used_textures[0]) {
append_line(fs_buf, &fs_len, "vec4 texVal0 = sampleTex(uTex0, vTexCoord, uTex0Size, uTex0Filter);"); append_line(fs_buf, &fs_len, "vec4 texVal0 = sampleTex(uTex0, vTexCoord, uTex0Size, uTex0Filter, uFilter);");
} }
if (ccf.used_textures[1]) { if (ccf.used_textures[1]) {
if (opt_light_map) { if (opt_light_map) {
append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vLightMap, uTex1Size, uTex1Filter);"); append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vLightMap, uTex1Size, uTex1Filter, uFilter);");
append_line(fs_buf, &fs_len, "texVal0.rgb *= uLightmapColor.rgb;"); append_line(fs_buf, &fs_len, "texVal0.rgb *= uLightmapColor.rgb;");
append_line(fs_buf, &fs_len, "texVal1.rgb = texVal1.rgb * texVal1.rgb + texVal1.rgb;"); append_line(fs_buf, &fs_len, "texVal1.rgb = texVal1.rgb * texVal1.rgb + texVal1.rgb;");
} else { } else {
append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter);"); append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter, uFilter);");
} }
} }
@ -561,6 +557,8 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
} else { } else {
prg->used_lightmap = false; prg->used_lightmap = false;
} }
prg->uniform_locations[6] = glGetUniformLocation(shader_program, "uFilter");
return prg; return prg;
} }