improve the sgusersettings implementation by introducing custom enum item and more accuracy

This commit is contained in:
Mamadou Babaei
2024-08-16 18:00:53 +02:00
parent aa148ceff0
commit 474f70c049
6 changed files with 138 additions and 140 deletions
@@ -35,6 +35,8 @@
#include "SenseGlove/GameFramework/SGGameUserSettings.h" #include "SenseGlove/GameFramework/SGGameUserSettings.h"
#include "Scalability.h"
#include "SGSettings/SGSettings.h" #include "SGSettings/SGSettings.h"
struct USGGameUserSettings::FImpl struct USGGameUserSettings::FImpl
@@ -43,6 +45,10 @@ struct USGGameUserSettings::FImpl
* Static methods * Static methods
************************/ ************************/
static float GetRenderScaleLevelFromQualityLevel(
int32 InQualityLevel,
Scalability::EQualityLevelBehavior Behavior = Scalability::EQualityLevelBehavior::EAbsolute);
/************************ /************************
* Owner object * Owner object
************************/ ************************/
@@ -67,9 +73,42 @@ struct USGGameUserSettings::FImpl
* Methods * Methods
************************/ ************************/
bool DoesCurrentSettingsMatch(ESGEngineScalabilitySettings Scalability, float ResolutionScaleNormalized) const; bool DoesCurrentSettingsMatch(ESGEngineScalabilitySettings Scalability) const;
}; };
float USGGameUserSettings::FImpl::GetRenderScaleLevelFromQualityLevel(
const int32 InQualityLevel, const Scalability::EQualityLevelBehavior Behavior)
{
if (!ensureAlwaysMsgf(GConfig, TEXT("Invalid GConfig!")))
{
return 0.0f;
}
TArray<FString> ResolutionValueStrings;
GConfig->GetSingleLineArray(TEXT("ScalabilitySettings"), TEXT("PerfIndexValues_ResolutionQuality"),
ResolutionValueStrings, GScalabilityIni);
if (ResolutionValueStrings.Num() == 0)
{
UE_LOG(LogConsoleResponse, Display,
TEXT("Failed to find resolution value strings in scalability ini. Falling back to the default."));
return 100.0f;
}
// No negative levels!
int32 QualityLevel = FMath::Max(0, InQualityLevel);
if (Behavior == Scalability::EQualityLevelBehavior::ERelativeToMax)
{
QualityLevel = FMath::Max(ResolutionValueStrings.Num() - 1 - QualityLevel, 0);
}
else
{
QualityLevel = FMath::Clamp(QualityLevel, 0, ResolutionValueStrings.Num() - 1);
}
return FCString::Atof(*ResolutionValueStrings[QualityLevel]);
}
USGGameUserSettings::USGGameUserSettings(const FObjectInitializer& ObjectInitializer) USGGameUserSettings::USGGameUserSettings(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer), : Super(ObjectInitializer),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter)) Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
@@ -85,57 +124,50 @@ USGGameUserSettings* USGGameUserSettings::GetInstance()
ESGEngineScalabilitySettings USGGameUserSettings::GetEngineScalabilitySettings() const ESGEngineScalabilitySettings USGGameUserSettings::GetEngineScalabilitySettings() const
{ {
const FSGGameUserSettingSettings& Settings{USGSettings::GetInstance()->GetGameUserSettings()}; const bool bDoesCurrentSettingsMatchLow = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Low);
const bool bDoesCurrentSettingsMatchLow = Pimpl->DoesCurrentSettingsMatch(
ESGEngineScalabilitySettings::Low, Settings.ResolutionScaleNormalizedLow);
if (bDoesCurrentSettingsMatchLow) if (bDoesCurrentSettingsMatchLow)
{ {
return ESGEngineScalabilitySettings::Low; return ESGEngineScalabilitySettings::Low;
} }
const bool bDoesCurrentSettingsMatchMedium = Pimpl->DoesCurrentSettingsMatch( const bool bDoesCurrentSettingsMatchMedium = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Medium);
ESGEngineScalabilitySettings::Medium, Settings.ResolutionScaleNormalizedMedium);
if (bDoesCurrentSettingsMatchMedium) if (bDoesCurrentSettingsMatchMedium)
{ {
return ESGEngineScalabilitySettings::Medium; return ESGEngineScalabilitySettings::Medium;
} }
const bool bDoesCurrentSettingsMatchHigh = Pimpl->DoesCurrentSettingsMatch( const bool bDoesCurrentSettingsMatchHigh = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::High);
ESGEngineScalabilitySettings::High, Settings.ResolutionScaleNormalizedHigh);
if (bDoesCurrentSettingsMatchHigh) if (bDoesCurrentSettingsMatchHigh)
{ {
return ESGEngineScalabilitySettings::High; return ESGEngineScalabilitySettings::High;
} }
const bool bDoesCurrentSettingsMatchEpic = Pimpl->DoesCurrentSettingsMatch( const bool bDoesCurrentSettingsMatchEpic = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Epic);
ESGEngineScalabilitySettings::Epic, Settings.ResolutionScaleNormalizedEpic);
if (bDoesCurrentSettingsMatchEpic) if (bDoesCurrentSettingsMatchEpic)
{ {
return ESGEngineScalabilitySettings::Epic; return ESGEngineScalabilitySettings::Epic;
} }
const bool bDoesCurrentSettingsMatchCinematic = Pimpl->DoesCurrentSettingsMatch( const bool bDoesCurrentSettingsMatchCinematic = Pimpl->DoesCurrentSettingsMatch(
ESGEngineScalabilitySettings::Cinematic, Settings.ResolutionScaleNormalizedCinematic); ESGEngineScalabilitySettings::Cinematic);
if (bDoesCurrentSettingsMatchCinematic) if (bDoesCurrentSettingsMatchCinematic)
{ {
return ESGEngineScalabilitySettings::Cinematic; return ESGEngineScalabilitySettings::Cinematic;
} }
static constexpr int32 ScalabilityMinValue = 0; return ESGEngineScalabilitySettings::Custom;
static constexpr int32 ScalabilityMaxValue = static_cast<int32>(ESGEngineScalabilitySettings::Cinematic);
const int32 OverallScalabilityLevel = GetOverallScalabilityLevel();
if (OverallScalabilityLevel >= ScalabilityMinValue && OverallScalabilityLevel <= ScalabilityMaxValue)
{
return static_cast<ESGEngineScalabilitySettings>(OverallScalabilityLevel);
}
return ESGEngineScalabilitySettings::Epic;
} }
void USGGameUserSettings::SetEngineScalabilitySettings(ESGEngineScalabilitySettings Scalability) void USGGameUserSettings::SetEngineScalabilitySettings(ESGEngineScalabilitySettings Scalability)
{ {
if (!ensureAlwaysMsgf(Scalability != ESGEngineScalabilitySettings::Custom,
TEXT("Cannot set the engine scalability directly to custom!"
" It should be either: Low, Medium, High, Epic, Cinematic,"
" or Auto (determined by hardware benchmarking)!")))
{
return;
}
const FSGGameUserSettingSettings& Settings{USGSettings::GetInstance()->GetGameUserSettings()}; const FSGGameUserSettingSettings& Settings{USGSettings::GetInstance()->GetGameUserSettings()};
if (IsDirty()) if (IsDirty())
@@ -146,44 +178,23 @@ void USGGameUserSettings::SetEngineScalabilitySettings(ESGEngineScalabilitySetti
if (Scalability != ESGEngineScalabilitySettings::Auto) if (Scalability != ESGEngineScalabilitySettings::Auto)
{ {
float ResolutionScaleNormalized = 0.0f;
switch (Scalability)
{
case ESGEngineScalabilitySettings::Low:
ResolutionScaleNormalized = Settings.ResolutionScaleNormalizedLow;
break;
case ESGEngineScalabilitySettings::Medium:
ResolutionScaleNormalized = Settings.ResolutionScaleNormalizedMedium;
break;
case ESGEngineScalabilitySettings::High:
ResolutionScaleNormalized = Settings.ResolutionScaleNormalizedHigh;
break;
case ESGEngineScalabilitySettings::Epic:
ResolutionScaleNormalized = Settings.ResolutionScaleNormalizedEpic;
break;
case ESGEngineScalabilitySettings::Cinematic:
ResolutionScaleNormalized = Settings.ResolutionScaleNormalizedCinematic;
break;
default:
break;
}
SetResolutionScaleNormalized(ResolutionScaleNormalized);
const int32 ScalabilityValue = static_cast<int32>(Scalability); const int32 ScalabilityValue = static_cast<int32>(Scalability);
SetViewDistanceQuality(ScalabilityValue); const float ResolutionScaleNormalized = FImpl::GetRenderScaleLevelFromQualityLevel(
SetAntiAliasingQuality(ScalabilityValue); ScalabilityValue, Scalability::EQualityLevelBehavior::EAbsolute);
SetShadowQuality(ScalabilityValue); SetResolutionScaleNormalized(ResolutionScaleNormalized);
SetGlobalIlluminationQuality(ScalabilityValue);
SetReflectionQuality(ScalabilityValue);
SetPostProcessingQuality(ScalabilityValue);
SetTextureQuality(ScalabilityValue);
SetVisualEffectQuality(ScalabilityValue);
SetFoliageQuality(ScalabilityValue);
SetShadingQuality(ScalabilityValue);
SetOverallScalabilityLevel(ScalabilityValue); ScalabilityQuality.SetViewDistanceQuality(ScalabilityValue);
ScalabilityQuality.SetAntiAliasingQuality(ScalabilityValue);
ScalabilityQuality.SetShadowQuality(ScalabilityValue);
ScalabilityQuality.SetGlobalIlluminationQuality(ScalabilityValue);
ScalabilityQuality.SetReflectionQuality(ScalabilityValue);
ScalabilityQuality.SetPostProcessQuality(ScalabilityValue);
ScalabilityQuality.SetTextureQuality(ScalabilityValue);
ScalabilityQuality.SetEffectsQuality(ScalabilityValue);
ScalabilityQuality.SetFoliageQuality(ScalabilityValue);
ScalabilityQuality.SetShadingQuality(ScalabilityValue);
ScalabilityQuality.SetLandscapeQuality(ScalabilityValue);
} }
else else
{ {
@@ -205,42 +216,71 @@ USGGameUserSettings::FImpl::FImpl(USGGameUserSettings* InOwner)
USGGameUserSettings::FImpl::~FImpl() = default; USGGameUserSettings::FImpl::~FImpl() = default;
bool USGGameUserSettings::FImpl::DoesCurrentSettingsMatch( bool USGGameUserSettings::FImpl::DoesCurrentSettingsMatch(const ESGEngineScalabilitySettings Scalability) const
const ESGEngineScalabilitySettings Scalability, const float ResolutionScaleNormalized) const
{ {
const ESGEngineScalabilitySettings CurrentViewDistanceQuality = static const float ResolutionScaleNormalizedLow = FImpl::GetRenderScaleLevelFromQualityLevel(
static_cast<ESGEngineScalabilitySettings>(Owner->GetViewDistanceQuality()); static_cast<int32>(ESGEngineScalabilitySettings::Low));
const ESGEngineScalabilitySettings CurrentAntiAliasingQuality = static const float ResolutionScaleNormalizedMedium = FImpl::GetRenderScaleLevelFromQualityLevel(
static_cast<ESGEngineScalabilitySettings>(Owner->GetAntiAliasingQuality()); static_cast<int32>(ESGEngineScalabilitySettings::Medium));
const ESGEngineScalabilitySettings CurrentShadowQuality = static const float ResolutionScaleNormalizedHigh = FImpl::GetRenderScaleLevelFromQualityLevel(
static_cast<ESGEngineScalabilitySettings>(Owner->GetShadowQuality()); static_cast<int32>(ESGEngineScalabilitySettings::High));
const ESGEngineScalabilitySettings CurrentGlobalIlluminationQuality = static const float ResolutionScaleNormalizedEpic = FImpl::GetRenderScaleLevelFromQualityLevel(
static_cast<ESGEngineScalabilitySettings>(Owner->GetGlobalIlluminationQuality()); static_cast<int32>(ESGEngineScalabilitySettings::Epic));
const ESGEngineScalabilitySettings CurrentReflectionQuality = static const float ResolutionScaleNormalizedCinematic = FImpl::GetRenderScaleLevelFromQualityLevel(
static_cast<ESGEngineScalabilitySettings>(Owner->GetReflectionQuality()); static_cast<int32>(ESGEngineScalabilitySettings::Cinematic));
const ESGEngineScalabilitySettings CurrentPostProcessingQuality =
static_cast<ESGEngineScalabilitySettings>(Owner->GetPostProcessingQuality()); float ResolutionScaleNormalized = 0.0f;
const ESGEngineScalabilitySettings CurrentTextureQuality = switch (Scalability)
static_cast<ESGEngineScalabilitySettings>(Owner->GetTextureQuality()); {
const ESGEngineScalabilitySettings CurrentVisualEffectQuality = case ESGEngineScalabilitySettings::Low:
static_cast<ESGEngineScalabilitySettings>(Owner->GetVisualEffectQuality()); ResolutionScaleNormalized = ResolutionScaleNormalizedLow;
const ESGEngineScalabilitySettings CurrentFoliageQuality = break;
static_cast<ESGEngineScalabilitySettings>(Owner->GetFoliageQuality()); case ESGEngineScalabilitySettings::Medium:
const ESGEngineScalabilitySettings CurrentShadingQuality = ResolutionScaleNormalized = ResolutionScaleNormalizedMedium;
static_cast<ESGEngineScalabilitySettings>(Owner->GetShadingQuality()); break;
const float CurrentResolutionScaleNormalized = Owner->GetResolutionScaleNormalized(); case ESGEngineScalabilitySettings::High:
ResolutionScaleNormalized = ResolutionScaleNormalizedHigh;
break;
case ESGEngineScalabilitySettings::Epic:
ResolutionScaleNormalized = ResolutionScaleNormalizedEpic;
break;
case ESGEngineScalabilitySettings::Cinematic:
ResolutionScaleNormalized = ResolutionScaleNormalizedCinematic;
break;
default:
ensureAlwaysMsgf(false, TEXT("Login Error: the execution flow should never reach here!"));
break;
}
const int32 ScalabilityValue = static_cast<int32>(Scalability);
const float CurrentResolutionScaleNormalized = FImpl::GetRenderScaleLevelFromQualityLevel(
ScalabilityValue, Scalability::EQualityLevelBehavior::EAbsolute);
const int32 CurrentViewDistanceQuality = Owner->ScalabilityQuality.ViewDistanceQuality;
const int32 CurrentAntiAliasingQuality = Owner->ScalabilityQuality.AntiAliasingQuality;
const int32 CurrentShadowQuality = Owner->ScalabilityQuality.ShadowQuality;
const int32 CurrentGlobalIlluminationQuality = Owner->ScalabilityQuality.GlobalIlluminationQuality;
const int32 CurrentReflectionQuality = Owner->ScalabilityQuality.ReflectionQuality;
const int32 CurrentPostProcessingQuality = Owner->ScalabilityQuality.PostProcessQuality;
const int32 CurrentTextureQuality = Owner->ScalabilityQuality.TextureQuality;
const int32 CurrentEffectQuality = Owner->ScalabilityQuality.EffectsQuality;
const int32 CurrentFoliageQuality = Owner->ScalabilityQuality.FoliageQuality;
const int32 CurrentShadingQuality = Owner->ScalabilityQuality.ShadingQuality;
const int32 CurrentLandscapeQuality = Owner->ScalabilityQuality.LandscapeQuality;
if (FMath::IsNearlyEqual(CurrentResolutionScaleNormalized, ResolutionScaleNormalized) if (FMath::IsNearlyEqual(CurrentResolutionScaleNormalized, ResolutionScaleNormalized)
&& CurrentViewDistanceQuality == Scalability && CurrentViewDistanceQuality == ScalabilityValue
&& CurrentAntiAliasingQuality == Scalability && CurrentAntiAliasingQuality == ScalabilityValue
&& CurrentShadowQuality == Scalability && CurrentShadowQuality == ScalabilityValue
&& CurrentGlobalIlluminationQuality == Scalability && CurrentGlobalIlluminationQuality == ScalabilityValue
&& CurrentReflectionQuality == Scalability && CurrentReflectionQuality == ScalabilityValue
&& CurrentPostProcessingQuality == Scalability && CurrentPostProcessingQuality == ScalabilityValue
&& CurrentTextureQuality == Scalability && CurrentTextureQuality == ScalabilityValue
&& CurrentVisualEffectQuality == Scalability && CurrentEffectQuality == ScalabilityValue
&& CurrentFoliageQuality == Scalability && CurrentFoliageQuality == ScalabilityValue
&& CurrentShadingQuality == Scalability) && CurrentShadingQuality == ScalabilityValue
&& CurrentLandscapeQuality == ScalabilityValue)
{ {
return true; return true;
} }
@@ -37,11 +37,6 @@
#include "SenseGlove/GameFramework/SGGameUserSettings.h" #include "SenseGlove/GameFramework/SGGameUserSettings.h"
USGGameUserSettings* UGameUserSettingsKismetLibrary::GetInstance()
{
return USGGameUserSettings::GetInstance();
}
ESGEngineScalabilitySettings UGameUserSettingsKismetLibrary::GetEngineScalabilitySettings( ESGEngineScalabilitySettings UGameUserSettingsKismetLibrary::GetEngineScalabilitySettings(
const USGGameUserSettings* GameUserSettings) const USGGameUserSettings* GameUserSettings)
{ {
@@ -48,9 +48,6 @@ class SENSEGLOVEKISMET_API UGameUserSettingsKismetLibrary final : public USGBlue
GENERATED_BODY() GENERATED_BODY()
public: public:
UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Game User Settings")
static USGGameUserSettings* GetInstance();
UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Game User Settings") UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Game User Settings")
static ESGEngineScalabilitySettings GetEngineScalabilitySettings(const USGGameUserSettings* GameUserSettings); static ESGEngineScalabilitySettings GetEngineScalabilitySettings(const USGGameUserSettings* GameUserSettings);
@@ -37,11 +37,6 @@
FSGGameUserSettingSettings::FSGGameUserSettingSettings() FSGGameUserSettingSettings::FSGGameUserSettingSettings()
: FSGGameUserSettingSettings( : FSGGameUserSettingSettings(
0.5f,
0.71f,
0.87f,
1.0f,
1.0f,
10.0f, 10.0f,
1.0f, 1.0f,
1.0f) 1.0f)
@@ -49,20 +44,10 @@ FSGGameUserSettingSettings::FSGGameUserSettingSettings()
} }
FSGGameUserSettingSettings::FSGGameUserSettingSettings( FSGGameUserSettingSettings::FSGGameUserSettingSettings(
const float InResolutionScaleNormalizedLow,
const float InResolutionScaleNormalizedMedium,
const float InResolutionScaleNormalizedHigh,
const float InResolutionScaleNormalizedEpic,
const float InResolutionScaleNormalizedCinematic,
const float InHardwareBenchmarkWorkScale, const float InHardwareBenchmarkWorkScale,
const float InHardwareBenchmarkCPUMultiplier, const float InHardwareBenchmarkCPUMultiplier,
const float InHardwareBenchmarkGPUMultiplier) const float InHardwareBenchmarkGPUMultiplier)
: ResolutionScaleNormalizedLow(InResolutionScaleNormalizedLow), : HardwareBenchmarkWorkScale(InHardwareBenchmarkWorkScale),
ResolutionScaleNormalizedMedium(InResolutionScaleNormalizedMedium),
ResolutionScaleNormalizedHigh(InResolutionScaleNormalizedHigh),
ResolutionScaleNormalizedEpic(InResolutionScaleNormalizedEpic),
ResolutionScaleNormalizedCinematic(InResolutionScaleNormalizedCinematic),
HardwareBenchmarkWorkScale(InHardwareBenchmarkWorkScale),
HardwareBenchmarkCPUMultiplier(InHardwareBenchmarkCPUMultiplier), HardwareBenchmarkCPUMultiplier(InHardwareBenchmarkCPUMultiplier),
HardwareBenchmarkGPUMultiplier(InHardwareBenchmarkGPUMultiplier) HardwareBenchmarkGPUMultiplier(InHardwareBenchmarkGPUMultiplier)
{ {
@@ -45,21 +45,6 @@ struct SENSEGLOVESETTINGS_API FSGGameUserSettingSettings
GENERATED_USTRUCT_BODY() GENERATED_USTRUCT_BODY()
public: public:
UPROPERTY(Config, VisibleDefaultsOnly, Category = "Game User Settings")
float ResolutionScaleNormalizedLow;
UPROPERTY(Config, VisibleDefaultsOnly, Category = "Game User Settings")
float ResolutionScaleNormalizedMedium;
UPROPERTY(Config, VisibleDefaultsOnly, Category = "Game User Settings")
float ResolutionScaleNormalizedHigh;
UPROPERTY(Config, VisibleDefaultsOnly, Category = "Game User Settings")
float ResolutionScaleNormalizedEpic;
UPROPERTY(Config, VisibleDefaultsOnly, Category = "Game User Settings")
float ResolutionScaleNormalizedCinematic;
UPROPERTY(Config, EditDefaultsOnly, Category = "Game User Settings") UPROPERTY(Config, EditDefaultsOnly, Category = "Game User Settings")
float HardwareBenchmarkWorkScale; float HardwareBenchmarkWorkScale;
@@ -73,11 +58,6 @@ public:
FSGGameUserSettingSettings(); FSGGameUserSettingSettings();
FSGGameUserSettingSettings( FSGGameUserSettingSettings(
float InResolutionScaleNormalizedLow,
float InResolutionScaleNormalizedMedium,
float InResolutionScaleNormalizedHigh,
float InResolutionScaleNormalizedEpic,
float InResolutionScaleNormalizedCinematic,
float InHardwareBenchmarkWorkScale, float InHardwareBenchmarkWorkScale,
float InHardwareBenchmarkCPUMultiplier, float InHardwareBenchmarkCPUMultiplier,
float InHardwareBenchmarkGPUMultiplier); float InHardwareBenchmarkGPUMultiplier);
@@ -44,15 +44,16 @@
UENUM(BlueprintType) UENUM(BlueprintType)
enum class ESGEngineScalabilitySettings : uint8 enum class ESGEngineScalabilitySettings : uint8
{ {
Low UMETA(DisplayName = "Low"), Low = 0 UMETA(DisplayName = "Low"),
Medium UMETA(DisplayName = "Medium"), Medium = 1 UMETA(DisplayName = "Medium"),
High UMETA(DisplayName = "High"), High = 2 UMETA(DisplayName = "High"),
Epic UMETA(DisplayName = "Epic"), Epic = 3 UMETA(DisplayName = "Epic"),
Cinematic UMETA(DisplayName = "Cinematic"), Cinematic = 4 UMETA(DisplayName = "Cinematic"),
/** /**
* This will be used for benchmarking purpose. Then it should set the engine scalability settings to one of the * This will be used for benchmarking purpose. Then it should set the engine scalability settings to one of the
* other levels. * other levels.
*/ */
Auto UMETA(DisplayName = "Auto"), Auto = 254 UMETA(DisplayName = "Auto"),
Custom = 255 UMETA(DisplayName = "Custom"),
}; };