- fixed sprite sorting in the hardware renderer.

This did no longer sort sprites in the same position reliably since the feature to render sprites which only partially are inside a sector was added.
With this, sprites in the same position are no longer guaranteed to be added to the render list in sequence.
Fixed by adding an 'order' field to AActor which gets incremented with each spawned actor and reset when a new level is started.

The software renderer will also need a variation of this fix but its data no longer has access to the defining actor when being sorted, so a bit more work is needed here.
This commit is contained in:
Christoph Oelckers 2018-12-24 10:18:25 +01:00
parent 0c4602507e
commit c58f5095d9
7 changed files with 10 additions and 2 deletions

View file

@ -1237,6 +1237,8 @@ public:
// When was this actor spawned?
int SpawnTime;
uint32_t SpawnOrder;
// ThingIDs
static void ClearTIDHashes ();

View file

@ -496,6 +496,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
level.time = 0;
level.maptime = 0;
level.totaltime = 0;
level.spawnindex = 0;
if (!multiplayer || !deathmatch)
{
@ -869,6 +870,7 @@ void G_DoCompleted (void)
}
level.time = 0;
level.maptime = 0;
level.spawnindex = 0;
}
finishstate = mode;

View file

@ -108,6 +108,7 @@ struct FLevelLocals : public FLevelData
int starttime;
int partime;
int sucktime;
uint32_t spawnindex;
level_info_t *info;
int cluster;

View file

@ -588,7 +588,7 @@ inline int HWDrawList::CompareSprites(SortNode * a,SortNode * b)
int res = s1->depth - s2->depth;
if (res != 0) return -res;
else return (i_compatflags & COMPATF_SPRITESORT)? s1->index-s2->index : s2->index-s1->index;
else return (i_compatflags & COMPATF_SPRITESORT)? s2->index-s1->index : s1->index-s2->index;
}
//==========================================================================

View file

@ -1062,7 +1062,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
// end of light calculation
actor = thing;
index = di->spriteindex++; // this assumes that sprites from the same sector are added sequentially, i.e. by the same thread.
index = thing->SpawnOrder;
particle = nullptr;
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)

View file

@ -362,6 +362,7 @@ void AActor::Serialize(FSerializer &arc)
A("renderrequired", RenderRequired)
A("friendlyseeblocks", friendlyseeblocks)
A("spawntime", SpawnTime)
A("spawnorder", SpawnOrder)
A("friction", Friction);
}
@ -4409,6 +4410,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a
actor = static_cast<AActor *>(const_cast<PClassActor *>(type)->CreateNew ());
actor->SpawnTime = level.totaltime;
actor->SpawnOrder = level.spawnindex++;
// Set default dialogue
actor->ConversationRoot = GetConversation(actor->GetClass()->TypeName);

View file

@ -971,6 +971,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
("level.skyfog", level.skyfog)
("level.deathsequence", level.deathsequence)
("level.bodyqueslot", level.bodyqueslot)
("level.spawnindex", level.spawnindex)
.Array("level.bodyque", level.bodyque, level.BODYQUESIZE);
// Hub transitions must keep the current total time