diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index f7facda887..e6fa8ea4d0 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -19,8 +19,6 @@ EXTERN_CVAR(Bool, r_dynlights); namespace swrenderer { - struct vissprite_t; - struct ShadeConstants { uint16_t light_alpha; diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index 591b57588b..252c31f561 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -90,7 +90,7 @@ namespace swrenderer } } - bool RenderTranslucentPass::ClipSpriteColumnWithPortals(int x, vissprite_t* spr) + bool RenderTranslucentPass::ClipSpriteColumnWithPortals(int x, VisibleSprite *spr) { RenderPortal *renderportal = RenderPortal::Instance(); @@ -118,7 +118,7 @@ namespace swrenderer return false; } - void RenderTranslucentPass::DrawSprite(vissprite_t *spr) + void RenderTranslucentPass::DrawSprite(VisibleSprite *spr) { static short clipbot[MAXWIDTH]; static short cliptop[MAXWIDTH]; @@ -136,12 +136,13 @@ namespace swrenderer Clip3DFloors *clip3d = Clip3DFloors::Instance(); // [RH] Check for particles - if (!spr->bIsVoxel && spr->pic == nullptr) + if (spr->IsParticle()) { // kg3D - reject invisible parts if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return; if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return; - RenderParticle::Render(spr); + + spr->Render(nullptr, nullptr, 0, 0); return; } @@ -258,7 +259,7 @@ namespace swrenderer double scale = InvZtoScale * spr->idepth; double hzb = DBL_MIN, hzt = DBL_MAX; - if (spr->bIsVoxel && spr->floorclip != 0) + if (spr->IsVoxel() && spr->floorclip != 0) { hzb = spr->gzb; } @@ -272,7 +273,7 @@ namespace swrenderer if (spr->FakeFlatStat == WaterFakeSide::BelowFloor) { // seen below floor: clip top - if (!spr->bIsVoxel && h > topclip) + if (!spr->IsVoxel() && h > topclip) { topclip = short(MIN(h, viewheight)); } @@ -280,7 +281,7 @@ namespace swrenderer } else { // seen in the middle: clip bottom - if (!spr->bIsVoxel && h < botclip) + if (!spr->IsVoxel() && h < botclip) { botclip = MAX(0, h); } @@ -294,7 +295,7 @@ namespace swrenderer if (spr->FakeFlatStat == WaterFakeSide::AboveCeiling) { // seen above ceiling: clip bottom - if (!spr->bIsVoxel && h < botclip) + if (!spr->IsVoxel() && h < botclip) { botclip = MAX(0, h); } @@ -302,7 +303,7 @@ namespace swrenderer } else { // seen in the middle: clip top - if (!spr->bIsVoxel && h > topclip) + if (!spr->IsVoxel() && h > topclip) { topclip = MIN(h, viewheight); } @@ -311,7 +312,7 @@ namespace swrenderer } } // killough 3/27/98: end special clipping for deep water / fake ceilings - else if (!spr->bIsVoxel && spr->floorclip) + else if (!spr->IsVoxel() && spr->floorclip) { // [RH] Move floorclip stuff from R_DrawVisSprite to here //int clip = ((FLOAT2FIXED(CenterY) - FixedMul (spr->texturemid - (spr->pic->GetHeight() << FRACBITS) + spr->floorclip, spr->yscale)) >> FRACBITS); int clip = xs_RoundToInt(CenterY - (spr->texturemid - spr->pic->GetHeight() + spr->floorclip) * spr->yscale); @@ -323,7 +324,7 @@ namespace swrenderer if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) { - if (!spr->bIsVoxel) + if (!spr->IsVoxel()) { double hz = clip3d->sclipBottom; if (spr->fakefloor) @@ -344,7 +345,7 @@ namespace swrenderer } if (clip3d->fake3D & FAKE3D_CLIPTOP) { - if (!spr->bIsVoxel) + if (!spr->IsVoxel()) { double hz = clip3d->sclipTop; if (spr->fakeceiling != nullptr) @@ -411,7 +412,7 @@ namespace swrenderer r2 = MIN(ds->x2, x2); float neardepth, fardepth; - if (!spr->bWallSprite) + if (!spr->IsWallSprite()) { if (ds->sz1 < ds->sz2) { @@ -425,7 +426,7 @@ namespace swrenderer // Check if sprite is in front of draw seg: - if ((!spr->bWallSprite && neardepth > spr->depth) || ((spr->bWallSprite || fardepth > spr->depth) && + if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) && (spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) - (spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0)) { @@ -475,16 +476,9 @@ namespace swrenderer // all clipping has been performed, so draw the sprite - if (!spr->bIsVoxel) + if (!spr->IsVoxel()) { - if (!spr->bWallSprite) - { - RenderSprite::Render(spr, clipbot, cliptop); - } - else - { - RenderWallSprite::Render(spr, clipbot, cliptop); - } + spr->Render(clipbot, cliptop, 0, 0); } else { @@ -517,7 +511,7 @@ namespace swrenderer } int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale); int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale); - RenderVoxel::Render(spr, minvoxely, maxvoxely, cliptop, clipbot); + spr->Render(cliptop, clipbot, minvoxely, maxvoxely); } spr->Style.BaseColormap = colormap; spr->Style.ColormapNum = colormapnum; diff --git a/src/swrenderer/scene/r_translucent_pass.h b/src/swrenderer/scene/r_translucent_pass.h index 359a5002d6..2e94198b64 100644 --- a/src/swrenderer/scene/r_translucent_pass.h +++ b/src/swrenderer/scene/r_translucent_pass.h @@ -22,7 +22,7 @@ struct FVoxel; namespace swrenderer { - struct vissprite_t; + class VisibleSprite; struct drawseg_t; class RenderTranslucentPass @@ -34,11 +34,11 @@ namespace swrenderer static bool DrewAVoxel; - static bool ClipSpriteColumnWithPortals(int x, vissprite_t* spr); + static bool ClipSpriteColumnWithPortals(int x, VisibleSprite *spr); private: static void CollectPortals(); - static void DrawSprite(vissprite_t *spr); + static void DrawSprite(VisibleSprite *spr); static void DrawMaskedSingle(bool renew); static TArray portaldrawsegs; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 60363e9807..3620c916b0 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -178,7 +178,7 @@ namespace swrenderer return; // store information in a vissprite - vissprite_t *vis = RenderMemory::NewObject(); + RenderParticle *vis = RenderMemory::NewObject(); vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->heightsec = heightsec; vis->xscale = FLOAT2FIXED(xscale); @@ -194,7 +194,6 @@ namespace swrenderer vis->Translation = 0; vis->startfrac = 255 & (particle->color >> 24); vis->pic = NULL; - vis->bIsVoxel = false; vis->renderflags = (short)(particle->alpha * 255.0f + 0.5f); vis->FakeFlatStat = fakeside; vis->floorclip = 0; @@ -226,10 +225,12 @@ namespace swrenderer VisibleSpriteList::Instance()->Push(vis); } - void RenderParticle::Render(vissprite_t *vis) + void RenderParticle::Render(short *cliptop, short *clipbottom, int minZ, int maxZ) { using namespace drawerargs; + auto vis = this; + int spacing; BYTE color = vis->Style.BaseColormap->Maps[vis->startfrac]; int yl = vis->y1; @@ -240,7 +241,7 @@ namespace swrenderer if (ycount <= 0 || countbase <= 0) return; - DrawMaskedSegsBehindParticle(vis); + DrawMaskedSegsBehindParticle(); uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Style.ColormapNum << FRACBITS))); @@ -275,11 +276,8 @@ namespace swrenderer } } - void RenderParticle::DrawMaskedSegsBehindParticle(const vissprite_t *vis) + void RenderParticle::DrawMaskedSegsBehindParticle() { - const int x1 = vis->x1; - const int x2 = vis->x2; - // Draw any masked textures behind this particle so that when the // particle is drawn, it will be in front of them. for (unsigned int p = InterestingDrawsegs.Size(); p-- > FirstInterestingDrawseg; ) @@ -291,10 +289,10 @@ namespace swrenderer { continue; } - if ((ds->siz2 - ds->siz1) * ((x2 + x1) / 2 - ds->sx1) / (ds->sx2 - ds->sx1) + ds->siz1 < vis->idepth) + if ((ds->siz2 - ds->siz1) * ((x2 + x1) / 2 - ds->sx1) / (ds->sx2 - ds->sx1) + ds->siz1 < idepth) { // [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves - if (ds->CurrentPortalUniq == vis->CurrentPortalUniq) + if (ds->CurrentPortalUniq == CurrentPortalUniq) R_RenderMaskedSegRange(ds, MAX(ds->x1, x1), MIN(ds->x2, x2)); } } diff --git a/src/swrenderer/things/r_particle.h b/src/swrenderer/things/r_particle.h index d8aa2952a7..964b2ac164 100644 --- a/src/swrenderer/things/r_particle.h +++ b/src/swrenderer/things/r_particle.h @@ -18,13 +18,22 @@ namespace swrenderer { - class RenderParticle + class RenderParticle : public VisibleSprite { public: static void Project(particle_t *, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy); - static void Render(vissprite_t *); + + bool IsParticle() const override { return true; } + void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; private: - static void DrawMaskedSegsBehindParticle(const vissprite_t *vis); + void DrawMaskedSegsBehindParticle(); + + fixed_t xscale; + fixed_t startfrac; // horizontal position of x1 + int y1, y2; + + uint32_t Translation; + uint32_t FillColor; }; } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index b94ce19417..0632af0741 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -72,7 +72,7 @@ namespace swrenderer double RenderPlayerSprite::pspritexiscale; double RenderPlayerSprite::pspriteyscale; - TArray RenderPlayerSprite::avis; + TArray RenderPlayerSprite::avis; void RenderPlayerSprite::SetupSpriteScale() { @@ -205,7 +205,6 @@ namespace swrenderer FTextureID picnum; WORD flip; FTexture* tex; - vissprite_t* vis; bool noaccel; double alpha = owner->Alpha; @@ -273,7 +272,7 @@ namespace swrenderer return; // store information in a vissprite - vis = &avis[vispspindex]; + RenderSprite *vis = &avis[vispspindex]; vis->renderflags = owner->renderflags; vis->floorclip = 0; @@ -571,16 +570,14 @@ namespace swrenderer short *mfloorclip = screenheightarray; short *mceilingclip = zeroarray; - RenderSprite::Render(vis, mfloorclip, mceilingclip); + vis->Render(mfloorclip, mceilingclip, 0, 0); } void RenderPlayerSprite::RenderRemainingPlayerSprites() { for (unsigned int i = 0; i < vispspindex; i++) { - vissprite_t *vis; - - vis = vispsprites[i].vis; + RenderSprite *vis = vispsprites[i].vis; FDynamicColormap *colormap = vispsprites[i].basecolormap; bool flip = vis->xiscale < 0; FSpecialColormap *special = NULL; diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index b1eebe4310..75a4e7ba67 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -14,6 +14,7 @@ #pragma once #include "r_visiblesprite.h" +#include "r_sprite.h" class DPSprite; @@ -36,7 +37,7 @@ namespace swrenderer // Used to store a psprite's drawing information if it needs to be drawn later. struct vispsp_t { - vissprite_t *vis; + RenderSprite *vis; FDynamicColormap *basecolormap; int x1; }; @@ -48,6 +49,6 @@ namespace swrenderer static double pspritexiscale; static double pspriteyscale; - static TArray avis; + static TArray avis; }; } diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index d1c55165fa..95c95a208d 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -156,7 +156,7 @@ namespace swrenderer double yscale = spriteScale.Y / tex->Scale.Y; // store information in a vissprite - vissprite_t *vis = RenderMemory::NewObject(); + RenderSprite *vis = RenderMemory::NewObject(); vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); @@ -166,7 +166,7 @@ namespace swrenderer vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale; vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1; vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2; - vis->Angle = thing->Angles.Yaw; + //vis->Angle = thing->Angles.Yaw; if (renderflags & RF_XFLIP) { @@ -202,12 +202,10 @@ namespace swrenderer vis->fakefloor = fakefloor; vis->fakeceiling = fakeceiling; vis->Style.ColormapNum = 0; - vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; - vis->bSplitSprite = false; + //vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; + //vis->bSplitSprite = false; vis->pic = tex; - vis->bIsVoxel = false; - vis->bWallSprite = false; vis->foggy = foggy; @@ -278,8 +276,10 @@ namespace swrenderer VisibleSpriteList::Instance()->Push(vis); } - void RenderSprite::Render(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip) + void RenderSprite::Render(short *mfloorclip, short *mceilingclip, int, int) { + auto vis = this; + fixed_t frac; FTexture *tex; int x2; diff --git a/src/swrenderer/things/r_sprite.h b/src/swrenderer/things/r_sprite.h index 7c5a68a078..d45fd39550 100644 --- a/src/swrenderer/things/r_sprite.h +++ b/src/swrenderer/things/r_sprite.h @@ -17,10 +17,21 @@ namespace swrenderer { - class RenderSprite + class RenderSprite : public VisibleSprite { public: static void Project(AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); - static void Render(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip); + + void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; + + private: + fixed_t xscale; + fixed_t startfrac; // horizontal position of x1 + fixed_t xiscale; // negative if flipped + + uint32_t Translation; + uint32_t FillColor; + + friend class RenderPlayerSprite; // To do: detach sprite from playersprite! }; } diff --git a/src/swrenderer/things/r_visiblesprite.h b/src/swrenderer/things/r_visiblesprite.h index b7718991d1..95b8028b1c 100644 --- a/src/swrenderer/things/r_visiblesprite.h +++ b/src/swrenderer/things/r_visiblesprite.h @@ -24,70 +24,44 @@ struct FVoxel; namespace swrenderer { - struct vissprite_t + class VisibleSprite { - struct posang - { - FVector3 vpos; // view origin - FAngle vang; // view angle - }; + public: + virtual bool IsParticle() const { return false; } + virtual bool IsVoxel() const { return false; } + virtual bool IsWallSprite() const { return false; } + + virtual void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) = 0; + + FTexture *pic; short x1, x2; - FVector3 gpos; // origin in world coordinates - union - { - struct - { - float gzb, gzt; // global bottom / top for silhouette clipping - }; - struct - { - int y1, y2; // top / bottom of particle on screen - }; - }; - DAngle Angle; - fixed_t xscale; - float yscale; - float depth; - float idepth; // 1/z - float deltax, deltay; - uint32_t FillColor; + float gzb, gzt; // global bottom / top for silhouette clipping + double floorclip; - union - { - FTexture *pic; - struct FVoxel *voxel; - }; - union - { - // Used by face sprites - struct - { - double texturemid; - fixed_t startfrac; // horizontal position of x1 - fixed_t xiscale; // negative if flipped - }; - // Used by wall sprites - FWallCoords wallc; - // Used by voxels - posang pa; - }; - sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling - sector_t *sector; // [RH] sector this sprite is in - F3DFloor *fakefloor; + + double texturemid; // floorclip + float yscale; // voxel and floorclip + + sector_t *heightsec; // height sector for underwater/fake ceiling + WaterFakeSide FakeFlatStat; // which side of fake/floor ceiling sprite is on + + F3DFloor *fakefloor; // 3d floor clipping F3DFloor *fakeceiling; - uint8_t bIsVoxel : 1; // [RH] Use voxel instead of pic - uint8_t bWallSprite : 1; // [RH] This is a wall sprite - uint8_t bSplitSprite : 1; // [RH] Sprite was split by a drawseg - uint8_t bInMirror : 1; // [RH] Sprite is "inside" a mirror - WaterFakeSide FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on - short renderflags; - uint32_t Translation; // [RH] for color translation + + FVector3 gpos; // origin in world coordinates + sector_t *sector; // sector this sprite is in + + // Light shared calculation? visstyle_t Style; - int CurrentPortalUniq; // [ZZ] to identify the portal that this thing is in. used for clipping. - bool foggy; + short renderflags; - vissprite_t() {} + float depth; // Sort (draw segments), also light + + float deltax, deltay; // Sort (2d/voxel version) + float idepth; // Sort (non-voxel version) + + int CurrentPortalUniq; // to identify the portal that this thing is in. used for clipping. }; } diff --git a/src/swrenderer/things/r_visiblespritelist.cpp b/src/swrenderer/things/r_visiblespritelist.cpp index 084f7b49ca..2ec36e9788 100644 --- a/src/swrenderer/things/r_visiblespritelist.cpp +++ b/src/swrenderer/things/r_visiblespritelist.cpp @@ -52,15 +52,15 @@ namespace swrenderer StartIndices.Pop(); } - void VisibleSpriteList::Push(vissprite_t *sprite) + void VisibleSpriteList::Push(VisibleSprite *sprite) { Sprites.Push(sprite); } void VisibleSpriteList::Sort(bool compare2d) { - size_t first = StartIndices.Size() == 0 ? 0 : StartIndices.Last(); - size_t count = Sprites.Size() - first; + unsigned int first = StartIndices.Size() == 0 ? 0 : StartIndices.Last(); + unsigned int count = Sprites.Size() - first; SortedSprites.Resize(count); @@ -69,7 +69,7 @@ namespace swrenderer if (!(i_compatflags & COMPATF_SPRITESORT)) { - for (size_t i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) SortedSprites[i] = Sprites[first + i]; } else @@ -77,7 +77,7 @@ namespace swrenderer // If the compatibility option is on sprites of equal distance need to // be sorted in inverse order. This is most easily achieved by // filling the sort array backwards before the sort. - for (size_t i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) SortedSprites[i] = Sprites[first + count - i - 1]; } @@ -87,7 +87,7 @@ namespace swrenderer // It does a 2D distance test based on whichever one is furthest from // the viewpoint. - std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](vissprite_t *a, vissprite_t *b) -> bool + std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool { return DVector2(a->deltax, a->deltay).LengthSquared() < DVector2(b->deltax, b->deltay).LengthSquared(); }); @@ -96,7 +96,7 @@ namespace swrenderer { // This is the standard version, which does a simple test based on depth. - std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](vissprite_t *a, vissprite_t *b) -> bool + std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool { return a->idepth > b->idepth; }); diff --git a/src/swrenderer/things/r_visiblespritelist.h b/src/swrenderer/things/r_visiblespritelist.h index 0dd43e0009..7add812ae1 100644 --- a/src/swrenderer/things/r_visiblespritelist.h +++ b/src/swrenderer/things/r_visiblespritelist.h @@ -16,7 +16,7 @@ namespace swrenderer { struct drawseg_t; - struct vissprite_t; + class VisibleSprite; class VisibleSpriteList { @@ -26,13 +26,13 @@ namespace swrenderer void Clear(); void PushPortal(); void PopPortal(); - void Push(vissprite_t *sprite); + void Push(VisibleSprite *sprite); void Sort(bool compare2d); - TArray SortedSprites; + TArray SortedSprites; private: - TArray Sprites; - TArray StartIndices; + TArray Sprites; + TArray StartIndices; }; } diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 6c4d3322f4..7ff15c7be3 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -105,7 +105,7 @@ namespace swrenderer } } - vissprite_t *vis = RenderMemory::NewObject(); + RenderVoxel *vis = RenderMemory::NewObject(); vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); @@ -150,12 +150,10 @@ namespace swrenderer vis->fakefloor = fakefloor; vis->fakeceiling = fakeceiling; vis->Style.ColormapNum = 0; - vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; - vis->bSplitSprite = false; + //vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; + //vis->bSplitSprite = false; vis->voxel = voxel->Voxel; - vis->bIsVoxel = true; - vis->bWallSprite = false; vis->foggy = foggy; // The software renderer cannot invert the source without inverting the overlay @@ -227,8 +225,10 @@ namespace swrenderer RenderTranslucentPass::DrewAVoxel = true; } - void RenderVoxel::Render(vissprite_t *sprite, int minZ, int maxZ, short *cliptop, short *clipbottom) + void RenderVoxel::Render(short *cliptop, short *clipbottom, int minZ, int maxZ) { + auto sprite = this; + FDynamicColormap *basecolormap = static_cast(sprite->Style.BaseColormap); R_SetColorMapLight(sprite->Style.BaseColormap, 0, sprite->Style.ColormapNum << FRACBITS); diff --git a/src/swrenderer/things/r_voxel.h b/src/swrenderer/things/r_voxel.h index 3788d0b192..57992fe834 100644 --- a/src/swrenderer/things/r_voxel.h +++ b/src/swrenderer/things/r_voxel.h @@ -25,11 +25,10 @@ struct kvxslab_t; struct FVoxelMipLevel; +struct FVoxel; namespace swrenderer { - struct vissprite_t; - // [RH] A c-buffer. Used for keeping track of offscreen voxel spans. struct FCoverageBuffer { @@ -52,15 +51,31 @@ namespace swrenderer unsigned int NumLists; }; - class RenderVoxel + class RenderVoxel : public VisibleSprite { public: static void Project(AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); - static void Render(vissprite_t *sprite, int minZ, int maxZ, short *cliptop, short *clipbottom); static void Deinit(); + bool IsVoxel() const override { return true; } + void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; + private: + struct posang + { + FVector3 vpos; // view origin + FAngle vang; // view angle + }; + + posang pa; + DAngle Angle; + fixed_t xscale; + FVoxel *voxel; + + uint32_t Translation; + uint32_t FillColor; + enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 }; static void FillBox(DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch); diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 319dcfc891..3f8ecbaa79 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -104,7 +104,7 @@ namespace swrenderer gzt = pos.Z + scale.Y * scaled_to; gzb = pos.Z + scale.Y * scaled_bo; - vissprite_t *vis = RenderMemory::NewObject(); + RenderWallSprite *vis = RenderMemory::NewObject(); vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->x1 = wallc.sx1 < renderportal->WindowLeft ? renderportal->WindowLeft : wallc.sx1; vis->x2 = wallc.sx2 >= renderportal->WindowRight ? renderportal->WindowRight : wallc.sx2; @@ -127,12 +127,9 @@ namespace swrenderer vis->Style.Alpha = float(thing->Alpha); vis->fakefloor = NULL; vis->fakeceiling = NULL; - vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; + //vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; vis->pic = pic; - vis->bIsVoxel = false; - vis->bWallSprite = true; - vis->Style.ColormapNum = GETPALOOKUP( - r_SpriteVisibility / MAX(tz, MINZ), spriteshade); + vis->Style.ColormapNum = GETPALOOKUP(r_SpriteVisibility / MAX(tz, MINZ), spriteshade); vis->Style.BaseColormap = basecolormap; vis->wallc = wallc; vis->foggy = foggy; @@ -140,8 +137,10 @@ namespace swrenderer VisibleSpriteList::Instance()->Push(vis); } - void RenderWallSprite::Render(vissprite_t *spr, const short *mfloorclip, const short *mceilingclip) + void RenderWallSprite::Render(short *mfloorclip, short *mceilingclip, int, int) { + auto spr = this; + int x1, x2; double iyscale; bool sprflipvert; diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index 350912cd1b..9791da678b 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -17,13 +17,19 @@ namespace swrenderer { - class RenderWallSprite + class RenderWallSprite : public VisibleSprite { public: static void Project(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap); - static void Render(vissprite_t *spr, const short *mfloorclip, const short *mceilingclip); + + bool IsWallSprite() const override { return true; } + void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; private: static void DrawColumn(int x, FTexture *WallSpriteTile, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); + + FWallCoords wallc; + uint32_t Translation; + uint32_t FillColor; }; }