- Add sprite adjustment to softpoly

This commit is contained in:
Magnus Norddahl 2017-08-13 01:10:33 +02:00
parent bf38fd57b0
commit 6d6c25bb26
2 changed files with 126 additions and 9 deletions

View File

@ -29,10 +29,14 @@
#include "polyrenderer/poly_renderer.h" #include "polyrenderer/poly_renderer.h"
#include "polyrenderer/scene/poly_light.h" #include "polyrenderer/scene/poly_light.h"
#include "r_data/r_vanillatrans.h" #include "r_data/r_vanillatrans.h"
#include "actorinlines.h"
EXTERN_CVAR(Float, transsouls) EXTERN_CVAR(Float, transsouls)
EXTERN_CVAR(Int, r_drawfuzz) EXTERN_CVAR(Int, r_drawfuzz)
EXTERN_CVAR (Bool, r_debug_disable_vis_filter) EXTERN_CVAR (Bool, r_debug_disable_vis_filter)
EXTERN_CVAR(Int, gl_spriteclip)
EXTERN_CVAR(Float, gl_sclipthreshold)
EXTERN_CVAR(Float, gl_sclipfactor)
extern uint32_t r_renderercaps; extern uint32_t r_renderercaps;
bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right) bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
@ -74,8 +78,17 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
return; return;
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); DVector3 thingpos = thing->InterpolatedPosition(viewpoint.TicFrac);
pos.Z += thing->GetBobOffset(viewpoint.TicFrac);
DVector3 pos = thingpos;
uint32_t spritetype = (thing->renderflags & RF_SPRITETYPEMASK);
if (spritetype == RF_FACESPRITE)
pos.Z -= thing->Floorclip;
if (thing->flags2 & MF2_FLOATBOB)
pos.Z += thing->GetBobOffset(viewpoint.TicFrac);
bool flipTextureX = false; bool flipTextureX = false;
FTexture *tex = GetSpriteTexture(thing, flipTextureX); FTexture *tex = GetSpriteTexture(thing, flipTextureX);
@ -85,20 +98,19 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
DVector2 spriteScale = thing->Scale; DVector2 spriteScale = thing->Scale;
double thingxscalemul = spriteScale.X / tex->Scale.X; double thingxscalemul = spriteScale.X / tex->Scale.X;
double thingyscalemul = spriteScale.Y / tex->Scale.Y; double thingyscalemul = spriteScale.Y / tex->Scale.Y;
double spriteHalfWidth = thingxscalemul * tex->GetWidth() * 0.5;
double spriteHeight = thingyscalemul * tex->GetHeight();
if (flipTextureX) if (flipTextureX)
pos.X -= (tex->GetWidth() - tex->LeftOffset) * thingxscalemul; pos.X -= (tex->GetWidth() - tex->LeftOffset) * thingxscalemul;
else else
pos.X -= tex->LeftOffset * thingxscalemul; pos.X -= tex->LeftOffset * thingxscalemul;
//pos.Z -= tex->TopOffset * thingyscalemul;
pos.Z -= (tex->GetHeight() - tex->TopOffset) * thingyscalemul + thing->Floorclip;
double spriteHalfWidth = thingxscalemul * tex->GetWidth() * 0.5;
double spriteHeight = thingyscalemul * tex->GetHeight();
pos.X += spriteHalfWidth; pos.X += spriteHalfWidth;
pos.Z -= (tex->GetHeight() - tex->TopOffset) * thingyscalemul;
pos.Z = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, pos.Z);
//double depth = 1.0; //double depth = 1.0;
//visstyle_t visstyle = GetSpriteVisStyle(thing, depth); //visstyle_t visstyle = GetSpriteVisStyle(thing, depth);
// Rumor has it that AlterWeaponSprite needs to be called with visstyle passed in somewhere around here.. // Rumor has it that AlterWeaponSprite needs to be called with visstyle passed in somewhere around here..
@ -157,6 +169,109 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
} }
double RenderPolySprite::GetSpriteFloorZ(AActor *thing, const DVector2 &thingpos)
{
extsector_t::xfloor &x = thing->Sector->e->XFloor;
for (unsigned int i = 0; i < x.ffloors.Size(); i++)
{
F3DFloor *ff = x.ffloors[i];
double floorh = ff->top.plane->ZatPoint(thingpos);
if (floorh == thing->floorz)
return floorh;
}
if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC))
{
if (thing->flags2&MF2_ONMOBJ && thing->floorz == thing->Sector->heightsec->floorplane.ZatPoint(thingpos))
{
return thing->floorz;
}
}
return thing->Sector->floorplane.ZatPoint(thing) - thing->Floorclip;
}
double RenderPolySprite::GetSpriteCeilingZ(AActor *thing, const DVector2 &thingpos)
{
extsector_t::xfloor &x = thing->Sector->e->XFloor;
for (unsigned int i = 0; i < x.ffloors.Size(); i++)
{
F3DFloor *ff = x.ffloors[i];
double ceilingh = ff->bottom.plane->ZatPoint(thingpos);
if (ceilingh == thing->ceilingz)
return ceilingh;
}
if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC))
{
if (thing->flags2&MF2_ONMOBJ && thing->ceilingz == thing->Sector->heightsec->ceilingplane.ZatPoint(thingpos))
{
return thing->ceilingz;
}
}
return thing->Sector->ceilingplane.ZatPoint(thingpos);
}
double RenderPolySprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, double spriteheight, double z2)
{
int spriteclip = 2; // gl_spriteclip, but use 'always' mode for now
double z1 = z2 + spriteheight;
// Tests show that this doesn't look good for many decorations and corpses
uint32_t spritetype = (thing->renderflags & RF_SPRITETYPEMASK);
if (!(spriteheight > 0 && spriteclip > 0 && spritetype == RF_FACESPRITE))
return z2;
bool clipthing = (thing->player || thing->flags3&MF3_ISMONSTER || thing->IsKindOf(RUNTIME_CLASS(AInventory))) && (thing->flags&MF_ICECORPSE || !(thing->flags&MF_CORPSE));
bool smarterclip = !clipthing && spriteclip == 3;
if (clipthing || spriteclip > 1)
{
double diffb = MIN(z2 - GetSpriteFloorZ(thing, thingpos), 0.0);
// Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics
if (smarterclip)
{
// Reduce slightly clipping adjustment of corpses
if (thing->flags & MF_CORPSE || spriteheight > fabs(diffb))
{
double ratio = clamp<double>((fabs(diffb) * (double)gl_sclipfactor / (spriteheight + 1)), 0.5, 1.0);
diffb *= ratio;
}
if (!diffb)
{
double difft = MAX(z1 - GetSpriteCeilingZ(thing, thingpos), 0.0);
if (difft >= (double)gl_sclipthreshold)
{
// dumb copy of the above.
if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || difft > (double)gl_sclipthreshold)
{
difft = 0;
}
}
if (spriteheight > fabs(difft))
{
double ratio = clamp<double>((fabs(difft) * (double)gl_sclipfactor / (spriteheight + 1)), 0.5, 1.0);
difft *= ratio;
}
z2 -= difft;
}
}
if (diffb <= (0 - (double)gl_sclipthreshold)) // such a large displacement can't be correct!
{
// for living monsters standing on the floor allow a little more.
if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || diffb < (-1.8*(double)gl_sclipthreshold))
{
diffb = 0;
}
}
z2 -= diffb;
}
return z2;
}
bool RenderPolySprite::IsThingCulled(AActor *thing) bool RenderPolySprite::IsThingCulled(AActor *thing)
{ {
FIntCVar *cvar = thing->GetInfo()->distancecheck; FIntCVar *cvar = thing->GetInfo()->distancecheck;

View File

@ -34,5 +34,7 @@ public:
static FTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX); static FTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX);
private: private:
//visstyle_t GetSpriteVisStyle(AActor *thing, double z); static double PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, double spriteheight, double z);
static double GetSpriteFloorZ(AActor *thing, const DVector2 &thingpos);
static double GetSpriteCeilingZ(AActor *thing, const DVector2 &thingpos);
}; };