Fix sprites

This commit is contained in:
Magnus Norddahl 2025-05-29 03:08:09 +02:00
commit b5f309ade9
4 changed files with 61 additions and 122 deletions

View file

@ -37,6 +37,7 @@
#include "hw_drawcontext.h"
#include "hw_walldispatcher.h"
#include "hw_visibleset.h"
#include "hw_fakeflat.h"
#include "po_man.h"
#include "models.h"
#include "hw_clock.h"
@ -56,6 +57,9 @@ EXTERN_CVAR(Float, r_visibility)
EXTERN_CVAR(Int, lm_background_updates);
EXTERN_CVAR(Float, r_actorspriteshadowdist)
EXTERN_CVAR(Bool, gl_portals)
EXTERN_CVAR(Bool, gl_render_things);
EXTERN_CVAR(Bool, gl_render_walls);
EXTERN_CVAR(Bool, gl_render_flats);
CVAR(Bool, lm_always_update, false, 0)
@ -460,7 +464,47 @@ void HWDrawInfo::RenderPVS(bool drawpsprites, FRenderState& state)
CheckUpdate(state, &Level->sectors[sectorIndex]);
}
for (int sectorIndex : SeenSectors.Get())
{
Level->sectors[sectorIndex].MoreFlags |= SECMF_DRAWN;
}
for (int subIndex : SeenHackedSubsectors.Get())
{
SubsectorHackInfo sh = { &Level->subsectors[subIndex], 0 };
SubsectorHacks.Push(sh);
}
if (gl_render_things)
{
for (int subIndex : SeenSubsectors.Get())
{
subsector_t* sub = &Level->subsectors[subIndex];
sector_t* sector = sub->sector;
bool things = sector->touching_renderthings || sector->sectorportal_thinglist;
bool particles = sub->sprites.Size() > 0 || Level->ParticlesInSubsec[sub->Index()] != NO_PARTICLE;
if (things || particles)
{
auto fakesector = hw_FakeFlat(drawctx, sector, in_area, false);
if (things)
RenderThings(sub, fakesector, state);
if (particles)
RenderParticles(sub, fakesector, state);
}
}
}
Bsp.Unclock();
// Process all the sprites on the current portal's back side which touch the portal.
if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this, state);
if (drawpsprites)
PreparePlayerSprites(Viewpoint.sector, in_area, state);
}
}

View file

@ -226,7 +226,7 @@ struct HWDrawInfo
TArray<bool> AddedToList;
};
VisList SeenSectors, SeenSides;
VisList SeenSectors, SeenSides, SeenSubsectors, SeenHackedSubsectors;
TArray<bool> QueryResultsBuffer;
@ -242,9 +242,7 @@ struct HWDrawInfo
void AddPolyobjs(subsector_t *sub);
void AddLines(subsector_t * sub, sector_t * sector);
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, linebase_t *line);
public:
void RenderThings(subsector_t * sub, sector_t * sector);
void RenderParticles(subsector_t *sub, sector_t *front);
public:
void DoSubsector(subsector_t * sub);
void DrawPSprite(HUDSprite* huds, FRenderState& state);
WeaponLighting GetWeaponLighting(sector_t* viewsector, const DVector3& pos, int cm, area_t in_area, const DVector3& playerpos);

View file

