diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 5d73a6fa77..76ec3b981f 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -248,6 +248,7 @@ wxString scaled_efb_copy_tooltip = wxTRANSLATE("Uses the high-resolution render wxString pixel_lighting_tooltip = wxTRANSLATE("Calculates lighting of 3D graphics on a per-pixel basis rather than per vertex.\nThis is the more accurate behavior but reduces performance."); wxString pixel_depth_tooltip = wxT(""); wxString force_filtering_tooltip = wxTRANSLATE("Forces bilinear texture filtering even if the game explicitly disabled it.\nImproves texture quality (especially when using a high internal resolution) but causes glitches in some games."); +wxString force_no_filtering_tooltip = wxTRANSLATE("Forces no texture filtering even if the game explicitly enabled it.\nGood for some 2D games."); wxString _3d_vision_tooltip = wxT(""); wxString internal_res_tooltip = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality but is also quite heavy on performance and might cause glitches in certain games.\nFractional: Uses your display resolution directly instead of the native resolution. The quality scales with your display/window size, as does the performance impact.\nIntegral: This is like Fractional, but rounds up to an integer multiple of the native resolution. Should give a more accurate look but is usually slower.\nThe other options are fixed resolutions for choosing a visual quality independent of your display size."); wxString efb_access_tooltip = wxTRANSLATE("Allows the CPU to read or write to the EFB (render buffer).\nThis is needed for certain gameplay functionality (e.g. star pointer in Super Mario Galaxy) as well as for certain visual effects (e.g. Monster Hunter Tri),\nbut enabling this option can also have a huge negative impact on performance if the game uses this functionality heavily."); @@ -441,6 +442,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_enh->Add(pixel_lighting = new SettingCheckBox(page_general, _("Pixel Lighting"), wxGetTranslation(pixel_lighting_tooltip), SET_PARAMS(bEnablePixelLighting), false, cb_style)); szr_enh->Add(pixel_depth = new SettingCheckBox(page_general, _("Pixel Depth"), wxGetTranslation(pixel_depth_tooltip), SET_PARAMS(bEnablePerPixelDepth), false, cb_style)); szr_enh->Add(force_filtering = new SettingCheckBox(page_general, _("Force Bi/Trilinear Filtering"), wxGetTranslation(force_filtering_tooltip), SET_PARAMS(bForceFiltering), false, cb_style)); + szr_enh->Add(force_no_filtering = new SettingCheckBox(page_general, _("Force No Filtering"), wxGetTranslation(force_no_filtering_tooltip), SET_PARAMS(bForceNoFiltering), false, cb_style)); _3d_vision = new SettingCheckBox(page_general, _("3D Vision (Requires Fullscreen)"), wxGetTranslation(_3d_vision_tooltip), SET_PARAMS(b3DVision), false, cb_style); szr_enh->Add(_3d_vision); @@ -712,6 +714,7 @@ void VideoConfigDiag::ChangeStyle() CHANGE_DATAREF(pixel_lighting, bEnablePixelLighting); CHANGE_DATAREF(pixel_depth, bEnablePerPixelDepth); CHANGE_DATAREF(force_filtering, bForceFiltering); + CHANGE_DATAREF(force_no_filtering, bForceNoFiltering); CHANGE_DATAREF(_3d_vision, b3DVision); if (cur_profile == 0) choice_efbscale->Delete(0); @@ -938,6 +941,7 @@ void VideoConfigDiag::SetUIValuesFromConfig() SET_CHOICE(pixel_lighting, bEnablePixelLighting); SET_CHOICE(pixel_depth, bEnablePerPixelDepth); SET_CHOICE(force_filtering, bForceFiltering); + SET_CHOICE(force_no_filtering, bForceNoFiltering); SET_CHOICE(_3d_vision, b3DVision); SET_CHOICE(choice_efbscale, iEFBScale); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index eb1eefbe02..1bd2348be5 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -261,6 +261,7 @@ protected: SettingCheckBox* pixel_lighting; SettingCheckBox* pixel_depth; SettingCheckBox* force_filtering; + SettingCheckBox* force_no_filtering; SettingCheckBox* _3d_vision; SettingChoice* choice_efbscale; diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 03716358c1..aea2fc5d24 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -102,6 +102,7 @@ void VideoConfig::Load(const char *main_ini_file, bool filecheck_passed, const c #endif SET_STATE(iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, false), bForceFiltering); + SET_STATE(iniFile.Get("Enhancements", "ForceNoFiltering", &bForceNoFiltering, false), bForceNoFiltering); SET_STATE(iniFile.Get("Enhancements", "MaxAnisotropy", &iMaxAnisotropy, 0), iMaxAnisotropy); // NOTE - this is x in (1 << x) iniFile.Get("Enhancements", "PostProcessingShader", &sPostProcessingShader, ""); SET_STATE(iniFile.Get("Enhancements", "Enable3dVision", &b3DVision, false), b3DVision); @@ -195,6 +196,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) SET_UISTATE(iniFile.GetIfExists("Video_Settings", "OMPDecoder", &bOMPDecoder), bOMPDecoder); #endif SET_UISTATE(iniFile.GetIfExists("Video_Enhancements", "ForceFiltering", &bForceFiltering), bForceFiltering); + SET_UISTATE(iniFile.GetIfExists("Video_Enhancements", "ForceNoFiltering", &bForceNoFiltering), bForceNoFiltering); SET_UISTATE(iniFile.GetIfExists("Video_Enhancements", "MaxAnisotropy", &iMaxAnisotropy), iMaxAnisotropy); // NOTE - this is x in (1 << x) iniFile.GetIfExists("Video_Enhancements", "PostProcessingShader", &sPostProcessingShader); @@ -294,6 +296,7 @@ void VideoConfig::Save(const char *ini_file) #endif iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering); + iniFile.Set("Enhancements", "ForceNoFiltering", bForceNoFiltering); iniFile.Set("Enhancements", "MaxAnisotropy", iMaxAnisotropy); iniFile.Set("Enhancements", "PostProcessingShader", sPostProcessingShader); iniFile.Set("Enhancements", "Enable3dVision", b3DVision); @@ -377,6 +380,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) #endif CHECK_UISTATE("Video_Enhancements", "ForceFiltering", bForceFiltering); + CHECK_UISTATE("Video_Enhancements", "ForceNoFiltering", bForceNoFiltering); CHECK_UISTATE("Video_Enhancements", "MaxAnisotropy", iMaxAnisotropy); // NOTE - this is x in (1 << x) iniFile.Set("Video_Enhancements", "PostProcessingShader", sPostProcessingShader); CHECK_UISTATE("Video_Enhancements", "Enable3dVision", b3DVision); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 76945e6675..0a7ef81148 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -96,6 +96,7 @@ public: int iMultisampleMode; int iEFBScale; bool bForceFiltering; + bool bForceNoFiltering; int iMaxAnisotropy; std::string sPostProcessingShader; @@ -172,6 +173,7 @@ public: bool iMultisampleMode; bool iEFBScale; bool bForceFiltering; + bool bForceNoFiltering; bool iMaxAnisotropy; bool bShowFPS; bool bShowInputDisplay; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 21e9278f70..1e3df3e6d4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1346,6 +1346,10 @@ void Renderer::SetSamplerState(int stage, int texindex) { gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; } + else if (g_ActiveConfig.bForceNoFiltering) + { + gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + } else if (tm0.min_filter & 4) // linear min filter { if (tm0.mag_filter) // linear mag filter @@ -1390,4 +1394,4 @@ void Renderer::SetInterlacingMode() // TODO } -} // namespace DX11 \ No newline at end of file +} // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 765f337bed..124bac774d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1381,6 +1381,10 @@ void Renderer::SetSamplerState(int stage, int texindex) { min = mag = mip = D3DTEXF_LINEAR; } + else if (g_ActiveConfig.bForceNoFiltering) + { + min = mag = mip = D3DTEXF_POINT; + } else { min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 4a9431a563..605c986cea 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -348,13 +348,15 @@ void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, co //mode1 = newmode1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - (newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST); + ((newmode.mag_filter && !g_Config.bForceNoFiltering) || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST); if (bHaveMipMaps) { // TODO: not used anywhere if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4) mode.min_filter += 4; // take equivalent forced linear + else if (g_ActiveConfig.bForceNoFiltering && newmode.min_filter >= 4) + mode.min_filter -= 4; int filt = newmode.min_filter; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]); @@ -364,7 +366,7 @@ void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, co } else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - (g_ActiveConfig.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST); + (g_ActiveConfig.bForceFiltering || (newmode.min_filter >= 4 && !g_ActiveConfig.bForceNoFiltering)) ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);