Detach player sprites from VisibleSprite

This commit is contained in:
Magnus Norddahl 2017-01-24 04:15:54 +01:00
parent 3ea27cd996
commit ba6094be2e
12 changed files with 284 additions and 192 deletions

View file

@ -452,7 +452,7 @@ namespace swrenderer
else if (style == LegacyRenderStyles[STYLE_Shaded]) else if (style == LegacyRenderStyles[STYLE_Shaded])
{ {
// Shaded drawer only gets 16 levels of alpha because it saves memory. // Shaded drawer only gets 16 levels of alpha because it saves memory.
if ((alpha >>= 12) == 0) if ((alpha >>= 12) == 0 || basecolormap == nullptr)
return false; return false;
colfunc = &SWPixelFormatDrawers::DrawShadedColumn; colfunc = &SWPixelFormatDrawers::DrawShadedColumn;
drawer_needs_pal_input = true; drawer_needs_pal_input = true;

View file

@ -217,7 +217,7 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites()
{ {
if (!r_polyrenderer) if (!r_polyrenderer)
{ {
RenderPlayerSprite::RenderRemainingPlayerSprites(); RenderPlayerSprites::Instance()->RenderRemaining();
} }
else else
{ {

View file

@ -208,6 +208,7 @@ namespace swrenderer
clip3d->DeleteHeights(); clip3d->DeleteHeights();
clip3d->fake3D = 0; clip3d->fake3D = 0;
} }
RenderPlayerSprite::RenderPlayerSprites();
RenderPlayerSprites::Instance()->Render();
} }
} }

View file

@ -114,7 +114,7 @@ namespace swrenderer
WallTMapScale2 = IYaspectMul / CenterX; WallTMapScale2 = IYaspectMul / CenterX;
// psprite scales // psprite scales
RenderPlayerSprite::SetupSpriteScale(); RenderPlayerSprites::Instance()->SetupSpriteScale();
// thing clipping // thing clipping
fillshort(screenheightarray, viewwidth, (short)viewheight); fillshort(screenheightarray, viewwidth, (short)viewheight);

View file

@ -198,11 +198,10 @@ namespace swrenderer
vis->renderflags = (short)(particle->alpha * 255.0f + 0.5f); vis->renderflags = (short)(particle->alpha * 255.0f + 0.5f);
vis->FakeFlatStat = fakeside; vis->FakeFlatStat = fakeside;
vis->floorclip = 0; vis->floorclip = 0;
vis->ColormapNum = 0;
vis->foggy = foggy; vis->foggy = foggy;
// Particles are slightly more visible than regular sprites. // Particles are slightly more visible than regular sprites.
vis->SetColormap(tiz * r_SpriteVisibility * 0.5, shade, map, particle->bright != 0, false, false); vis->Light.SetColormap(tiz * r_SpriteVisibility * 0.5, shade, map, particle->bright != 0, false, false);
VisibleSpriteList::Instance()->Push(vis); VisibleSpriteList::Instance()->Push(vis);
} }
@ -214,7 +213,7 @@ namespace swrenderer
auto vis = this; auto vis = this;
int spacing; int spacing;
BYTE color = vis->BaseColormap->Maps[vis->startfrac]; BYTE color = vis->Light.BaseColormap->Maps[vis->startfrac];
int yl = vis->y1; int yl = vis->y1;
int ycount = vis->y2 - yl + 1; int ycount = vis->y2 - yl + 1;
int x1 = vis->x1; int x1 = vis->x1;
@ -225,7 +224,7 @@ namespace swrenderer
DrawMaskedSegsBehindParticle(); DrawMaskedSegsBehindParticle();
uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->ColormapNum << FRACBITS))); uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Light.ColormapNum << FRACBITS)));
// vis->renderflags holds translucency level (0-255) // vis->renderflags holds translucency level (0-255)
fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff; fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;

View file