@ -89,6 +89,8 @@ void HWVisibleSet::RenderBSP(void* node)
SeenSectors.Clear();
SeenSides.Clear();
SeenSubsectors.Clear();
SeenHackedSubsectors.Clear();
RenderBSPNode(node);
}
@ -171,7 +173,8 @@ void HWVisibleSet::DoSubsector(subsector_t* sub)
// [RH] Add particles
if (gl_render_things && (sub->sprites.Size() > 0 || Level->ParticlesInSubsec[sub->Index()] != NO_PARTICLE))
{
RenderParticles(sub, fakesector);
SeenSubsectors.Add(sub->Index());
//RenderParticles(sub, fakesector);
}
AddLines(sub, fakesector);
@ -184,11 +187,12 @@ void HWVisibleSet::DoSubsector(subsector_t* sub)
{
// Well, now it will be done.
validcount.sector[sector->Index()] = validcount.current;
sector->MoreFlags |= SECMF_DRAWN;
//sector->MoreFlags |= SECMF_DRAWN;
if (gl_render_things && (sector->touching_renderthings || sector->sectorportal_thinglist))
{
RenderThings(sub, fakesector);
SeenSubsectors.Add(sub->Index());
//RenderThings(sub, fakesector);
}
}
@ -465,13 +469,10 @@ void HWVisibleSet::PolySubsector(subsector_t* sub)
void HWVisibleSet::AddHackedSubsector(subsector_t* sub)
{
#if NEEDS_PVS_PORTING
if (Level->maptype != MAPTYPE_HEXEN)
{
SubsectorHackInfo sh = { sub, 0 };
SubsectorHacks.Push(sh);
SeenHackedSubsectors.Add(sub->Index());
}
#endif
}
static bool PointOnLine(const DVector2& pos, const linebase_t* line)
@ -501,114 +502,6 @@ void HWVisibleSet::AddSpecialPortalLines(subsector_t* sub, sector_t* sector, lin
}
}
void HWVisibleSet::RenderThings(subsector_t* sub, sector_t* sector)
{
#if NEEDS_PVS_PORTING
sector_t* sec = sub->sector;
// Handle all things in sector.
const auto& vp = Viewpoint;
for (auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext)
{
auto thing = p->m_thing;
if (thing->validcount == validcount) continue;
thing->validcount = validcount;
if (Viewpoint.IsAllowedOoB() && thing->Sector->isSecret() && thing->Sector->wasSecret() && !r_radarclipper) continue; // This covers things that are touching non-secret sectors
FIntCVar* cvar = thing->GetInfo()->distancecheck;
if (cvar != nullptr && *cvar >= 0)
{
double dist = (thing->Pos() - vp.Pos).LengthSquared();
double check = (double)**cvar;
if (dist >= check * check)
{
continue;
}
}
// If this thing is in a map section that's not in view it can't possibly be visible
if ((*CurrentMapSections)[thing->subsector->mapsection])
{
HWSprite sprite;
// [Nash] draw sprite shadow
if (R_ShouldDrawSpriteShadow(thing))
{
double dist = (thing->Pos() - vp.Pos).LengthSquared();
double check = r_actorspriteshadowdist;
if (dist <= check * check)
{
sprite.Process(this, state, thing, sector, in_area, false, true);
}
}
sprite.Process(this, state, thing, sector, in_area, false);
}
}
for (msecnode_t* node = sec->sectorportal_thinglist; node; node = node->m_snext)
{
AActor* thing = node->m_thing;
FIntCVar* cvar = thing->GetInfo()->distancecheck;
if (cvar != nullptr && *cvar >= 0)
{
double dist = (thing->Pos() - vp.Pos).LengthSquared();
double check = (double)**cvar;
if (dist >= check * check)
{
continue;
}
}
HWSprite sprite;
// [Nash] draw sprite shadow
if (R_ShouldDrawSpriteShadow(thing))
{
double dist = (thing->Pos() - vp.Pos).LengthSquared();
double check = r_actorspriteshadowdist;
if (dist <= check * check)
{
sprite.Process(this, state, thing, sector, in_area, true, true);
}
}
sprite.Process(this, state, thing, sector, in_area, true);
}
#endif
}
void HWVisibleSet::RenderParticles(subsector_t* sub, sector_t* front)
{
#if NEEDS_PVS_PORTING
SetupSprite.Clock();
for (uint32_t i = 0; i < sub->sprites.Size(); i++)
{
DVisualThinker* sp = sub->sprites[i];
if (!sp || sp->ObjectFlags & OF_EuthanizeMe)
continue;
if (mClipPortal)
{
int clipres = mClipPortal->ClipPoint(sp->PT.Pos.XY());
if (clipres == PClip_InFront) continue;
}
HWSprite sprite;
sprite.ProcessParticle(this, state, &sp->PT, front, sp);
}
for (int i = Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Level->Particles[i].snext)
{
if (mClipPortal)
{
int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos.XY());
if (clipres == PClip_InFront) continue;
}
HWSprite sprite;
sprite.ProcessParticle(this, state, &Level->Particles[i], front, nullptr);
}
SetupSprite.Unclock();
#endif
}
/////////////////////////////////////////////////////////////////////////////
HWVisibleSetThreads::HWVisibleSetThreads()
@ -670,12 +563,18 @@ void HWVisibleSetThreads::FindPVS(HWDrawInfo* di)
// Merge results
di->SeenSectors.Clear();
di->SeenSides.Clear();
di->SeenSubsectors.Clear();
di->SeenHackedSubsectors.Clear();
for (int i = 0; i < SliceCount; i++)
{
for (int sectorIndex : Slices[i].SeenSectors.Get())
di->SeenSectors.Add(sectorIndex);
for (int sideIndex : Slices[i].SeenSides.Get())
di->SeenSides.Add(sideIndex);
for (int subIndex : Slices[i].SeenSubsectors.Get())
di->SeenSubsectors.Add(subIndex);
for (int subIndex : Slices[i].SeenHackedSubsectors.Get())
di->SeenHackedSubsectors.Add(subIndex);
}
}

View file

@ -49,7 +49,7 @@ public:
TArray<bool> AddedToList;
};
VisList SeenSectors, SeenSides;
VisList SeenSectors, SeenSides, SeenSubsectors, SeenHackedSubsectors;
private:
void RenderBSP(void* node);
@ -63,8 +63,6 @@ private:
void PolySubsector(subsector_t* sub);
void AddHackedSubsector(subsector_t* sub);
void AddSpecialPortalLines(subsector_t* sub, sector_t* sector, linebase_t* line);
void RenderParticles(subsector_t* sub, sector_t* front);
void RenderThings(subsector_t* sub, sector_t* sector);
angle_t FrustumAngle();
struct