Skip to content

Commit f6208a8

Browse files
committed
Add fps adaptive LOD for 60hz
1 parent 7b2fd72 commit f6208a8

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

GeneralsMD/Code/GameEngine/Include/Common/GameLOD.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ class GameLODManager
188188
Bool didMemPass( void );
189189
void setReallyLowMHz(Int mhz) { m_reallyLowMHz = mhz; }
190190
Bool isReallyLowMHz() const { return m_cpuFreq < m_reallyLowMHz; }
191+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
192+
void updateGraphicsQualityState(float averageFPS);
193+
#endif
191194

192195
StaticGameLODInfo m_staticGameLODInfo[STATIC_GAME_LOD_COUNT];
193196
DynamicGameLODInfo m_dynamicGameLODInfo[DYNAMIC_GAME_LOD_COUNT];
@@ -226,6 +229,15 @@ class GameLODManager
226229
Real m_memBenchIndex;
227230
Real m_compositeBenchIndex;
228231
Int m_reallyLowMHz;
232+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
233+
bool m_userGraphSnapshotTaken;
234+
bool m_userShadowVolumesEnabled;
235+
bool m_userShadowDecalsEnabled;
236+
bool m_userHeatEffectsEnabled;
237+
bool m_isQualityReduced;
238+
int m_sustainedGoodFrames;
239+
DynamicGameLODLevel m_userDynamicLOD;
240+
#endif
229241
};
230242

231243
Bool GameLODManager::isParticleSkipped(void)

GeneralsMD/Code/GameEngine/Source/Common/GameLOD.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ GameLODManager::GameLODManager(void)
230230
m_compositeBenchIndex=0;
231231
m_numBenchProfiles=0;
232232
m_reallyLowMHz = 400;
233+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
234+
m_userGraphSnapshotTaken = false;
235+
m_userShadowVolumesEnabled = true;
236+
m_userShadowDecalsEnabled = true;
237+
m_userHeatEffectsEnabled = true;
238+
m_isQualityReduced = false;
239+
m_sustainedGoodFrames = 0;
240+
m_userDynamicLOD = DYNAMIC_GAME_LOD_VERY_HIGH;
241+
#endif
233242

234243
for (Int i=0; i<STATIC_GAME_LOD_CUSTOM; i++)
235244
m_numLevelPresets[i]=0;
@@ -394,6 +403,10 @@ void GameLODManager::init(void)
394403
}
395404

396405
setStaticLODLevel(userSetDetail);
406+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
407+
m_dynamicGameLODInfo[DYNAMIC_GAME_LOD_LOW].m_minFPS = 56;
408+
m_dynamicGameLODInfo[DYNAMIC_GAME_LOD_LOW].m_minDynamicParticlePriority = ALWAYS_RENDER;
409+
#endif
397410
}
398411

399412
void GameLODManager::refreshCustomStaticLODLevel(void)
@@ -767,3 +780,70 @@ Bool GameLODManager::didMemPass( void )
767780
{
768781
return m_memPassed;
769782
}
783+
784+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
785+
void GameLODManager::updateGraphicsQualityState(float averageFPS)
786+
{
787+
if (!m_userGraphSnapshotTaken)
788+
{
789+
m_userShadowVolumesEnabled = TheGlobalData->m_useShadowVolumes;
790+
m_userShadowDecalsEnabled = TheGlobalData->m_useShadowDecals;
791+
m_userHeatEffectsEnabled = TheGlobalData->m_useHeatEffects;
792+
m_userDynamicLOD = m_currentDynamicLOD;
793+
m_userGraphSnapshotTaken = true;
794+
}
795+
796+
if (m_isQualityReduced && TheGameClient && TheGameClient->getFrame() <= 1)
797+
{
798+
TheWritableGlobalData->m_useShadowVolumes = m_userShadowVolumesEnabled;
799+
TheWritableGlobalData->m_useShadowDecals = m_userShadowDecalsEnabled;
800+
TheWritableGlobalData->m_useHeatEffects = m_userHeatEffectsEnabled;
801+
setDynamicLODLevel(m_userDynamicLOD);
802+
if (TheGameClient)
803+
TheGameClient->allocateShadows();
804+
m_isQualityReduced = false;
805+
m_sustainedGoodFrames = 0;
806+
}
807+
808+
if (!m_isQualityReduced)
809+
{
810+
m_userShadowVolumesEnabled = TheGlobalData->m_useShadowVolumes;
811+
m_userShadowDecalsEnabled = TheGlobalData->m_useShadowDecals;
812+
m_userHeatEffectsEnabled = TheGlobalData->m_useHeatEffects;
813+
m_userDynamicLOD = m_currentDynamicLOD;
814+
}
815+
816+
m_sustainedGoodFrames = (averageFPS >= 58.0f) ? (m_sustainedGoodFrames + 1) : 0; // Track a duration of sustained good performance
817+
818+
bool shouldReduceQuality = (averageFPS < 56.0f && TheGameClient && TheGameClient->getFrame() > LOGICFRAMES_PER_SECOND * 10);
819+
if (shouldReduceQuality && !m_isQualityReduced)
820+
{
821+
setDynamicLODLevel(DYNAMIC_GAME_LOD_LOW);
822+
TheGameClient->releaseShadows();
823+
TheWritableGlobalData->m_useShadowVolumes = false;
824+
TheWritableGlobalData->m_useShadowDecals = false;
825+
TheWritableGlobalData->m_useHeatEffects = false;
826+
m_isQualityReduced = true;
827+
}
828+
829+
// Restore to user preferences after sustained good performance
830+
else if (!shouldReduceQuality && m_isQualityReduced)
831+
{
832+
if (m_sustainedGoodFrames > 300)
833+
{
834+
TheWritableGlobalData->m_useShadowVolumes = m_userShadowVolumesEnabled;
835+
TheWritableGlobalData->m_useShadowDecals = m_userShadowDecalsEnabled;
836+
TheWritableGlobalData->m_useHeatEffects = m_userHeatEffectsEnabled;
837+
838+
if (TheGameClient)
839+
TheGameClient->allocateShadows();
840+
841+
DynamicGameLODLevel lod = TheGameLODManager->findDynamicLODLevel(averageFPS);
842+
TheGameLODManager->setDynamicLODLevel(lod);
843+
844+
m_isQualityReduced = false;
845+
m_sustainedGoodFrames = 0;
846+
}
847+
}
848+
}
849+
#endif // GENERALS_ONLINE_HIGH_FPS_SERVER

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,9 @@ void W3DDisplay::draw( void )
16861686
return;
16871687

16881688
updateAverageFPS();
1689+
#if defined(GENERALS_ONLINE_HIGH_FPS_SERVER)
1690+
TheGameLODManager->updateGraphicsQualityState(m_averageFPS);
1691+
#else
16891692
if (TheGlobalData->m_enableDynamicLOD && TheGameLogic->getShowDynamicLOD())
16901693
{
16911694
DynamicGameLODLevel lod=TheGameLODManager->findDynamicLODLevel(m_averageFPS);
@@ -1695,6 +1698,7 @@ void W3DDisplay::draw( void )
16951698
{ //if dynamic LOD is turned off, force highest LOD
16961699
TheGameLODManager->setDynamicLODLevel(DYNAMIC_GAME_LOD_VERY_HIGH);
16971700
}
1701+
#endif
16981702

16991703
if (TheGlobalData->m_terrainLOD == TERRAIN_LOD_AUTOMATIC && TheTerrainRenderObject)
17001704
{

0 commit comments

Comments
 (0)