mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +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)
|
CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
|
EXTERN_CVAR(Float, r_actorspriteshadowdist)
|
||||||
|
|
||||||
thread_local bool isWorkerThread;
|
thread_local bool isWorkerThread;
|
||||||
ctpl::thread_pool renderPool(1);
|
ctpl::thread_pool renderPool(1);
|
||||||
bool inited = false;
|
bool inited = false;
|
||||||
|
@ -547,6 +549,18 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
|
||||||
if (CurrentMapSections[thing->subsector->mapsection])
|
if (CurrentMapSections[thing->subsector->mapsection])
|
||||||
{
|
{
|
||||||
HWSprite sprite;
|
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);
|
sprite.Process(this, thing, sector, in_area, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,6 +580,18 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
|
||||||
}
|
}
|
||||||
|
|
||||||
HWSprite sprite;
|
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);
|
sprite.Process(this, thing, sector, in_area, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ public:
|
||||||
|
|
||||||
void CreateVertices(HWDrawInfo *di);
|
void CreateVertices(HWDrawInfo *di);
|
||||||
void PutSprite(HWDrawInfo *di, bool translucent);
|
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 ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector);//, int shade, int fakeside)
|
||||||
|
|
||||||
void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent);
|
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 rs;
|
||||||
sector_t * rendersector;
|
sector_t * rendersector;
|
||||||
|
@ -795,6 +795,12 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
||||||
y = thingpos.Y;
|
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.
|
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.
|
// [RH] Make floatbobbing a renderer-only effect.
|
||||||
if (thing->flags2 & MF2_FLOATBOB)
|
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));
|
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)
|
if (!modelframe)
|
||||||
{
|
{
|
||||||
bool mirror = false;
|
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
|
if (thing->renderflags & RF_SPRITEFLIP) // [SP] Flip back
|
||||||
thing->renderflags ^= RF_XFLIP;
|
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 SpriteOffY = thing->SpriteOffset.Y;
|
||||||
float rightfac = -r.left - thing->SpriteOffset.X;
|
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;
|
if (trans == 0.0f) return;
|
||||||
|
|
||||||
// end of light calculation
|
// end of light calculation
|
||||||
|
|
||||||
actor = thing;
|
actor = thing;
|
||||||
index = thing->SpawnOrder;
|
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;
|
particle = nullptr;
|
||||||
|
|
||||||
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)
|
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)
|
||||||
|
@ -1348,6 +1378,13 @@ void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area)
|
||||||
th->Prev += newpos - savedpos;
|
th->Prev += newpos - savedpos;
|
||||||
|
|
||||||
HWSprite spr;
|
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.
|
// 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);
|
spr.Process(this, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2);
|
||||||
th->Angles.Yaw = savedangle;
|
th->Angles.Yaw = savedangle;
|
||||||
|
|
Loading…
Reference in a new issue