@ -65,23 +65,20 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer namespace swrenderer
{ {
TArray<RenderPlayerSprite::vispsp_t> RenderPlayerSprite::vispsprites; RenderPlayerSprites *RenderPlayerSprites::Instance()
unsigned int RenderPlayerSprite::vispspindex; {
static RenderPlayerSprites instance;
return &instance;
}
double RenderPlayerSprite::pspritexscale; void RenderPlayerSprites::SetupSpriteScale()
double RenderPlayerSprite::pspritexiscale;
double RenderPlayerSprite::pspriteyscale;
TArray<RenderSprite> RenderPlayerSprite::avis;
void RenderPlayerSprite::SetupSpriteScale()
{ {
pspritexscale = centerxwide / 160.0; pspritexscale = centerxwide / 160.0;
pspriteyscale = pspritexscale * YaspectMul; pspriteyscale = pspritexscale * YaspectMul;
pspritexiscale = 1 / pspritexscale; pspritexiscale = 1 / pspritexscale;
} }
void RenderPlayerSprite::RenderPlayerSprites() void RenderPlayerSprites::Render()
{ {
int i; int i;
int lightnum; int lightnum;
@ -184,7 +181,7 @@ namespace swrenderer
if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr) if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr)
{ {
Render(psp, camera, bobx, boby, wx, wy, r_TicFracF, spriteshade, basecolormap); RenderSprite(psp, camera, bobx, boby, wx, wy, r_TicFracF, spriteshade, basecolormap, foggy);
} }
psp = psp->GetNext(); psp = psp->GetNext();
@ -194,7 +191,7 @@ namespace swrenderer
} }
} }
void RenderPlayerSprite::Render(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap) void RenderPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy)
{ {
double tx; double tx;
int x1; int x1;
@ -208,9 +205,6 @@ namespace swrenderer
bool noaccel; bool noaccel;
double alpha = owner->Alpha; double alpha = owner->Alpha;
if (avis.Size() < vispspindex + 1)
avis.Reserve(avis.Size() - vispspindex + 1);
// decide which patch to use // decide which patch to use
if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size()) if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size())
{ {
@ -272,12 +266,11 @@ namespace swrenderer
return; return;
// store information in a vissprite // store information in a vissprite
RenderSprite *vis = &avis[vispspindex]; NoAccelPlayerSprite vis;
vis->renderflags = owner->renderflags; vis.renderflags = owner->renderflags;
vis->floorclip = 0;
vis->texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
if (camera->player && (RenderTarget != screen || if (camera->player && (RenderTarget != screen ||
viewheight == RenderTarget->GetHeight() || viewheight == RenderTarget->GetHeight() ||
@ -288,41 +281,39 @@ namespace swrenderer
{ {
if (RenderTarget != screen || viewheight == RenderTarget->GetHeight()) if (RenderTarget != screen || viewheight == RenderTarget->GetHeight())
{ {
vis->texturemid -= weapon->YAdjust; vis.texturemid -= weapon->YAdjust;
} }
else else
{ {
vis->texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust; vis.texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust;
} }
} }
} }
if (pspr->GetID() < PSP_TARGETCENTER) if (pspr->GetID() < PSP_TARGETCENTER)
{ // Move the weapon down for 1280x1024. { // Move the weapon down for 1280x1024.
vis->texturemid -= AspectPspriteOffset(WidescreenRatio); vis.texturemid -= AspectPspriteOffset(WidescreenRatio);
} }
vis->x1 = x1 < 0 ? 0 : x1; vis.x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth : x2; vis.x2 = x2 >= viewwidth ? viewwidth : x2;
vis->xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X);
vis->yscale = float(pspriteyscale / tex->Scale.Y); vis.yscale = float(pspriteyscale / tex->Scale.Y);
vis->Translation = 0; // [RH] Use default colors vis.pic = tex;
vis->pic = tex;
vis->ColormapNum = 0;
// If flip is used, provided that it's not already flipped (that would just invert itself) // If flip is used, provided that it's not already flipped (that would just invert itself)
// (It's an XOR...) // (It's an XOR...)
if (!(flip) != !(pspr->Flags & PSPF_FLIP)) if (!(flip) != !(pspr->Flags & PSPF_FLIP))
{ {
vis->xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X); vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1; vis.startfrac = (tex->GetWidth() << FRACBITS) - 1;
} }
else else
{ {
vis->xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X); vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis->startfrac = 0; vis.startfrac = 0;
} }
if (vis->x1 > x1) if (vis.x1 > x1)
vis->startfrac += vis->xiscale*(vis->x1 - x1); vis.startfrac += vis.xiscale*(vis.x1 - x1);
noaccel = false; noaccel = false;
FDynamicColormap *colormap_to_use = nullptr; FDynamicColormap *colormap_to_use = nullptr;
@ -336,42 +327,42 @@ namespace swrenderer
if (pspr->Flags & PSPF_FORCESTYLE) if (pspr->Flags & PSPF_FORCESTYLE)
{ {
vis->RenderStyle = LegacyRenderStyles[rs]; vis.RenderStyle = LegacyRenderStyles[rs];
} }
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy]) else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
{ {
vis->RenderStyle = LegacyRenderStyles[STYLE_Fuzzy]; vis.RenderStyle = LegacyRenderStyles[STYLE_Fuzzy];
} }
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]) else if (owner->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])
{ {
vis->RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy]; vis.RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy];
vis->RenderStyle.CheckFuzz(); vis.RenderStyle.CheckFuzz();
} }
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
{ {
vis->RenderStyle = LegacyRenderStyles[STYLE_Subtract]; vis.RenderStyle = LegacyRenderStyles[STYLE_Subtract];
} }
else else
{ {
vis->RenderStyle = LegacyRenderStyles[rs]; vis.RenderStyle = LegacyRenderStyles[rs];
} }
} }
else else
{ {
vis->RenderStyle = owner->RenderStyle; vis.RenderStyle = owner->RenderStyle;
} }
// Set the alpha based on if using the overlay's own or not. Also adjust // Set the alpha based on if using the overlay's own or not. Also adjust
// and override the alpha if not forced. // and override the alpha if not forced.
if (pspr->Flags & PSPF_ALPHA) if (pspr->Flags & PSPF_ALPHA)
{ {
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy]) if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
{ {
alpha = owner->Alpha; alpha = owner->Alpha;
} }
else if (vis->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]) else if (vis.RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])
{ {
FRenderStyle style = vis->RenderStyle; FRenderStyle style = vis.RenderStyle;
style.CheckFuzz(); style.CheckFuzz();
switch (style.BlendOp) switch (style.BlendOp)
{ {
@ -385,15 +376,15 @@ namespace swrenderer
} }
} }
else if (vis->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Subtract])
{ {
alpha = owner->Alpha; alpha = owner->Alpha;
} }
else if (vis->RenderStyle == LegacyRenderStyles[STYLE_Add] || else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Add] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_Translucent] || vis.RenderStyle == LegacyRenderStyles[STYLE_Translucent] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] || vis.RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_AddStencil] || vis.RenderStyle == LegacyRenderStyles[STYLE_AddStencil] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_AddShaded]) vis.RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
{ {
alpha = owner->Alpha * pspr->alpha; alpha = owner->Alpha * pspr->alpha;
} }
@ -406,10 +397,10 @@ namespace swrenderer
// Should normal renderstyle come out on top at the end and we desire alpha, // Should normal renderstyle come out on top at the end and we desire alpha,
// switch it to translucent. Normal never applies any sort of alpha. // switch it to translucent. Normal never applies any sort of alpha.
if ((pspr->Flags & PSPF_ALPHA) && if ((pspr->Flags & PSPF_ALPHA) &&
vis->RenderStyle == LegacyRenderStyles[STYLE_Normal] && vis.RenderStyle == LegacyRenderStyles[STYLE_Normal] &&
vis->Alpha < 1.0) vis.Alpha < 1.0)
{ {
vis->RenderStyle = LegacyRenderStyles[STYLE_Translucent]; vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = owner->Alpha * pspr->alpha; alpha = owner->Alpha * pspr->alpha;
} }
@ -418,22 +409,22 @@ namespace swrenderer
if (pspr->Flags & PSPF_FORCEALPHA) if (pspr->Flags & PSPF_FORCEALPHA)
{ {
//Due to lack of != operators... //Due to lack of != operators...
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] || if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] || vis.RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_Stencil]) vis.RenderStyle == LegacyRenderStyles[STYLE_Stencil])
{ {
} }
else else
{ {
alpha = pspr->alpha; alpha = pspr->alpha;
vis->RenderStyle.Flags |= STYLEF_ForceAlpha; vis.RenderStyle.Flags |= STYLEF_ForceAlpha;
} }
} }
vis->Alpha = clamp<float>(float(alpha), 0.f, 1.f); vis.Alpha = clamp<float>(float(alpha), 0.f, 1.f);
// Due to how some of the effects are handled, going to 0 or less causes some // Due to how some of the effects are handled, going to 0 or less causes some
// weirdness to display. There's no point rendering it anyway if it's 0. // weirdness to display. There's no point rendering it anyway if it's 0.
if (vis->Alpha <= 0.) if (vis.Alpha <= 0.)
return; return;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -441,60 +432,60 @@ namespace swrenderer
// The software renderer cannot invert the source without inverting the overlay // The software renderer cannot invert the source without inverting the overlay
// too. That means if the source is inverted, we need to do the reverse of what // too. That means if the source is inverted, we need to do the reverse of what
// the invert overlay flag says to do. // the invert overlay flag says to do.
bool invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay) != 0; bool invertcolormap = (vis.RenderStyle.Flags & STYLEF_InvertOverlay) != 0;
if (vis->RenderStyle.Flags & STYLEF_InvertSource) if (vis.RenderStyle.Flags & STYLEF_InvertSource)
{ {
invertcolormap = !invertcolormap; invertcolormap = !invertcolormap;
} }
bool fullbright = !vis->foggy && pspr->GetState()->GetFullbright(); bool fullbright = !foggy && pspr->GetState()->GetFullbright();
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0; bool fadeToBlack = (vis.RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
vis->SetColormap(0, spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); vis.Light.SetColormap(0, spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
colormap_to_use = (FDynamicColormap*)vis->BaseColormap; colormap_to_use = (FDynamicColormap*)vis.Light.BaseColormap;
if (camera->Inventory != nullptr) if (camera->Inventory != nullptr)
{ {
visstyle_t visstyle; visstyle_t visstyle;
visstyle.Alpha = vis->Alpha; visstyle.Alpha = vis.Alpha;
visstyle.RenderStyle = STYLE_Count; visstyle.RenderStyle = STYLE_Count;
visstyle.Invert = false; visstyle.Invert = false;
camera->Inventory->AlterWeaponSprite(&visstyle); camera->Inventory->AlterWeaponSprite(&visstyle);
vis->Alpha = visstyle.Alpha; vis.Alpha = visstyle.Alpha;
if (visstyle.RenderStyle != STYLE_Count) if (visstyle.RenderStyle != STYLE_Count)
{ {
vis->RenderStyle = visstyle.RenderStyle; vis.RenderStyle = visstyle.RenderStyle;
} }
if (visstyle.Invert) if (visstyle.Invert)
{ {
vis->BaseColormap = &SpecialColormaps[INVERSECOLORMAP]; vis.Light.BaseColormap = &SpecialColormaps[INVERSECOLORMAP];
vis->ColormapNum = 0; vis.Light.ColormapNum = 0;
noaccel = true; noaccel = true;
} }
} }
// If we're drawing with a special colormap, but shaders for them are disabled, do // If we're drawing with a special colormap, but shaders for them are disabled, do
// not accelerate. // not accelerate.
if (!r_shadercolormaps && (vis->BaseColormap >= &SpecialColormaps[0] && if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialColormaps[0] &&
vis->BaseColormap <= &SpecialColormaps.Last())) vis.Light.BaseColormap <= &SpecialColormaps.Last()))
{ {
noaccel = true; noaccel = true;
} }
// If drawing with a BOOM colormap, disable acceleration. // If drawing with a BOOM colormap, disable acceleration.
if (vis->BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps) if (vis.Light.BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps)
{ {
noaccel = true; noaccel = true;
} }
// If the main colormap has fixed lights, and this sprite is being drawn with that // If the main colormap has fixed lights, and this sprite is being drawn with that
// colormap, disable acceleration so that the lights can remain fixed. // colormap, disable acceleration so that the lights can remain fixed.
if (!noaccel && realfixedcolormap == nullptr && if (!noaccel && realfixedcolormap == nullptr &&
NormalLightHasFixedLights && vis->BaseColormap == &NormalLight && NormalLightHasFixedLights && vis.Light.BaseColormap == &NormalLight &&
vis->pic->UseBasePalette()) vis.pic->UseBasePalette())
{ {
noaccel = true; noaccel = true;
} }
@ -503,89 +494,145 @@ namespace swrenderer
{ {
colormap_to_use = basecolormap; colormap_to_use = basecolormap;
vis->BaseColormap = basecolormap; vis.Light.BaseColormap = basecolormap;
vis->ColormapNum = 0; vis.Light.ColormapNum = 0;
} }
// Check for hardware-assisted 2D. If it's available, and this sprite is not // Check for hardware-assisted 2D. If it's available, and this sprite is not
// fuzzy, don't draw it until after the switch to 2D mode. // fuzzy, don't draw it until after the switch to 2D mode.
if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D)
{ {
FRenderStyle style = vis->RenderStyle; FRenderStyle style = vis.RenderStyle;
style.CheckFuzz(); style.CheckFuzz();
if (style.BlendOp != STYLEOP_Fuzz) if (style.BlendOp != STYLEOP_Fuzz)
{ {
if (vispsprites.Size() < vispspindex + 1) HWAccelPlayerSprite accelSprite;
vispsprites.Reserve(vispsprites.Size() - vispspindex + 1);
vispsprites[vispspindex].vis = vis; accelSprite.pic = vis.pic;
vispsprites[vispspindex].basecolormap = colormap_to_use; accelSprite.texturemid = vis.texturemid;
vispsprites[vispspindex].x1 = x1; accelSprite.yscale = vis.yscale;
vispspindex++; accelSprite.xscale = vis.xscale;
accelSprite.Alpha = vis.Alpha;
accelSprite.RenderStyle = vis.RenderStyle;
accelSprite.Translation = vis.Translation;
accelSprite.FillColor = vis.FillColor;
accelSprite.basecolormap = colormap_to_use;
accelSprite.x1 = x1;
accelSprite.flip = vis.xiscale < 0;
if (vis.Light.BaseColormap >= &SpecialColormaps[0] &&
vis.Light.BaseColormap < &SpecialColormaps[SpecialColormaps.Size()])
{
accelSprite.special = static_cast<FSpecialColormap*>(vis.Light.BaseColormap);
}
else if (colormap_to_use->Color == PalEntry(255, 255, 255) &&
colormap_to_use->Desaturate == 0)
{
accelSprite.overlay = colormap_to_use->Fade;
accelSprite.overlay.a = BYTE(vis.Light.ColormapNum * 255 / NUMCOLORMAPS);
}
else
{
accelSprite.usecolormapstyle = true;
accelSprite.colormapstyle.Color = colormap_to_use->Color;
accelSprite.colormapstyle.Fade = colormap_to_use->Fade;
accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate;
accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS);
}
AcceleratedSprites.Push(accelSprite);
return; return;
} }
} }
// clip to screen bounds vis.Render();
short *mfloorclip = screenheightarray;
short *mceilingclip = zeroarray;
vis->Render(mfloorclip, mceilingclip, 0, 0);
} }
void RenderPlayerSprite::RenderRemainingPlayerSprites() void RenderPlayerSprites::RenderRemaining()
{ {
for (unsigned int i = 0; i < vispspindex; i++) for (const HWAccelPlayerSprite &sprite : AcceleratedSprites)
{ {
RenderSprite *vis = vispsprites[i].vis; screen->DrawTexture(sprite.pic,
FDynamicColormap *colormap = vispsprites[i].basecolormap; viewwindowx + sprite.x1,
bool flip = vis->xiscale < 0; viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5,
FSpecialColormap *special = NULL; DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale),
PalEntry overlay = 0; DTA_DestHeightF, sprite.pic->GetHeight() * sprite.yscale,
FColormapStyle colormapstyle; DTA_Translation, TranslationToTable(sprite.Translation),
bool usecolormapstyle = false; DTA_FlipX, sprite.flip,
if (vis->BaseColormap >= &SpecialColormaps[0] &&
vis->BaseColormap < &SpecialColormaps[SpecialColormaps.Size()])
{
special = static_cast<FSpecialColormap*>(vis->BaseColormap);
}
else if (colormap->Color == PalEntry(255, 255, 255) &&
colormap->Desaturate == 0)
{
overlay = colormap->Fade;
overlay.a = BYTE(vis->ColormapNum * 255 / NUMCOLORMAPS);
}
else
{
usecolormapstyle = true;
colormapstyle.Color = colormap->Color;
colormapstyle.Fade = colormap->Fade;
colormapstyle.Desaturate = colormap->Desaturate;
colormapstyle.FadeLevel = vis->ColormapNum / float(NUMCOLORMAPS);
}
screen->DrawTexture(vis->pic,
viewwindowx + vispsprites[i].x1,
viewwindowy + viewheight / 2 - vis->texturemid * vis->yscale - 0.5,
DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale),
DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale,
DTA_Translation, TranslationToTable(vis->Translation),
DTA_FlipX, flip,
DTA_TopOffset, 0, DTA_TopOffset, 0,
DTA_LeftOffset, 0, DTA_LeftOffset, 0,
DTA_ClipLeft, viewwindowx, DTA_ClipLeft, viewwindowx,
DTA_ClipTop, viewwindowy, DTA_ClipTop, viewwindowy,
DTA_ClipRight, viewwindowx + viewwidth, DTA_ClipRight, viewwindowx + viewwidth,
DTA_ClipBottom, viewwindowy + viewheight, DTA_ClipBottom, viewwindowy + viewheight,
DTA_AlphaF, vis->Alpha, DTA_AlphaF, sprite.Alpha,
DTA_RenderStyle, vis->RenderStyle, DTA_RenderStyle, sprite.RenderStyle,
DTA_FillColor, vis->FillColor, DTA_FillColor, sprite.FillColor,
DTA_SpecialColormap, special, DTA_SpecialColormap, sprite.special,
DTA_ColorOverlay, overlay.d, DTA_ColorOverlay, sprite.overlay.d,
DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL, DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr,
TAG_DONE); TAG_DONE);
} }
vispspindex = 0; AcceleratedSprites.Clear();
}
/////////////////////////////////////////////////////////////////////////
void NoAccelPlayerSprite::Render()
{
if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f))
{ // scaled to 0; can't see
return;
}
R_SetColorMapLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS);
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
bool visible = R_SetPatchStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap);
if (RenderStyle == LegacyRenderStyles[STYLE_Shaded])
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
// it is the brightest one. We need to get back to the proper light level for
// this sprite.
R_SetColorMapLight(drawerargs::dc_fcolormap, 0, Light.ColormapNum << FRACBITS);
}
if (!visible)
return;
double spryscale = yscale;
bool sprflipvert = false;
fixed_t iscale = FLOAT2FIXED(1 / yscale);
double sprtopscreen;
if (renderflags & RF_YFLIP)
{
sprflipvert = true;
spryscale = -spryscale;
iscale = -iscale;
sprtopscreen = CenterY + (texturemid - pic->GetHeight()) * spryscale;
}
else
{
sprflipvert = false;
sprtopscreen = CenterY - texturemid * spryscale;
}
// clip to screen bounds
short *mfloorclip = screenheightarray;
short *mceilingclip = zeroarray;
fixed_t frac = startfrac;
for (int x = x1; x < x2; x++)
{
R_DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
frac += xiscale;
}
NetUpdate();
} }
} }

