From ba6094be2e90436ce23ba1b2494f1ecb9c6962ff Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 24 Jan 2017 04:15:54 +0100 Subject: [PATCH] Detach player sprites from VisibleSprite --- src/swrenderer/drawers/r_draw.cpp | 2 +- src/swrenderer/r_swrenderer.cpp | 2 +- src/swrenderer/scene/r_translucent_pass.cpp | 3 +- src/swrenderer/scene/r_viewport.cpp | 2 +- src/swrenderer/things/r_particle.cpp | 7 +- src/swrenderer/things/r_playersprite.cpp | 313 +++++++++++--------- src/swrenderer/things/r_playersprite.h | 84 ++++-- src/swrenderer/things/r_sprite.cpp | 12 +- src/swrenderer/things/r_visiblesprite.cpp | 20 +- src/swrenderer/things/r_visiblesprite.h | 15 +- src/swrenderer/things/r_voxel.cpp | 8 +- src/swrenderer/things/r_wallsprite.cpp | 8 +- 12 files changed, 284 insertions(+), 192 deletions(-) diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp index 46c0ec784..cf3e4edbb 100644 --- a/src/swrenderer/drawers/r_draw.cpp +++ b/src/swrenderer/drawers/r_draw.cpp @@ -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; diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index db0ede2e6..e8e1d2c12 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -217,7 +217,7 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites() { if (!r_polyrenderer) { - RenderPlayerSprite::RenderRemainingPlayerSprites(); + RenderPlayerSprites::Instance()->RenderRemaining(); } else { diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index cbacf11e1..3cf4998f1 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -208,6 +208,7 @@ namespace swrenderer clip3d->DeleteHeights(); clip3d->fake3D = 0; } - RenderPlayerSprite::RenderPlayerSprites(); + + RenderPlayerSprites::Instance()->Render(); } } diff --git a/src/swrenderer/scene/r_viewport.cpp b/src/swrenderer/scene/r_viewport.cpp index df5b37f08..c92509492 100644 --- a/src/swrenderer/scene/r_viewport.cpp +++ b/src/swrenderer/scene/r_viewport.cpp @@ -114,7 +114,7 @@ namespace swrenderer WallTMapScale2 = IYaspectMul / CenterX; // psprite scales - RenderPlayerSprite::SetupSpriteScale(); + RenderPlayerSprites::Instance()->SetupSpriteScale(); // thing clipping fillshort(screenheightarray, viewwidth, (short)viewheight); diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index ed32c2a00..775e9358e 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -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; diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index a259ff1b3..69da6b947 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -65,23 +65,20 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) namespace swrenderer { - TArray RenderPlayerSprite::vispsprites; - unsigned int RenderPlayerSprite::vispspindex; + RenderPlayerSprites *RenderPlayerSprites::Instance() + { + static RenderPlayerSprites instance; + return &instance; + } - double RenderPlayerSprite::pspritexscale; - double RenderPlayerSprite::pspritexiscale; - double RenderPlayerSprite::pspriteyscale; - - TArray 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(alpha), 0.f, 1.f); + vis.Alpha = clamp(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(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(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(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(); } } diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 75a4e7ba6..b12bbd8d3 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -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 AcceleratedSprites; - static TArray vispsprites; - static unsigned int vispspindex; - - static double pspritexscale; - static double pspritexiscale; - static double pspriteyscale; - - static TArray avis; + double pspritexscale = 0.0; + double pspritexiscale = 0.0; + double pspriteyscale = 0.0; }; } diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index d237348f4..1c91c75b0 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -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(vis->BaseColormap); + FDynamicColormap *basecolormap = static_cast(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; diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index 5007cd10d..73cf909f4 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -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) { diff --git a/src/swrenderer/things/r_visiblesprite.h b/src/swrenderer/things/r_visiblesprite.h index bfe8a84e0..edc83667e 100644 --- a/src/swrenderer/things/r_visiblesprite.h +++ b/src/swrenderer/things/r_visiblesprite.h @@ -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; diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 7706da69b..a4b44e008 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -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(sprite->BaseColormap); + FDynamicColormap *basecolormap = static_cast(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) diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 44477c1e1..76691e07d 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -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(spr->BaseColormap); + FDynamicColormap *basecolormap = static_cast(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)