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])
{
// Shaded drawer only gets 16 levels of alpha because it saves memory.
if ((alpha >>= 12) == 0)
if ((alpha >>= 12) == 0 || basecolormap == nullptr)
return false;
colfunc = &SWPixelFormatDrawers::DrawShadedColumn;
drawer_needs_pal_input = true;

View file

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

View file

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

View file

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

View file

@ -198,11 +198,10 @@ namespace swrenderer
vis->renderflags = (short)(particle->alpha * 255.0f + 0.5f);
vis->FakeFlatStat = fakeside;
vis->floorclip = 0;
vis->ColormapNum = 0;
vis->foggy = foggy;
// 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);
}
@ -214,7 +213,7 @@ namespace swrenderer
auto vis = this;
int spacing;
BYTE color = vis->BaseColormap->Maps[vis->startfrac];
BYTE color = vis->Light.BaseColormap->Maps[vis->startfrac];
int yl = vis->y1;
int ycount = vis->y2 - yl + 1;
int x1 = vis->x1;
@ -225,7 +224,7 @@ namespace swrenderer
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)
fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;

View file

@ -65,23 +65,20 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer
{
TArray<RenderPlayerSprite::vispsp_t> RenderPlayerSprite::vispsprites;
unsigned int RenderPlayerSprite::vispspindex;
RenderPlayerSprites *RenderPlayerSprites::Instance()
{
static RenderPlayerSprites instance;
return &instance;
}
double RenderPlayerSprite::pspritexscale;
double RenderPlayerSprite::pspritexiscale;
double RenderPlayerSprite::pspriteyscale;
TArray<RenderSprite> RenderPlayerSprite::avis;
void RenderPlayerSprite::SetupSpriteScale()
void RenderPlayerSprites::SetupSpriteScale()
{
pspritexscale = centerxwide / 160.0;
pspriteyscale = pspritexscale * YaspectMul;
pspritexiscale = 1 / pspritexscale;
}
void RenderPlayerSprite::RenderPlayerSprites()
void RenderPlayerSprites::Render()
{
int i;
int lightnum;
@ -184,7 +181,7 @@ namespace swrenderer
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();
@ -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;
int x1;
@ -208,9 +205,6 @@ namespace swrenderer
bool noaccel;
double alpha = owner->Alpha;
if (avis.Size() < vispspindex + 1)
avis.Reserve(avis.Size() - vispspindex + 1);
// decide which patch to use
if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size())
{
@ -272,12 +266,11 @@ namespace swrenderer
return;
// store information in a vissprite
RenderSprite *vis = &avis[vispspindex];
NoAccelPlayerSprite vis;
vis->renderflags = owner->renderflags;
vis->floorclip = 0;
vis.renderflags = owner->renderflags;
vis->texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
if (camera->player && (RenderTarget != screen ||
viewheight == RenderTarget->GetHeight() ||
@ -288,41 +281,39 @@ namespace swrenderer
{
if (RenderTarget != screen || viewheight == RenderTarget->GetHeight())
{
vis->texturemid -= weapon->YAdjust;
vis.texturemid -= weapon->YAdjust;
}
else
{
vis->texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust;
vis.texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust;
}
}
}
if (pspr->GetID() < PSP_TARGETCENTER)
{ // Move the weapon down for 1280x1024.
vis->texturemid -= AspectPspriteOffset(WidescreenRatio);
vis.texturemid -= AspectPspriteOffset(WidescreenRatio);
}
vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth : x2;
vis->xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X);
vis->yscale = float(pspriteyscale / tex->Scale.Y);
vis->Translation = 0; // [RH] Use default colors
vis->pic = tex;
vis->ColormapNum = 0;
vis.x1 = x1 < 0 ? 0 : x1;
vis.x2 = x2 >= viewwidth ? viewwidth : x2;
vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X);
vis.yscale = float(pspriteyscale / tex->Scale.Y);
vis.pic = tex;
// If flip is used, provided that it's not already flipped (that would just invert itself)
// (It's an XOR...)
if (!(flip) != !(pspr->Flags & PSPF_FLIP))
{
vis->xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis.startfrac = (tex->GetWidth() << FRACBITS) - 1;
}
else
{
vis->xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis->startfrac = 0;
vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X);
vis.startfrac = 0;
}
if (vis->x1 > x1)
vis->startfrac += vis->xiscale*(vis->x1 - x1);
if (vis.x1 > x1)
vis.startfrac += vis.xiscale*(vis.x1 - x1);
noaccel = false;
FDynamicColormap *colormap_to_use = nullptr;
@ -336,42 +327,42 @@ namespace swrenderer
if (pspr->Flags & PSPF_FORCESTYLE)
{
vis->RenderStyle = LegacyRenderStyles[rs];
vis.RenderStyle = LegacyRenderStyles[rs];
}
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
{
vis->RenderStyle = LegacyRenderStyles[STYLE_Fuzzy];
vis.RenderStyle = LegacyRenderStyles[STYLE_Fuzzy];
}
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])
{
vis->RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy];
vis->RenderStyle.CheckFuzz();
vis.RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy];
vis.RenderStyle.CheckFuzz();
}
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
{
vis->RenderStyle = LegacyRenderStyles[STYLE_Subtract];
vis.RenderStyle = LegacyRenderStyles[STYLE_Subtract];
}
else
{
vis->RenderStyle = LegacyRenderStyles[rs];
vis.RenderStyle = LegacyRenderStyles[rs];
}
}
else
{
vis->RenderStyle = owner->RenderStyle;
vis.RenderStyle = owner->RenderStyle;
}
// Set the alpha based on if using the overlay's own or not. Also adjust
// and override the alpha if not forced.
if (pspr->Flags & PSPF_ALPHA)
{
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
{
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();
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;
}
else if (vis->RenderStyle == LegacyRenderStyles[STYLE_Add] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_Translucent] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_AddStencil] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Add] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_Translucent] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_AddStencil] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
{
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,
// switch it to translucent. Normal never applies any sort of alpha.
if ((pspr->Flags & PSPF_ALPHA) &&
vis->RenderStyle == LegacyRenderStyles[STYLE_Normal] &&
vis->Alpha < 1.0)
vis.RenderStyle == LegacyRenderStyles[STYLE_Normal] &&
vis.Alpha < 1.0)
{
vis->RenderStyle = LegacyRenderStyles[STYLE_Translucent];
vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = owner->Alpha * pspr->alpha;
}
@ -418,22 +409,22 @@ namespace swrenderer
if (pspr->Flags & PSPF_FORCEALPHA)
{
//Due to lack of != operators...
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] ||
vis->RenderStyle == LegacyRenderStyles[STYLE_Stencil])
if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] ||
vis.RenderStyle == LegacyRenderStyles[STYLE_Stencil])
{
}
else
{
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
// weirdness to display. There's no point rendering it anyway if it's 0.
if (vis->Alpha <= 0.)
if (vis.Alpha <= 0.)
return;
//-----------------------------------------------------------------------------
@ -441,60 +432,60 @@ namespace swrenderer
// 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
// 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;
}
bool fullbright = !vis->foggy && pspr->GetState()->GetFullbright();
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
bool fullbright = !foggy && pspr->GetState()->GetFullbright();
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)
{
visstyle_t visstyle;
visstyle.Alpha = vis->Alpha;
visstyle.Alpha = vis.Alpha;
visstyle.RenderStyle = STYLE_Count;
visstyle.Invert = false;
camera->Inventory->AlterWeaponSprite(&visstyle);
vis->Alpha = visstyle.Alpha;
vis.Alpha = visstyle.Alpha;
if (visstyle.RenderStyle != STYLE_Count)
{
vis->RenderStyle = visstyle.RenderStyle;
vis.RenderStyle = visstyle.RenderStyle;
}
if (visstyle.Invert)
{
vis->BaseColormap = &SpecialColormaps[INVERSECOLORMAP];
vis->ColormapNum = 0;
vis.Light.BaseColormap = &SpecialColormaps[INVERSECOLORMAP];
vis.Light.ColormapNum = 0;
noaccel = true;
}
}
// If we're drawing with a special colormap, but shaders for them are disabled, do
// not accelerate.
if (!r_shadercolormaps && (vis->BaseColormap >= &SpecialColormaps[0] &&
vis->BaseColormap <= &SpecialColormaps.Last()))
if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialColormaps[0] &&
vis.Light.BaseColormap <= &SpecialColormaps.Last()))
{
noaccel = true;
}
// 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;
}
// 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.
if (!noaccel && realfixedcolormap == nullptr &&
NormalLightHasFixedLights && vis->BaseColormap == &NormalLight &&
vis->pic->UseBasePalette())
NormalLightHasFixedLights && vis.Light.BaseColormap == &NormalLight &&
vis.pic->UseBasePalette())
{
noaccel = true;
}
@ -503,89 +494,145 @@ namespace swrenderer
{
colormap_to_use = basecolormap;
vis->BaseColormap = basecolormap;
vis->ColormapNum = 0;
vis.Light.BaseColormap = basecolormap;
vis.Light.ColormapNum = 0;
}
// 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.
if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D)
{
FRenderStyle style = vis->RenderStyle;
FRenderStyle style = vis.RenderStyle;
style.CheckFuzz();
if (style.BlendOp != STYLEOP_Fuzz)
{
if (vispsprites.Size() < vispspindex + 1)
vispsprites.Reserve(vispsprites.Size() - vispspindex + 1);
HWAccelPlayerSprite accelSprite;
vispsprites[vispspindex].vis = vis;
vispsprites[vispspindex].basecolormap = colormap_to_use;
vispsprites[vispspindex].x1 = x1;
vispspindex++;
accelSprite.pic = vis.pic;
accelSprite.texturemid = vis.texturemid;
accelSprite.yscale = vis.yscale;
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;
}
}
// clip to screen bounds
short *mfloorclip = screenheightarray;
short *mceilingclip = zeroarray;
vis->Render(mfloorclip, mceilingclip, 0, 0);
vis.Render();
}
void RenderPlayerSprite::RenderRemainingPlayerSprites()
void RenderPlayerSprites::RenderRemaining()
{
for (unsigned int i = 0; i < vispspindex; i++)
for (const HWAccelPlayerSprite &sprite : AcceleratedSprites)
{
RenderSprite *vis = vispsprites[i].vis;
FDynamicColormap *colormap = vispsprites[i].basecolormap;
bool flip = vis->xiscale < 0;
FSpecialColormap *special = NULL;
PalEntry overlay = 0;
FColormapStyle colormapstyle;
bool usecolormapstyle = false;
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,
screen->DrawTexture(sprite.pic,
viewwindowx + sprite.x1,
viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5,
DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale),
DTA_DestHeightF, sprite.pic->GetHeight() * sprite.yscale,
DTA_Translation, TranslationToTable(sprite.Translation),
DTA_FlipX, sprite.flip,
DTA_TopOffset, 0,
DTA_LeftOffset, 0,
DTA_ClipLeft, viewwindowx,
DTA_ClipTop, viewwindowy,
DTA_ClipRight, viewwindowx + viewwidth,
DTA_ClipBottom, viewwindowy + viewheight,
DTA_AlphaF, vis->Alpha,
DTA_RenderStyle, vis->RenderStyle,
DTA_FillColor, vis->FillColor,
DTA_SpecialColormap, special,
DTA_ColorOverlay, overlay.d,
DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL,
DTA_AlphaF, sprite.Alpha,
DTA_RenderStyle, sprite.RenderStyle,
DTA_FillColor, sprite.FillColor,
DTA_SpecialColormap, sprite.special,
DTA_ColorOverlay, sprite.overlay.d,
DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr,
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
#include "r_visiblesprite.h"
#include "r_sprite.h"
#include "r_data/colormaps.h"
class DPSprite;
namespace swrenderer
{
class RenderPlayerSprite
class NoAccelPlayerSprite
{
public:
static void SetupSpriteScale();
short x1 = 0;
short x2 = 0;
static void RenderPlayerSprites();
static void RenderRemainingPlayerSprites();
double texturemid = 0.0;
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:
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 { BASEYCENTER = 100 };
// Used to store a psprite's drawing information if it needs to be drawn later.
struct vispsp_t
{
RenderSprite *vis;
FDynamicColormap *basecolormap;
int x1;
};
TArray<HWAccelPlayerSprite> AcceleratedSprites;
static TArray<vispsp_t> vispsprites;
static unsigned int vispspindex;
static double pspritexscale;
static double pspritexiscale;
static double pspriteyscale;
static TArray<RenderSprite> avis;
double pspritexscale = 0.0;
double pspritexiscale = 0.0;
double pspriteyscale = 0.0;
};
}

View file

@ -201,7 +201,6 @@ namespace swrenderer
vis->Alpha = float(thing->Alpha);
vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0;
//vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
//vis->bSplitSprite = false;
@ -224,7 +223,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
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);
}
@ -237,7 +236,6 @@ namespace swrenderer
FTexture *tex;
int x2;
fixed_t xiscale;
bool ispsprite = (!vis->sector && vis->gpos != FVector3(0, 0, 0));
double spryscale, sprtopscreen;
bool sprflipvert;
@ -248,9 +246,9 @@ namespace swrenderer
}
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);
@ -258,7 +256,7 @@ namespace swrenderer
{ // 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, vis->ColormapNum << FRACBITS);
R_SetColorMapLight(drawerargs::dc_fcolormap, 0, vis->Light.ColormapNum << FRACBITS);
}
if (visible)
@ -292,7 +290,7 @@ namespace swrenderer
{
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);
x++;
frac += xiscale;

