Re-added A_SpriteOffset with a fix to improve performance, and give support for wall and flat sprites.

This commit is contained in:
Major Cooke 2019-10-25 13:23:20 -05:00
parent 31712ed805
commit a1c58f7d10
10 changed files with 41 additions and 19 deletions

View file

@ -989,6 +989,7 @@ public:
DVector3 OldRenderPos; DVector3 OldRenderPos;
DVector3 Vel; DVector3 Vel;
DVector2 SpriteOffset;
double Speed; double Speed;
double FloatSpeed; double FloatSpeed;

View file

@ -366,7 +366,8 @@ void AActor::Serialize(FSerializer &arc)
A("spawntime", SpawnTime) A("spawntime", SpawnTime)
A("spawnorder", SpawnOrder) A("spawnorder", SpawnOrder)
A("friction", Friction) A("friction", Friction)
A("userlights", UserLights); A("userlights", UserLights)
A("SpriteOffset", SpriteOffset);
} }
#undef A #undef A

View file

@ -847,11 +847,10 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
r.Scale(sprscale.X, sprscale.Y); r.Scale(sprscale.X, sprscale.Y);
float rightfac = -r.left; float SpriteOffY = thing->SpriteOffset.Y;
float rightfac = -r.left - thing->SpriteOffset.X;
float leftfac = rightfac - r.width; float leftfac = rightfac - r.width;
float bottomfac = -r.top; z1 = z - r.top - SpriteOffY;
float topfac = bottomfac - r.height;
z1 = z - r.top;
z2 = z1 - r.height; z2 = z1 - r.height;
float spriteheight = sprscale.Y * r.height; float spriteheight = sprscale.Y * r.height;
@ -862,31 +861,39 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
PerformSpriteClipAdjustment(thing, thingpos, spriteheight); PerformSpriteClipAdjustment(thing, thingpos, spriteheight);
} }
float viewvecX;
float viewvecY;
switch (spritetype) switch (spritetype)
{ {
case RF_FACESPRITE: case RF_FACESPRITE:
viewvecX = vp.ViewVector.X; {
viewvecY = vp.ViewVector.Y; float viewvecX = vp.ViewVector.X;
float viewvecY = vp.ViewVector.Y;
x1 = x - viewvecY*leftfac; x1 = x - viewvecY*leftfac;
x2 = x - viewvecY*rightfac; x2 = x - viewvecY*rightfac;
y1 = y + viewvecX*leftfac; y1 = y + viewvecX*leftfac;
y2 = y + viewvecX*rightfac; y2 = y + viewvecX*rightfac;
break; break;
}
case RF_FLATSPRITE: case RF_FLATSPRITE:
{ {
float bottomfac = -r.top - SpriteOffY;
float topfac = bottomfac - r.height;
x1 = x + leftfac; x1 = x + leftfac;
x2 = x + rightfac; x2 = x + rightfac;
y1 = y - topfac; y1 = y - topfac;
y2 = y - bottomfac; y2 = y - bottomfac;
} // [MC] Counteract in case of any potential problems. Tests so far haven't
// shown any outstanding issues but that doesn't mean they won't appear later
// when more features are added.
z1 += SpriteOffY;
z2 += SpriteOffY;
break; break;
}
case RF_WALLSPRITE: case RF_WALLSPRITE:
viewvecX = Angles.Yaw.Cos(); {
viewvecY = Angles.Yaw.Sin(); float viewvecX = Angles.Yaw.Cos();
float viewvecY = Angles.Yaw.Sin();
x1 = x + viewvecY*leftfac; x1 = x + viewvecY*leftfac;
x2 = x + viewvecY*rightfac; x2 = x + viewvecY*rightfac;
@ -895,6 +902,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
break; break;
} }
} }
}
else else
{ {
x1 = x2 = x; x1 = x2 = x;

View file

@ -66,6 +66,8 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
else else
offsetX = tex->GetLeftOffsetPo() * thingxscalemul; offsetX = tex->GetLeftOffsetPo() * thingxscalemul;
offsetX -= thing->SpriteOffset.X;
left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX); left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX);
right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth); right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth);
return true; return true;
@ -113,7 +115,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, AActor *thing, subsector
double spriteHeight = thingyscalemul * tex->GetHeight(); double spriteHeight = thingyscalemul * tex->GetHeight();
posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul; posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul;
posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ); posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ) - thing->SpriteOffset.Y;
//double depth = 1.0; //double depth = 1.0;
//visstyle_t visstyle = GetSpriteVisStyle(thing, depth); //visstyle_t visstyle = GetSpriteVisStyle(thing, depth);

