mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
Add sprite shadows for the hardware renderer
This commit is contained in:
parent
5446a1a355
commit
15159a3c19
3 changed files with 66 additions and 3 deletions
|
@ -49,6 +49,8 @@
|
|||
|
||||
CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
EXTERN_CVAR(Float, r_actorspriteshadowdist)
|
||||
|
||||
thread_local bool isWorkerThread;
|
||||
ctpl::thread_pool renderPool(1);
|
||||
bool inited = false;
|
||||
|
@ -547,6 +549,18 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
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, thing, sector, in_area, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
sprite.Process(this, thing, sector, in_area, false);
|
||||
}
|
||||
}
|
||||
|
@ -566,6 +580,18 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
}
|
||||
|
||||
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, thing, sector, in_area, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
sprite.Process(this, thing, sector, in_area, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ public:
|
|||
|
||||
void CreateVertices(HWDrawInfo *di);
|
||||
void PutSprite(HWDrawInfo *di, bool translucent);
|
||||
void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false);
|
||||
void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false, bool isSpriteShadow = false);
|
||||
void ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector);//, int shade, int fakeside)
|
||||
|
||||
void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
|
|
|
@ -678,7 +678,7 @@ void HWSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t in_area, int thruportal)
|
||||
void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t in_area, int thruportal, bool isSpriteShadow)
|
||||
{
|
||||
sector_t rs;
|
||||
sector_t * rendersector;
|
||||
|
@ -795,6 +795,12 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
y = thingpos.Y;
|
||||
if (spritetype == RF_FACESPRITE) z -= thing->Floorclip; // wall and flat sprites are to be considered di->Level-> geometry so this may not apply.
|
||||
|
||||
// snap shadow Z to the floor
|
||||
if (isSpriteShadow)
|
||||
{
|
||||
z = thing->floorz;
|
||||
}
|
||||
|
||||
// [RH] Make floatbobbing a renderer-only effect.
|
||||
if (thing->flags2 & MF2_FLOATBOB)
|
||||
{
|
||||
|
@ -803,6 +809,13 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
}
|
||||
|
||||
modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
|
||||
// don't bother drawing sprite shadows if this is a model (it will never look right)
|
||||
if (modelframe && isSpriteShadow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!modelframe)
|
||||
{
|
||||
bool mirror = false;
|
||||
|
@ -897,7 +910,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
if (thing->renderflags & RF_SPRITEFLIP) // [SP] Flip back
|
||||
thing->renderflags ^= RF_XFLIP;
|
||||
|
||||
r.Scale(sprscale.X, sprscale.Y);
|
||||
r.Scale(sprscale.X, isSpriteShadow ? sprscale.Y * 0.15 : sprscale.Y);
|
||||
|
||||
float SpriteOffY = thing->SpriteOffset.Y;
|
||||
float rightfac = -r.left - thing->SpriteOffset.X;
|
||||
|
@ -1118,12 +1131,29 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
}
|
||||
}
|
||||
|
||||
// for sprite shadow, use a translucent stencil renderstyle
|
||||
if (isSpriteShadow)
|
||||
{
|
||||
RenderStyle = STYLE_Stencil;
|
||||
ThingColor = MAKEARGB(ColorMatcher.Pick(0, 0, 0), 0, 0, 0);
|
||||
trans = 0.5f;
|
||||
hw_styleflags = STYLEHW_NoAlphaTest;
|
||||
}
|
||||
|
||||
if (trans == 0.0f) return;
|
||||
|
||||
// end of light calculation
|
||||
|
||||
actor = thing;
|
||||
index = thing->SpawnOrder;
|
||||
|
||||
// sprite shadows should have a fixed index of -1 (ensuring they're drawn behind particles which have index 0)
|
||||
// sorting should be irrelevant since they're always translucent
|
||||
if (isSpriteShadow)
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
|
||||
particle = nullptr;
|
||||
|
||||
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)
|
||||
|
@ -1348,6 +1378,13 @@ void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area)
|
|||
th->Prev += newpos - savedpos;
|
||||
|
||||
HWSprite spr;
|
||||
|
||||
// [Nash] draw sprite shadow
|
||||
if (R_ShouldDrawSpriteShadow(th))
|
||||
{
|
||||
spr.Process(this, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2, true);
|
||||
}
|
||||
|
||||
// This is called from the worker thread and must not alter the fake sector cache.
|
||||
spr.Process(this, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2);
|
||||
th->Angles.Yaw = savedangle;
|
||||
|
|
Loading…
Reference in a new issue