View file

@ -52,8 +52,8 @@ namespace swrenderer
int r1, r2;
short topclip, botclip;
short *clip1, *clip2;
FSWColormap *colormap = spr->BaseColormap;
int colormapnum = spr->ColormapNum;
FSWColormap *colormap = spr->Light.BaseColormap;
int colormapnum = spr->Light.ColormapNum;
F3DFloor *rover;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
@ -134,7 +134,7 @@ namespace swrenderer
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)
{
spr->BaseColormap = colormap;
spr->ColormapNum = colormapnum;
spr->Light.BaseColormap = colormap;
spr->Light.ColormapNum = colormapnum;
return;
}
@ -386,8 +386,8 @@ namespace swrenderer
}
if (i == x2)
{
spr->BaseColormap = colormap;
spr->ColormapNum = colormapnum;
spr->Light.BaseColormap = colormap;
spr->Light.ColormapNum = colormapnum;
return;
}
}
@ -405,11 +405,11 @@ namespace swrenderer
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
spr->Render(cliptop, clipbot, minvoxely, maxvoxely);
}
spr->BaseColormap = colormap;
spr->ColormapNum = colormapnum;
spr->Light.BaseColormap = colormap;
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)
{

View file

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

View file

@ -149,7 +149,7 @@ namespace swrenderer
vis->Alpha = float(thing->Alpha);
vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0;
vis->Light.ColormapNum = 0;
//vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
//vis->bSplitSprite = false;
@ -175,7 +175,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
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);
RenderTranslucentPass::DrewAVoxel = true;
@ -185,9 +185,9 @@ namespace swrenderer
{
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);
if (!visible)

View file

@ -132,7 +132,7 @@ namespace swrenderer
vis->wallc = wallc;
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);
}
@ -165,7 +165,7 @@ namespace swrenderer
}
// Prepare lighting
bool calclighting = false;
FSWColormap *usecolormap = spr->BaseColormap;
FSWColormap *usecolormap = spr->Light.BaseColormap;
bool rereadcolormap = true;
// Decals that are added to the scene must fade to black.
@ -206,14 +206,14 @@ namespace swrenderer
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);
// R_SetPatchStyle can modify basecolormap.
if (rereadcolormap)
{
usecolormap = spr->BaseColormap;
usecolormap = spr->Light.BaseColormap;
}
if (!visible)