1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Implement 3 point filtering.

Code ported from mupen64plus-libretro.
This commit is contained in:
Sergey Lipskiy 2015-03-06 22:19:38 +06:00
parent b0e86e2cbc
commit cf11996d0e
4 changed files with 55 additions and 32 deletions

View File

@ -21,6 +21,7 @@ static GLuint g_calc_mipmap_shader_object;
static GLuint g_calc_noise_shader_object;
static GLuint g_calc_depth_shader_object;
static GLuint g_test_alpha_shader_object;
static GLuint g_readtex_shader_object;
GLuint g_monochrome_image_program = 0;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
@ -289,6 +290,11 @@ void InitShaderCombiner()
glCompileShader(g_test_alpha_shader_object);
assert(checkShaderCompileStatus(g_test_alpha_shader_object));
g_readtex_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(g_readtex_shader_object, 1, &fragment_shader_readtex, NULL);
glCompileShader(g_readtex_shader_object);
assert(checkShaderCompileStatus(g_readtex_shader_object));
#ifdef GL_IMAGE_TEXTURES_SUPPORT
if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) {
g_calc_depth_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
@ -315,6 +321,8 @@ void DestroyShaderCombiner() {
g_calc_light_shader_object = 0;
glDeleteShader(g_calc_mipmap_shader_object);
g_calc_mipmap_shader_object = 0;
glDeleteShader(g_readtex_shader_object);
g_readtex_shader_object = 0;
glDeleteShader(g_calc_noise_shader_object);
g_calc_noise_shader_object = 0;
glDeleteShader(g_test_alpha_shader_object);
@ -527,9 +535,9 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
#endif
} else {
if (usesT0())
strFragmentShader.append(fragment_shader_readtex0color);
strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFb8Bit == 1 || uFb8Bit == 3, uFbFixedAlpha == 1 || uFbFixedAlpha == 3); \n");
if (usesT1())
strFragmentShader.append(fragment_shader_readtex1color);
strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFb8Bit == 2 || uFb8Bit == 3, uFbFixedAlpha == 2 || uFbFixedAlpha == 3); \n");
}
if (config.generalEmulation.enableHWLighting)
#ifdef SHADER_PRECISION
@ -612,6 +620,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
glAttachShader(m_program, g_calc_light_shader_object);
if (bUseLod)
glAttachShader(m_program, g_calc_mipmap_shader_object);
glAttachShader(m_program, g_readtex_shader_object);
glAttachShader(m_program, g_test_alpha_shader_object);
if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0)
glAttachShader(m_program, g_calc_depth_shader_object);
@ -657,6 +666,7 @@ void ShaderCombiner::_locateUniforms() {
LocateUniform(uMaxTile)
LocateUniform(uTextureDetail);
LocateUniform(uTexturePersp);
LocateUniform(uTextureFilterMode);
LocateUniform(uSpecialBlendMode);
LocateUniform(uFogMultiplier);
@ -863,6 +873,7 @@ void ShaderCombiner::updateColors(bool _bForce)
void ShaderCombiner::updateTextureInfo(bool _bForce) {
_setIUniform(m_uniforms.uTexturePersp, gDP.otherMode.texturePersp, _bForce);
_setIUniform(m_uniforms.uTextureFilterMode, config.texture.forceBilinear == 0 ? gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP) : 0, _bForce);
_setFV2Uniform(m_uniforms.uTexScale, gSP.texture.scales, gSP.texture.scalet, _bForce);
int nFB0 = 0, nFB1 = 0;
TextureCache & cache = textureCache();

View File

@ -39,7 +39,7 @@ private:
uFogMode, uFogUsage, uEnableLod, uEnableAlphaTest,
uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate,
uDepthMode, uDepthSource, uFb8Bit, uFbFixedAlpha, uRenderState, uSpecialBlendMode,
uMaxTile, uTextureDetail, uTexturePersp,
uMaxTile, uTextureDetail, uTexturePersp, uTextureFilterMode,
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode, uGammaCorrectionEnabled;
fUniform uFogMultiplier, uFogOffset, uK4, uK5, uPrimLod, uScreenWidth, uScreenHeight,

View File

@ -185,6 +185,7 @@ static const char* fragment_shader_header_common_functions =
"lowp float snoise(); \n"
"mediump float calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n"
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in bool fb8bit, in bool fbFixedAlpha); \n"
"bool depth_compare(); \n"
"bool alpha_test(in lowp float alphaValue); \n"
#else
@ -332,18 +333,6 @@ static const char* fragment_shader_toonify =
#endif
#ifdef SHADER_PRECISION
static const char* fragment_shader_readtex0color =
" lowp vec4 readtex0 = texture(uTex0, vTexCoord0); \n"
" if (uFb8Bit == 1 || uFb8Bit == 3) readtex0 = vec4(readtex0.r); \n"
" if (uFbFixedAlpha == 1 || uFbFixedAlpha == 3) readtex0.a = 0.825; \n"
;
static const char* fragment_shader_readtex1color =
" lowp vec4 readtex1 = texture(uTex1, vTexCoord1); \n"
" if (uFb8Bit == 2 || uFb8Bit == 3) readtex1 = vec4(readtex1.r); \n"
" if (uFbFixedAlpha == 2 || uFbFixedAlpha == 3) readtex1.a = 0.825; \n"
;
#if 0
static const char* fragment_shader_blender =
" switch (uSpecialBlendMode) { \n"
@ -366,7 +355,7 @@ static const char* fragment_shader_blender =
" break; \n"
" case 2: \n"
// Bomberman2
" color1 = uBlendColor.rgb * uFogColor.a + color1.rgb * (1.0 - uFogColor.a); \n"
" color1 = uBlendColor.rgb * uFogColor.a + color1 * (1.0 - uFogColor.a); \n"
" break; \n"
" } \n"
;
@ -375,23 +364,17 @@ static const char* fragment_shader_blender =
static const char* fragment_shader_end =
"} \n"
#else
static const char* fragment_shader_readtex0color =
" vec4 readtex0 = texture(uTex0, vTexCoord0); \n"
" if (uFb8Bit == 1 || uFb8Bit == 3) readtex0 = vec4(readtex0.r); \n"
" if (uFbFixedAlpha == 1 || uFbFixedAlpha == 3) readtex0.a = 0.825; \n"
;
static const char* fragment_shader_readtex1color =
" vec4 readtex1 = texture(uTex1, vTexCoord1); \n"
" if (uFb8Bit == 2 || uFb8Bit == 3) readtex1 = vec4(readtex1.r); \n"
" if (uFbFixedAlpha == 2 || uFbFixedAlpha == 3) readtex1.a = 0.825; \n"
;
static const char* fragment_shader_blender =
" if (uSpecialBlendMode == 1) { \n"
" switch (uSpecialBlendMode) { \n"
" case 1: \n"
// Mace
" color1 = color1 * alpha1 + uBlendColor.rgb * (1.0 - alpha1); \n"
" } \n"
" break; \n"
" case 2: \n"
// Bomberman2
" color1 = uBlendColor.rgb * uFogColor.a + color1.rgb * (1.0 - uFogColor.a); \n"
" break; \n"
" } \n"
;
static const char* fragment_shader_end =
@ -541,6 +524,36 @@ static const char* fragment_shader_mipmap =
#endif
;
static const char* fragment_shader_readtex =
"#version 330 core \n"
"uniform lowp int uTextureFilterMode; \n"
"lowp vec4 filterNearest(in sampler2D tex, in mediump vec2 texCoord)\n"
"{ \n"
" return texture(tex, texCoord); \n"
"} \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
"lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord) \n"
"{ \n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n"
" offset -= step(1.0, offset.x + offset.y); \n"
" lowp vec4 c0 = TEX_OFFSET(offset); \n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n"
" return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
"} \n"
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in bool fb8bit, in bool fbFixedAlpha) \n"
"{ \n"
" lowp vec4 texColor = uTextureFilterMode == 0 ? filterNearest(tex, texCoord) : filter3point(tex, texCoord); \n"
" if (fb8bit) texColor = vec4(texColor.r); \n"
" if (fbFixedAlpha) texColor.a = 0.825; \n"
" return texColor; \n"
"} \n"
;
static const char* fragment_shader_noise =
"#version 330 core \n"
"uniform sampler2D uTexNoise; \n"

View File

@ -1048,8 +1048,7 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
glBindTexture( GL_TEXTURE_2D, _pTexture->glName );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, _pTexture->max_level);
// Set filter mode. Almost always bilinear, but check anyways
if ((gDP.otherMode.textureFilter == G_TF_BILERP) || (gDP.otherMode.textureFilter == G_TF_AVERAGE) || ((gSP.objRendermode&G_OBJRM_BILERP) != 0) || (config.texture.forceBilinear)) {
if (config.texture.forceBilinear != 0) {
if (_pTexture->max_level > 0)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
else