View file

@ -14,41 +14,83 @@
#pragma once #pragma once
#include "r_visiblesprite.h" #include "r_visiblesprite.h"
#include "r_sprite.h" #include "r_data/colormaps.h"
class DPSprite; class DPSprite;
namespace swrenderer namespace swrenderer
{ {
class RenderPlayerSprite class NoAccelPlayerSprite
{ {
public: public:
static void SetupSpriteScale(); short x1 = 0;
short x2 = 0;
static void RenderPlayerSprites(); double texturemid = 0.0;
static void RenderRemainingPlayerSprites();
fixed_t xscale = 0;
float yscale = 0.0f;
FTexture *pic = nullptr;
fixed_t xiscale = 0;
fixed_t startfrac = 0;
float Alpha = 0.0f;
FRenderStyle RenderStyle;
uint32_t Translation = 0;
uint32_t FillColor = 0;
ColormapLight Light;
short renderflags = 0;
void Render();
};
class HWAccelPlayerSprite
{
public:
FTexture *pic = nullptr;
double texturemid = 0.0;
float yscale = 0.0f;
fixed_t xscale = 0;
float Alpha = 0.0f;
FRenderStyle RenderStyle;
uint32_t Translation = 0;
uint32_t FillColor = 0;
FDynamicColormap *basecolormap = nullptr;
int x1 = 0;
bool flip = false;
FSpecialColormap *special = nullptr;
PalEntry overlay = 0;
FColormapStyle colormapstyle;
bool usecolormapstyle = false;
};
class RenderPlayerSprites
{
public:
static RenderPlayerSprites *Instance();
void SetupSpriteScale();
void Render();
void RenderRemaining();
private: private:
static void Render(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap); void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy);
enum { BASEXCENTER = 160 }; enum { BASEXCENTER = 160 };
enum { BASEYCENTER = 100 }; enum { BASEYCENTER = 100 };
// Used to store a psprite's drawing information if it needs to be drawn later. TArray<HWAccelPlayerSprite> AcceleratedSprites;
struct vispsp_t
{
RenderSprite *vis;
FDynamicColormap *basecolormap;
int x1;
};
static TArray<vispsp_t> vispsprites; double pspritexscale = 0.0;
static unsigned int vispspindex; double pspritexiscale = 0.0;
double pspriteyscale = 0.0;
static double pspritexscale;
static double pspritexiscale;
static double pspriteyscale;
static TArray<RenderSprite> avis;
}; };
} }

