From 20777734b6d1e0c591c0a7c122ad84544cf519a8 Mon Sep 17 00:00:00 2001 From: Mauller <26652186+Mauller@users.noreply.github.com> Date: Sat, 21 Mar 2026 18:38:31 +0000 Subject: [PATCH 1/2] feat(options): Implement game option to set MSAA level (#2482) --- .../Include/Common/OptionPreferences.h | 10 +++++ .../Source/Common/OptionPreferences.cpp | 15 +++++++ Core/Libraries/Include/Lib/BaseType.h | 16 +++++++ .../GameEngine/Include/Common/GlobalData.h | 2 +- .../GameEngine/Source/Common/GlobalData.cpp | 6 ++- .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 42 ++++++++++++------- .../W3DDevice/GameClient/W3DDisplay.cpp | 5 ++- .../Libraries/Source/WWVegas/WW3D2/ww3d.h | 8 ++-- 8 files changed, 82 insertions(+), 22 deletions(-) diff --git a/Core/GameEngine/Include/Common/OptionPreferences.h b/Core/GameEngine/Include/Common/OptionPreferences.h index 2bacaa07105..8c7cff8c446 100644 --- a/Core/GameEngine/Include/Common/OptionPreferences.h +++ b/Core/GameEngine/Include/Common/OptionPreferences.h @@ -44,8 +44,18 @@ class OptionPreferences : public UserPreferences OptionPreferences(); virtual ~OptionPreferences() override; + enum AliasingMode CPP_11(: Int) + { + MSAA_OFF = 0, + MSAA_2X, + MSAA_4X, + MSAA_8X, + NUM_ALIASING_MODES + }; + Bool loadFromIniFile(); + UnsignedInt getAntiAliasing() const; UnsignedInt getLANIPAddress(); UnsignedInt getOnlineIPAddress(); void setLANIPAddress(AsciiString IP); diff --git a/Core/GameEngine/Source/Common/OptionPreferences.cpp b/Core/GameEngine/Source/Common/OptionPreferences.cpp index 36df300ef8a..6b67e4d1cab 100644 --- a/Core/GameEngine/Source/Common/OptionPreferences.cpp +++ b/Core/GameEngine/Source/Common/OptionPreferences.cpp @@ -31,6 +31,8 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "ww3d.h" + #include "Common/AudioSettings.h" #include "Common/GameAudio.h" #include "Common/GameLOD.h" @@ -66,6 +68,19 @@ Bool OptionPreferences::loadFromIniFile() return load("Options.ini"); } +UnsignedInt OptionPreferences::getAntiAliasing() const +{ + OptionPreferences::const_iterator it = find("AntiAliasing"); + if (it == end()) + return WW3D::MULTISAMPLE_MODE_NONE; + + UnsignedInt level = atoi(it->second.str()); + level = clamp((UnsignedInt)WW3D::MULTISAMPLE_MODE_NONE, level, (UnsignedInt)WW3D::MULTISAMPLE_MODE_8X); + level = highestBit(level); + + return level; +} + Int OptionPreferences::getCampaignDifficulty() { OptionPreferences::const_iterator it = find("CampaignDifficulty"); diff --git a/Core/Libraries/Include/Lib/BaseType.h b/Core/Libraries/Include/Lib/BaseType.h index f3d24185882..82aa5e0157a 100644 --- a/Core/Libraries/Include/Lib/BaseType.h +++ b/Core/Libraries/Include/Lib/BaseType.h @@ -58,6 +58,22 @@ inline int sign(NUM x) else return 0; } +template +inline NUM highestBit(NUM x) +{ + static_assert(sizeof(NUM) <= 8, "NUM must be 8 bytes or less"); + UnsignedInt64 y = static_cast(x); + + y |= (y >> 1); + y |= (y >> 2); + y |= (y >> 4); + y |= (y >> 8); + y |= (y >> 16); + y |= (y >> 32); + + return static_cast(y & ~(y >> 1)); +} + // TheSuperHackers @refactor JohnsterID 24/01/2026 Add lowercase min/max templates for GameEngine layer. // GameEngine code typically uses BaseType.h, but may include WWVegas headers (which define min/max in always.h). // Header guard prevents duplicate definitions. VC6's lacks std::min/std::max. diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 8fcde36e5d5..a4eefc7b7d0 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -396,7 +396,7 @@ class GlobalData : public SubsystemInterface units will always keep their formation. If it's <1.0, then the user must click a smaller area within the rectangle to order the gather. */ - Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu + UnsignedInt m_antiAliasLevel; ///< value of selected antialias level in the game options Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 8527e8a70cd..3303fd6dba9 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -32,6 +32,8 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "ww3d.h" + #include "Common/GlobalData.h" #define DEFINE_TERRAIN_LOD_NAMES @@ -930,7 +932,7 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); - m_antiAliasBoxValue = 0; + m_antiAliasLevel = WW3D::MultiSampleModeEnum::MULTISAMPLE_MODE_NONE; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1229,6 +1231,8 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_playerInfoListFontSize = optionPref.getPlayerInfoListFontSize(); TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute(); + TheWritableGlobalData->m_antiAliasLevel = optionPref.getAntiAliasing(); + Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. if (val < 50) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 2c26f935a9f..979aa722a5a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -552,11 +552,17 @@ static void saveOptions() //------------------------------------------------------------------------------------------------- // antialiasing GadgetComboBoxGetSelectedPos(comboBoxAntiAliasing, &index); - if( index >= 0 && TheGlobalData->m_antiAliasBoxValue != index ) + if( index >= 0 && TheGlobalData ) { - TheWritableGlobalData->m_antiAliasBoxValue = index; + Int mode = WW3D::MULTISAMPLE_MODE_NONE; + + // TheSuperHackers @info We are converting comboBox entry position to MultiSampleModeEnum values + clamp((int)OptionPreferences::MSAA_OFF, index, (int)OptionPreferences::MSAA_8X); + mode = (index > 0) ? 1 << index : 0; + + TheWritableGlobalData->m_antiAliasLevel = mode; AsciiString prefString; - prefString.format("%d", index); + prefString.format("%d", mode); (*pref)["AntiAliasing"] = prefString; } @@ -1024,14 +1030,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) Color color = GameMakeColor(255,255,255,255); - enum AliasingMode CPP_11(: Int) - { - OFF = 0, - LOW, - HIGH, - NUM_ALIASING_MODES - }; - initLabelVersion(); // Choose an IP address, then initialize the IP combo box @@ -1135,18 +1133,32 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) GadgetComboBoxReset(comboBoxAntiAliasing); AsciiString temp; Int i=0; - for (; i < NUM_ALIASING_MODES; ++i) + for (; i < OptionPreferences::NUM_ALIASING_MODES; ++i) { temp.format("GUI:AntiAliasing%d", i); str = TheGameText->fetch( temp ); index = GadgetComboBoxAddEntry(comboBoxAntiAliasing, str, color); } Int val = atoi(selectedAliasingMode.str()); - if( val < 0 || val > NUM_ALIASING_MODES ) + Int pos = 0; + + // TheSuperHackers @info We are converting from human readable value to comboBox entry position + val = highestBit(val); + + if (val == WW3D::MULTISAMPLE_MODE_NONE) + pos = OptionPreferences::MSAA_OFF; + else if (val == WW3D::MULTISAMPLE_MODE_2X) + pos = OptionPreferences::MSAA_2X; + else if (val == WW3D::MULTISAMPLE_MODE_4X) + pos = OptionPreferences::MSAA_4X; + else if (val == WW3D::MULTISAMPLE_MODE_8X) + pos = OptionPreferences::MSAA_8X; + + if( val < 0 || val > WW3D::MULTISAMPLE_MODE_8X) { - TheWritableGlobalData->m_antiAliasBoxValue = val = 0; + TheWritableGlobalData->m_antiAliasLevel = pos = 0; } - GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, val); + GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, pos); // get resolution from saved preferences file AsciiString selectedResolution = (*pref) ["Resolution"]; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index e34e4428649..0f9eb077988 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -762,7 +762,7 @@ void W3DDisplay::init() } // TheSuperHackers @feature Mauller 13/03/2026 Add native MSAA support, must be set before creating render device - WW3D::Set_MSAA_Mode(WW3D::MULTISAMPLE_MODE_NONE); + WW3D::Set_MSAA_Mode((WW3D::MultiSampleModeEnum)TheWritableGlobalData->m_antiAliasLevel); renderDeviceError = WW3D::Set_Render_Device( 0, @@ -772,6 +772,9 @@ void W3DDisplay::init() getWindowed(), true ); + // TheSuperHackers @info Update the MSAA mode that was set as some GPU's may not support certain levels + TheWritableGlobalData->m_antiAliasLevel = (UnsignedInt)WW3D::Get_MSAA_Mode(); + ++attempt; } while (attempt < 3 && renderDeviceError != WW3D_ERROR_OK); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h index b70c737e066..250c6658b2c 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h @@ -73,10 +73,10 @@ class WW3D public: enum MultiSampleModeEnum { - MULTISAMPLE_MODE_NONE, - MULTISAMPLE_MODE_2X, - MULTISAMPLE_MODE_4X, - MULTISAMPLE_MODE_8X + MULTISAMPLE_MODE_NONE = 0, + MULTISAMPLE_MODE_2X = 2, + MULTISAMPLE_MODE_4X = 4, + MULTISAMPLE_MODE_8X = 8 }; enum PrelitModeEnum { From a4f900f9677393bb7a945d737a1a7ffce61a069e Mon Sep 17 00:00:00 2001 From: Mauller <26652186+Mauller@users.noreply.github.com> Date: Sat, 21 Mar 2026 21:09:00 +0000 Subject: [PATCH 2/2] feat(options): Implement game options for texture filter mode and anisotropy level (#2482) --- .../Include/Common/OptionPreferences.h | 2 ++ .../Source/Common/OptionPreferences.cpp | 35 +++++++++++++++++++ .../Source/WWVegas/WW3D2/texturefilter.cpp | 16 ++++++--- .../Source/WWVegas/WW3D2/texturefilter.h | 4 ++- .../GameEngine/Include/Common/GlobalData.h | 3 ++ .../GameEngine/Source/Common/GlobalData.cpp | 5 +++ .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 26 ++++++++++++++ .../W3DDevice/GameClient/W3DDisplay.cpp | 5 +++ .../Source/WWVegas/WW3D2/dx8wrapper.cpp | 5 ++- .../Libraries/Source/WWVegas/WW3D2/ww3d.cpp | 23 +++++++++++- .../Libraries/Source/WWVegas/WW3D2/ww3d.h | 4 +++ 11 files changed, 121 insertions(+), 7 deletions(-) diff --git a/Core/GameEngine/Include/Common/OptionPreferences.h b/Core/GameEngine/Include/Common/OptionPreferences.h index 8c7cff8c446..7a19e7f4d9d 100644 --- a/Core/GameEngine/Include/Common/OptionPreferences.h +++ b/Core/GameEngine/Include/Common/OptionPreferences.h @@ -56,6 +56,8 @@ class OptionPreferences : public UserPreferences Bool loadFromIniFile(); UnsignedInt getAntiAliasing() const; + UnsignedInt getTextureFilterMode() const; + UnsignedInt getTextureAnisotropyLevel() const; UnsignedInt getLANIPAddress(); UnsignedInt getOnlineIPAddress(); void setLANIPAddress(AsciiString IP); diff --git a/Core/GameEngine/Source/Common/OptionPreferences.cpp b/Core/GameEngine/Source/Common/OptionPreferences.cpp index 6b67e4d1cab..854ef508adb 100644 --- a/Core/GameEngine/Source/Common/OptionPreferences.cpp +++ b/Core/GameEngine/Source/Common/OptionPreferences.cpp @@ -32,6 +32,7 @@ #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine #include "ww3d.h" +#include "texturefilter.h" #include "Common/AudioSettings.h" #include "Common/GameAudio.h" @@ -81,6 +82,40 @@ UnsignedInt OptionPreferences::getAntiAliasing() const return level; } +UnsignedInt OptionPreferences::getTextureFilterMode() const +{ + OptionPreferences::const_iterator it = find("TextureFilter"); + if (it == end()) + return TextureFilterClass::TEXTURE_FILTER_BILINEAR; + + UnsignedInt filter = TextureFilterClass::TEXTURE_FILTER_NONE; + if (stricmp(it->second.str(), TextureFilterClass::TextureFilterModeString[TextureFilterClass::TEXTURE_FILTER_NONE]) == 0) + filter = TextureFilterClass::TEXTURE_FILTER_NONE; + else if(stricmp(it->second.str(), TextureFilterClass::TextureFilterModeString[TextureFilterClass::TEXTURE_FILTER_POINT]) == 0) + filter = TextureFilterClass::TEXTURE_FILTER_POINT; + else if (stricmp(it->second.str(), TextureFilterClass::TextureFilterModeString[TextureFilterClass::TEXTURE_FILTER_BILINEAR]) == 0) + filter = TextureFilterClass::TEXTURE_FILTER_BILINEAR; + else if (stricmp(it->second.str(), TextureFilterClass::TextureFilterModeString[TextureFilterClass::TEXTURE_FILTER_TRILINEAR]) == 0) + filter = TextureFilterClass::TEXTURE_FILTER_TRILINEAR; + else if (stricmp(it->second.str(), TextureFilterClass::TextureFilterModeString[TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC]) == 0) + filter = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC; + + return filter; +} + +UnsignedInt OptionPreferences::getTextureAnisotropyLevel() const +{ + OptionPreferences::const_iterator it = find("AnisotropyLevel"); + if (it == end()) + return TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X; + + UnsignedInt level = atoi(it->second.str()); + level = clamp((UnsignedInt)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X, level, (UnsignedInt)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X); + level = highestBit(level); + + return level; +} + Int OptionPreferences::getCampaignDifficulty() { OptionPreferences::const_iterator it = find("CampaignDifficulty"); diff --git a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp index 2592ac8a9bd..38f94d82c51 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp @@ -40,6 +40,14 @@ #include "texturefilter.h" #include "dx8wrapper.h" +const char* const TextureFilterClass::TextureFilterModeString[5] = { + "None", + "Point", + "Bilinear", + "Trilinear", + "Anisotropic" +}; + unsigned _MinTextureFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT]; unsigned _MagTextureFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT]; unsigned _MipMapFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT]; @@ -100,7 +108,7 @@ void TextureFilterClass::Apply(unsigned int stage) //! Init filters (legacy) /*! */ -void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type) +void TextureFilterClass::_Init_Filters(TextureFilterMode texture_filter, AnisotropicFilterMode anisotropy_level) { const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps(); @@ -122,7 +130,7 @@ void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type) // TheSuperHackers @feature Mauller 08/03/2026 Add full support for all texture filtering modes; // None, Point, Bilinear, Trilinear, Anisotropic. BOOL FilterSupported = false; - switch (filter_type) { + switch (texture_filter) { default: // TheSuperHackers @info if we have an invalid filter_type, set the filtering to none @@ -201,8 +209,8 @@ void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type) _MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC; _MagTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC; - // Set the Anisotropic filtering level for all stages - 2X by default - _Set_Max_Anisotropy(TEXTURE_FILTER_ANISOTROPIC_2X); + // Set the Anisotropic filtering level for all stages + _Set_Max_Anisotropy(anisotropy_level); } else { _MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_POINT; diff --git a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h index 7d38431753e..704b526c5e2 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h @@ -91,6 +91,8 @@ class TextureFilterClass TEXTURE_FILTER_ANISOTROPIC }; + static const char* const TextureFilterModeString[5]; + enum AnisotropicFilterMode { TEXTURE_FILTER_ANISOTROPIC_2X = 2, @@ -124,7 +126,7 @@ class TextureFilterClass void Set_V_Addr_Mode(TxtAddrMode mode) { VAddressMode=mode; } // These need to be called after device has been created - static void _Init_Filters(TextureFilterMode texture_filter); + static void _Init_Filters(TextureFilterMode texture_filter, AnisotropicFilterMode anisotropy_level); static void _Set_Max_Anisotropy(AnisotropicFilterMode mode); static void _Set_Default_Min_Filter(FilterType filter); diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index a4eefc7b7d0..d818b4ca082 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -397,6 +397,9 @@ class GlobalData : public SubsystemInterface smaller area within the rectangle to order the gather. */ UnsignedInt m_antiAliasLevel; ///< value of selected antialias level in the game options + UnsignedInt m_textureFilteringMode; ///< value related to TextureFilterClass::TextureFilterModeEnum + UnsignedInt m_textureAnisotropyLevel; ///< value related to TextureFilterClass::AnisotropicFilterMode + Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 3303fd6dba9..bb14f1c9346 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -33,6 +33,7 @@ #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine #include "ww3d.h" +#include "texturefilter.h" #include "Common/GlobalData.h" @@ -933,6 +934,8 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); m_antiAliasLevel = WW3D::MultiSampleModeEnum::MULTISAMPLE_MODE_NONE; + m_textureFilteringMode = TextureFilterClass::TextureFilterMode::TEXTURE_FILTER_BILINEAR; + m_textureAnisotropyLevel = TextureFilterClass::AnisotropicFilterMode::TEXTURE_FILTER_ANISOTROPIC_2X; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1232,6 +1235,8 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute(); TheWritableGlobalData->m_antiAliasLevel = optionPref.getAntiAliasing(); + TheWritableGlobalData->m_textureFilteringMode = optionPref.getTextureFilterMode(); + TheWritableGlobalData->m_textureAnisotropyLevel = optionPref.getTextureAnisotropyLevel(); Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 979aa722a5a..0a9737e1127 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -75,6 +75,7 @@ #include "GameClient/MessageBox.h" #include "ww3d.h" +#include "texturefilter.h" // This is for non-RC builds only!!! #define VERBOSE_VERSION L"Release" @@ -566,6 +567,31 @@ static void saveOptions() (*pref)["AntiAliasing"] = prefString; } + //------------------------------------------------------------------------------------------------- + // texture filter mode + val = pref->getTextureFilterMode(); + if (val >= 0 && TheGlobalData) + { + clamp((int)TextureFilterClass::TEXTURE_FILTER_NONE, val, (int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC); + + TheWritableGlobalData->m_textureFilteringMode = val; + AsciiString prefString; + prefString = TextureFilterClass::TextureFilterModeString[val]; + (*pref)["TextureFilter"] = prefString; + } + + //------------------------------------------------------------------------------------------------- + // anisotropy level + val = pref->getTextureAnisotropyLevel(); + if (val >= 0 && TheGlobalData) + { + clamp((int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X, val, (int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X); + + TheWritableGlobalData->m_textureAnisotropyLevel = val; + AsciiString prefString; + prefString.format("%d", val); + (*pref)["AnisotropyLevel"] = prefString; + } //------------------------------------------------------------------------------------------------- // mouse mode diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 0f9eb077988..41f74e03144 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -773,7 +773,12 @@ void W3DDisplay::init() true ); // TheSuperHackers @info Update the MSAA mode that was set as some GPU's may not support certain levels + // Texture filtering must be also be updated after render device initialisation TheWritableGlobalData->m_antiAliasLevel = (UnsignedInt)WW3D::Get_MSAA_Mode(); + WW3D::Set_Texture_Filter(TheWritableGlobalData->m_textureFilteringMode); + TheWritableGlobalData->m_textureFilteringMode = WW3D::Get_Texture_Filter(); + WW3D::Set_Anisotropy_level(TheWritableGlobalData->m_textureAnisotropyLevel); + TheWritableGlobalData->m_textureAnisotropyLevel = WW3D::Get_Anisotropy_level(); ++attempt; } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp index 82a48499509..d1c3edf873a 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp @@ -411,7 +411,10 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Inits() ** Initialize any other subsystems inside of WW3D */ MissingTexture::_Init(); - TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter()); + TextureFilterClass::_Init_Filters( + (TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter(), + (TextureFilterClass::AnisotropicFilterMode)WW3D::Get_Anisotropy_level() + ); TheDX8MeshRenderer.Init(); SHD_INIT; BoxRenderObjClass::Init(); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp index 2aa6e707339..0f26a042c48 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp @@ -223,6 +223,7 @@ int WW3D::LastFrameMemoryAllocations; int WW3D::LastFrameMemoryFrees; int WW3D::TextureFilter = TextureFilterClass::TextureFilterMode::TEXTURE_FILTER_BILINEAR; +int WW3D::AnisotropyLevel = TextureFilterClass::AnisotropicFilterMode::TEXTURE_FILTER_ANISOTROPIC_2X; bool WW3D::Lite = false; @@ -768,9 +769,29 @@ void WW3D::Set_Texture_Filter(int texture_filter) if (texture_filter<0) texture_filter=0; if (texture_filter>TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC) texture_filter=TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC; TextureFilter=texture_filter; - TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)TextureFilter); + TextureFilterClass::_Init_Filters( + (TextureFilterClass::TextureFilterMode)TextureFilter, + (TextureFilterClass::AnisotropicFilterMode)AnisotropyLevel + ); } +void WW3D::Set_Anisotropy_level(int level) +{ + if (level <= TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X) + level = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X; + else if(level <= TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_4X) + level = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_4X; + else if (level <= TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_8X) + level = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_8X; + else if (level <= TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X) + level = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X; + + if (level > TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X) + level = TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X; + + AnisotropyLevel = level; + TextureFilterClass::_Set_Max_Anisotropy((TextureFilterClass::AnisotropicFilterMode)AnisotropyLevel); +} /*********************************************************************************************** * WW3D::Begin_Render -- mark the start of rendering for a new frame * diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h index 250c6658b2c..d28221c5897 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h @@ -143,6 +143,9 @@ class WW3D static void Set_Texture_Filter(int filter); static int Get_Texture_Filter() { return TextureFilter; } + static void Set_Anisotropy_level(int level); + static int Get_Anisotropy_level() { return AnisotropyLevel; } + /* ** Rendering functions ** Each frame should be bracketed by a Begin_Render and End_Render call. Between these two calls you will @@ -396,6 +399,7 @@ class WW3D static bool ExposePrelit; static int TextureFilter; + static int AnisotropyLevel; static bool SnapshotActivated; static bool ThumbnailEnabled;