View file

@ -37,7 +37,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac);
pos.Z += thing->GetBobOffset(viewpoint.TicFrac); pos.Z += thing->GetBobOffset(viewpoint.TicFrac) - thing->SpriteOffset.Y;
bool flipTextureX = false; bool flipTextureX = false;
FSoftwareTexture *tex = RenderPolySprite::GetSpriteTexture(thing, flipTextureX); FSoftwareTexture *tex = RenderPolySprite::GetSpriteTexture(thing, flipTextureX);
@ -56,7 +56,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse
// Determine left and right edges of sprite. The sprite's angle is its normal, // Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it. // so the edges are 90 degrees each side of it.
double x2 = tex->GetScaledWidth() * spriteScale.X; double x2 = tex->GetScaledWidth() * spriteScale.X;
double x1 = tex->GetScaledLeftOffsetPo() * spriteScale.X; double x1 = (tex->GetScaledLeftOffsetPo() * spriteScale.X) - thing->SpriteOffset.X;
DVector2 left, right; DVector2 left, right;
left.X = pos.X - x1 * angcos; left.X = pos.X - x1 * angcos;
left.Y = pos.Y - x1 * angsin; left.Y = pos.Y - x1 * angsin;

View file

@ -1002,9 +1002,9 @@ namespace swrenderer
bool RenderOpaquePass::GetThingSprite(AActor *thing, ThingSprite &sprite) bool RenderOpaquePass::GetThingSprite(AActor *thing, ThingSprite &sprite)
{ {
// The X offsetting (SpriteOffset.X) is performed in r_sprite.cpp, in RenderSprite::Project().
sprite.pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac); sprite.pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac);
sprite.pos.Z += thing->GetBobOffset(Thread->Viewport->viewpoint.TicFrac); sprite.pos.Z += thing->GetBobOffset(Thread->Viewport->viewpoint.TicFrac) - thing->SpriteOffset.Y;
sprite.spritenum = thing->sprite; sprite.spritenum = thing->sprite;
sprite.tex = nullptr; sprite.tex = nullptr;
sprite.voxel = nullptr; sprite.voxel = nullptr;

View file

@ -95,6 +95,9 @@ namespace swrenderer
} }
//tx2 = tx >> 4; //tx2 = tx >> 4;
// The Y offsetting is done in r_opaque_pass.cpp, in RenderOpaquePass::GetThingSprite().
tx += thing->SpriteOffset.X;
// too far off the side? // too far off the side?
if (fabs(tx / 64) > fabs(tz)) if (fabs(tx / 64) > fabs(tz))
{ {

View file

@ -1711,6 +1711,7 @@ DEFINE_FIELD_NAMED(AActor, __Pos, pos)
DEFINE_FIELD_NAMED(AActor, __Pos.X, x) DEFINE_FIELD_NAMED(AActor, __Pos.X, x)
DEFINE_FIELD_NAMED(AActor, __Pos.Y, y) DEFINE_FIELD_NAMED(AActor, __Pos.Y, y)
DEFINE_FIELD_NAMED(AActor, __Pos.Z, z) DEFINE_FIELD_NAMED(AActor, __Pos.Z, z)
DEFINE_FIELD(AActor, SpriteOffset)
DEFINE_FIELD(AActor, Prev) DEFINE_FIELD(AActor, Prev)
DEFINE_FIELD(AActor, SpriteAngle) DEFINE_FIELD(AActor, SpriteAngle)
DEFINE_FIELD(AActor, SpriteRotation) DEFINE_FIELD(AActor, SpriteRotation)

View file

@ -95,4 +95,9 @@ extend class Actor
} }
} }
void A_SpriteOffset(double ox = 0.0, double oy = 0.0)
{
SpriteOffset.X = ox;
SpriteOffset.Y = oy;
}
} }

View file

@ -89,6 +89,7 @@ class Actor : Thinker native
native PlayerInfo Player; native PlayerInfo Player;
native readonly vector3 Pos; native readonly vector3 Pos;
native vector3 Prev; native vector3 Prev;
native vector2 SpriteOffset;
native double spriteAngle; native double spriteAngle;
native double spriteRotation; native double spriteRotation;
native double VisibleStartAngle; native double VisibleStartAngle;