View file

@ -201,7 +201,6 @@ namespace swrenderer
vis->Alpha = float(thing->Alpha); vis->Alpha = float(thing->Alpha);
vis->fakefloor = fakefloor; vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling; vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0;
//vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; //vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
//vis->bSplitSprite = false; //vis->bSplitSprite = false;
@ -224,7 +223,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0; bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
vis->SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis); VisibleSpriteList::Instance()->Push(vis);
} }
@ -237,7 +236,6 @@ namespace swrenderer
FTexture *tex; FTexture *tex;
int x2; int x2;
fixed_t xiscale; fixed_t xiscale;
bool ispsprite = (!vis->sector && vis->gpos != FVector3(0, 0, 0));
double spryscale, sprtopscreen; double spryscale, sprtopscreen;
bool sprflipvert; bool sprflipvert;
@ -248,9 +246,9 @@ namespace swrenderer
} }
fixed_t centeryfrac = FLOAT2FIXED(CenterY); fixed_t centeryfrac = FLOAT2FIXED(CenterY);
R_SetColorMapLight(vis->BaseColormap, 0, vis->ColormapNum << FRACBITS); R_SetColorMapLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap);
bool visible = R_SetPatchStyle(vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap); bool visible = R_SetPatchStyle(vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap);
@ -258,7 +256,7 @@ namespace swrenderer
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but { // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
// it is the brightest one. We need to get back to the proper light level for // it is the brightest one. We need to get back to the proper light level for
// this sprite. // this sprite.
R_SetColorMapLight(drawerargs::dc_fcolormap, 0, vis->ColormapNum << FRACBITS); R_SetColorMapLight(drawerargs::dc_fcolormap, 0, vis->Light.ColormapNum << FRACBITS);
} }
if (visible) if (visible)
@ -292,7 +290,7 @@ namespace swrenderer
{ {
while (x < x2) while (x < x2)
{ {
if (ispsprite || !RenderTranslucentPass::ClipSpriteColumnWithPortals(x, vis)) if (!RenderTranslucentPass::ClipSpriteColumnWithPortals(x, vis))
R_DrawMaskedColumn(x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); R_DrawMaskedColumn(x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
x++; x++;
frac += xiscale; frac += xiscale;

View file

@ -52,8 +52,8 @@ namespace swrenderer
int r1, r2; int r1, r2;
short topclip, botclip; short topclip, botclip;
short *clip1, *clip2; short *clip1, *clip2;
FSWColormap *colormap = spr->BaseColormap; FSWColormap *colormap = spr->Light.BaseColormap;
int colormapnum = spr->ColormapNum; int colormapnum = spr->Light.ColormapNum;
F3DFloor *rover; F3DFloor *rover;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Clip3DFloors::Instance();
@ -134,7 +134,7 @@ namespace swrenderer
int spriteshade = LIGHT2SHADE(sec->lightlevel + R_ActualExtraLight(spr->foggy)); int spriteshade = LIGHT2SHADE(sec->lightlevel + R_ActualExtraLight(spr->foggy));
SetColormap(r_SpriteVisibility / MAX(MINZ, (double)spr->depth), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack); Light.SetColormap(r_SpriteVisibility / MAX(MINZ, (double)spr->depth), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack);
} }
} }
@ -259,8 +259,8 @@ namespace swrenderer
if (topclip >= botclip) if (topclip >= botclip)
{ {
spr->BaseColormap = colormap; spr->Light.BaseColormap = colormap;
spr->ColormapNum = colormapnum; spr->Light.ColormapNum = colormapnum;
return; return;
} }
@ -386,8 +386,8 @@ namespace swrenderer
} }
if (i == x2) if (i == x2)
{ {
spr->BaseColormap = colormap; spr->Light.BaseColormap = colormap;
spr->ColormapNum = colormapnum; spr->Light.ColormapNum = colormapnum;
return; return;
} }
} }
@ -405,11 +405,11 @@ namespace swrenderer
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale); int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
spr->Render(cliptop, clipbot, minvoxely, maxvoxely); spr->Render(cliptop, clipbot, minvoxely, maxvoxely);
} }
spr->BaseColormap = colormap; spr->Light.BaseColormap = colormap;
spr->ColormapNum = colormapnum; spr->Light.ColormapNum = colormapnum;
} }
void VisibleSprite::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack) void ColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack)
{ {
if (fadeToBlack) if (fadeToBlack)
{ {

View file

@ -23,6 +23,15 @@ struct FSWColormap;
namespace swrenderer namespace swrenderer
{ {
class ColormapLight
{
public:
int ColormapNum = 0;
FSWColormap *BaseColormap = nullptr;
void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack);
};
class VisibleSprite class VisibleSprite
{ {
public: public:
@ -38,8 +47,6 @@ namespace swrenderer
float SortDist() const { return idepth; } float SortDist() const { return idepth; }
protected: protected:
void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack);
virtual bool IsParticle() const { return false; } virtual bool IsParticle() const { return false; }
virtual bool IsVoxel() const { return false; } virtual bool IsVoxel() const { return false; }
virtual bool IsWallSprite() const { return false; } virtual bool IsWallSprite() const { return false; }
@ -65,9 +72,7 @@ namespace swrenderer
FVector3 gpos = { 0.0f, 0.0f, 0.0f }; // origin in world coordinates FVector3 gpos = { 0.0f, 0.0f, 0.0f }; // origin in world coordinates
sector_t *sector = nullptr; // sector this sprite is in sector_t *sector = nullptr; // sector this sprite is in
// Light shared calculation? ColormapLight Light;
int ColormapNum = 0; // Which colormap is rendered
FSWColormap *BaseColormap = nullptr; // Base colormap used together with ColormapNum
float Alpha = 0.0f; float Alpha = 0.0f;
FRenderStyle RenderStyle; FRenderStyle RenderStyle;
bool foggy = false; bool foggy = false;

View file

@ -149,7 +149,7 @@ namespace swrenderer
vis->Alpha = float(thing->Alpha); vis->Alpha = float(thing->Alpha);
vis->fakefloor = fakefloor; vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling; vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0; vis->Light.ColormapNum = 0;
//vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; //vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
//vis->bSplitSprite = false; //vis->bSplitSprite = false;
@ -175,7 +175,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0; bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
vis->SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis); VisibleSpriteList::Instance()->Push(vis);
RenderTranslucentPass::DrewAVoxel = true; RenderTranslucentPass::DrewAVoxel = true;
@ -185,9 +185,9 @@ namespace swrenderer
{ {
auto sprite = this; auto sprite = this;
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(sprite->BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(sprite->Light.BaseColormap);
R_SetColorMapLight(sprite->BaseColormap, 0, sprite->ColormapNum << FRACBITS); R_SetColorMapLight(sprite->Light.BaseColormap, 0, sprite->Light.ColormapNum << FRACBITS);
bool visible = R_SetPatchStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap); bool visible = R_SetPatchStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap);
if (!visible) if (!visible)

View file

@ -132,7 +132,7 @@ namespace swrenderer
vis->wallc = wallc; vis->wallc = wallc;
vis->foggy = foggy; vis->foggy = foggy;
vis->SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false); vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false);
VisibleSpriteList::Instance()->Push(vis); VisibleSpriteList::Instance()->Push(vis);
} }
@ -165,7 +165,7 @@ namespace swrenderer
} }
// Prepare lighting // Prepare lighting
bool calclighting = false; bool calclighting = false;
FSWColormap *usecolormap = spr->BaseColormap; FSWColormap *usecolormap = spr->Light.BaseColormap;
bool rereadcolormap = true; bool rereadcolormap = true;
// Decals that are added to the scene must fade to black. // Decals that are added to the scene must fade to black.
@ -206,14 +206,14 @@ namespace swrenderer
int x = x1; int x = x1;
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->Light.BaseColormap);
bool visible = R_SetPatchStyle(spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap); bool visible = R_SetPatchStyle(spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap);
// R_SetPatchStyle can modify basecolormap. // R_SetPatchStyle can modify basecolormap.
if (rereadcolormap) if (rereadcolormap)
{ {
usecolormap = spr->BaseColormap; usecolormap = spr->Light.BaseColormap;
} }
if (!visible) if (!visible)