Skip to content

Commit 77a685a

Browse files
committed
bugfix(drawable): Fix duplicated terrain decals applied after call to W3DModelDraw::replaceModelConditionState
1 parent 35f042f commit 77a685a

File tree

3 files changed

+27
-32
lines changed

3 files changed

+27
-32
lines changed

GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ class Drawable : public Thing,
640640
virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle);
641641
void updateHiddenStatus();
642642

643+
void replaceModelConditionStateInDrawable();
644+
643645
private:
644646

645647
const Locomotor* getLocomotor() const;
@@ -727,7 +729,7 @@ class Drawable : public Thing,
727729
Bool m_receivesDynamicLights;
728730

729731
#ifdef DIRTY_CONDITION_FLAGS
730-
mutable Bool m_isModelDirty; ///< if true, must call replaceModelConditionState() before drawing or accessing drawmodule info
732+
Bool m_isModelDirty; ///< if true, must call replaceModelConditionState() before drawing or accessing drawmodule info
731733
#endif
732734

733735
//*******************************************

GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,13 +3984,7 @@ DrawModule** Drawable::getDrawModules()
39843984
}
39853985
else
39863986
{
3987-
for (DrawModule** dm2 = dm; *dm2; ++dm2)
3988-
{
3989-
ObjectDrawInterface* di = (*dm2)->getObjectDrawInterface();
3990-
if (di)
3991-
di->replaceModelConditionState( m_conditionState );
3992-
}
3993-
m_isModelDirty = false;
3987+
replaceModelConditionStateInDrawable();
39943988
}
39953989
}
39963990
#endif
@@ -4013,14 +4007,7 @@ DrawModule const** Drawable::getDrawModules() const
40134007
}
40144008
else
40154009
{
4016-
// yeah, yeah, yeah... I know (srj)
4017-
for (DrawModule** dm2 = (DrawModule**)dm; *dm2; ++dm2)
4018-
{
4019-
ObjectDrawInterface* di = (*dm2)->getObjectDrawInterface();
4020-
if (di)
4021-
di->replaceModelConditionState( m_conditionState );
4022-
}
4023-
m_isModelDirty = false;
4010+
const_cast<Drawable*>(this)->replaceModelConditionStateInDrawable();
40244011
}
40254012
}
40264013
#endif
@@ -4041,12 +4028,7 @@ void Drawable::clearAndSetModelConditionFlags(const ModelConditionFlags& clr, co
40414028
#ifdef DIRTY_CONDITION_FLAGS
40424029
m_isModelDirty = true;
40434030
#else
4044-
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
4045-
{
4046-
ObjectDrawInterface* di = (*dm)->getObjectDrawInterface();
4047-
if (di)
4048-
di->replaceModelConditionState( m_conditionState );
4049-
}
4031+
replaceModelConditionStateInDrawable();
40504032
#endif
40514033
}
40524034

@@ -4068,24 +4050,37 @@ void Drawable::replaceModelConditionFlags( const ModelConditionFlags &flags, Boo
40684050
// when forcing a replace we won't use dirty flags, we will immediately do an update now
40694051
if( forceReplace == TRUE )
40704052
{
4071-
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
4072-
{
4073-
ObjectDrawInterface* di = (*dm)->getObjectDrawInterface();
4074-
if (di)
4075-
di->replaceModelConditionState( m_conditionState );
4076-
}
4077-
m_isModelDirty = false;
4053+
replaceModelConditionStateInDrawable();
40784054
}
40794055
else
4056+
{
40804057
m_isModelDirty = true;
4058+
}
40814059
#else
4060+
replaceModelConditionStateInDrawable();
4061+
#endif
4062+
}
4063+
4064+
//-------------------------------------------------------------------------------------------------
4065+
void Drawable::replaceModelConditionStateInDrawable()
4066+
{
4067+
// TheSuperHackers @info Set not dirty early to avoid recursive calls from within getDrawModules().
4068+
m_isModelDirty = false;
4069+
4070+
// TheSuperHackers @bugfix Remove and re-add the terrain decal before processing the individual draw
4071+
// modules, because the terrain decal is applied to the first draw module only, and the new first
4072+
// draw module may be different than before.
4073+
const TerrainDecalType terrainDecalType = getTerrainDecalType();
4074+
setTerrainDecal(TERRAIN_DECAL_NONE);
4075+
40824076
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
40834077
{
40844078
ObjectDrawInterface* di = (*dm)->getObjectDrawInterface();
40854079
if (di)
40864080
di->replaceModelConditionState( m_conditionState );
40874081
}
4088-
#endif
4082+
4083+
setTerrainDecal(terrainDecalType);
40894084
}
40904085

40914086
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,8 +3136,6 @@ void W3DModelDraw::setModelState(const ModelConditionInfo* newState)
31363136
// tie in our drawable as the user data pointer in the render object
31373137
m_renderObject->Set_User_Data(draw->getDrawableInfo());
31383138

3139-
setTerrainDecal(draw->getTerrainDecalType());
3140-
31413139
//We created a new render object so we need to preserve the visibility state
31423140
//of the previous render object.
31433141
if (draw->isDrawableEffectivelyHidden())

0 commit comments

Comments
 (0)