From a4c0e299130f132a098cdc5acea08cd2f917c89d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 3 Jan 2017 18:57:48 +0100 Subject: [PATCH] Moved r_line into a class and implemented proper parameter passing between r_line and r_bsp, r_walldraw, r_wallsetup, r_decal, r_wallsprite, r_fogboundary, r_portal and r_playersprite --- src/swrenderer/line/r_line.cpp | 102 ++++++--------------- src/swrenderer/line/r_line.h | 105 ++++++++++++---------- src/swrenderer/line/r_walldraw.cpp | 82 +++++++++-------- src/swrenderer/line/r_walldraw.h | 7 +- src/swrenderer/line/r_wallsetup.cpp | 4 +- src/swrenderer/line/r_wallsetup.h | 5 +- src/swrenderer/plane/r_fogboundary.cpp | 7 +- src/swrenderer/plane/r_fogboundary.h | 2 +- src/swrenderer/plane/r_skyplane.cpp | 11 +-- src/swrenderer/r_main.cpp | 3 +- src/swrenderer/scene/r_bsp.cpp | 37 ++++---- src/swrenderer/scene/r_bsp.h | 3 +- src/swrenderer/scene/r_portal.cpp | 6 +- src/swrenderer/segments/r_drawsegment.cpp | 23 +++-- src/swrenderer/things/r_decal.cpp | 34 +++++-- src/swrenderer/things/r_decal.h | 5 +- src/swrenderer/things/r_playersprite.cpp | 3 +- src/swrenderer/things/r_wallsprite.cpp | 13 +-- 18 files changed, 229 insertions(+), 223 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 849ae635f2..c88e17a97f 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -51,72 +51,16 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - subsector_t *InSubsector; - sector_t *frontsector; - sector_t *backsector; - - seg_t *curline; - side_t *sidedef; - line_t *linedef; - - FWallCoords WallC; - FWallTmapVals WallT; - - double rw_backcz1; - double rw_backcz2; - double rw_backfz1; - double rw_backfz2; - double rw_frontcz1; - double rw_frontcz2; - double rw_frontfz1; - double rw_frontfz2; - - fixed_t rw_offset_top; - fixed_t rw_offset_mid; - fixed_t rw_offset_bottom; - - int rw_ceilstat, rw_floorstat; - bool rw_mustmarkfloor, rw_mustmarkceiling; - bool rw_prepped; - bool rw_markportal; - bool rw_havehigh; - bool rw_havelow; - - float rw_light; - float rw_lightstep; - float rw_lightleft; - - fixed_t rw_offset; - double rw_midtexturemid; - double rw_toptexturemid; - double rw_bottomtexturemid; - double rw_midtexturescalex; - double rw_midtexturescaley; - double rw_toptexturescalex; - double rw_toptexturescaley; - double rw_bottomtexturescalex; - double rw_bottomtexturescaley; - - FTexture *rw_pic; - - bool markfloor; // False if the back side is the same plane. - bool markceiling; - FTexture *toptexture; - FTexture *bottomtexture; - FTexture *midtexture; - - namespace - { - bool doorclosed; - int wallshade; - } - - void R_AddLine(seg_t *line) + void SWRenderLine::R_AddLine(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector) { static sector_t tempsec; // killough 3/8/98: ceiling/water hack bool solid; DVector2 pt1, pt2; + InSubsector = subsector; + frontsector = sector; + backsector = fakebacksector; + curline = line; // [RH] Color if not texturing line @@ -188,7 +132,7 @@ namespace swrenderer // kg3D - its fake, no transfer_heights if (!(fake3D & FAKE3D_FAKEBACK)) { // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water - backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); + backsector = R_FakeFlat(backsector, &tempsec, nullptr, nullptr, curline, WallC.sx1, WallC.sx2, rw_frontcz1, rw_frontcz2); } doorclosed = false; // killough 4/16/98 @@ -341,13 +285,19 @@ namespace swrenderer #endif } - if (R_ClipWallSegment(WallC.sx1, WallC.sx2, solid, R_StoreWallRange)) + static SWRenderLine *self = this; + bool visible = R_ClipWallSegment(WallC.sx1, WallC.sx2, solid, [](int x1, int x2) -> bool + { + return self->R_StoreWallRange(x1, x2); + }); + + if (visible) { InSubsector->flags |= SSECF_DRAWN; } } - bool R_SkyboxCompare(sector_t *frontsector, sector_t *backsector) + bool SWRenderLine::R_SkyboxCompare(sector_t *frontsector, sector_t *backsector) { FSectorPortal *frontc = frontsector->GetPortal(sector_t::ceiling); FSectorPortal *frontf = frontsector->GetPortal(sector_t::floor); @@ -365,7 +315,7 @@ namespace swrenderer } // A wall segment will be drawn between start and stop pixels (inclusive). - bool R_StoreWallRange(int start, int stop) + bool SWRenderLine::R_StoreWallRange(int start, int stop) { int i; bool maskedtexture = false; @@ -625,7 +575,7 @@ namespace swrenderer // [ZZ] Only if not an active mirror if (!rw_markportal) { - R_RenderDecals(curline->sidedef, draw_segment, wallshade); + R_RenderDecals(curline->sidedef, draw_segment, wallshade, rw_lightleft, rw_lightstep, curline, WallC); } if (rw_markportal) @@ -660,7 +610,7 @@ namespace swrenderer return !(fake3D & FAKE3D_FAKEMASK); } - void R_NewWall(bool needlights) + void SWRenderLine::R_NewWall(bool needlights) { double rowoffset; double yrepeat; @@ -968,7 +918,7 @@ namespace swrenderer bottomtexture ? (bottomtexture->Scale.X * sidedef->GetTextureXScale(side_t::bottom)) : 1.; - PrepWall(swall, lwall, sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2); + PrepWall(swall, lwall, sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT); if (fixedcolormap == NULL && fixedlightlev < 0) { @@ -986,7 +936,7 @@ namespace swrenderer } } - bool IsFogBoundary(sector_t *front, sector_t *back) + bool SWRenderLine::IsFogBoundary(sector_t *front, sector_t *back) { return r_fogboundary && fixedcolormap == NULL && front->ColorMap->Fade && front->ColorMap->Fade != back->ColorMap->Fade && @@ -995,7 +945,7 @@ namespace swrenderer // Draws zero, one, or two textures for walls. // Can draw or mark the starting pixel of floor and ceiling textures. - void R_RenderSegLoop(int x1, int x2) + void SWRenderLine::R_RenderSegLoop(int x1, int x2) { int x; double xscale; @@ -1094,7 +1044,7 @@ namespace swrenderer yscale = rw_pic->Scale.Y * rw_midtexturescaley; if (xscale != lwallscale) { - PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); + PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } if (midtexture->bWorldPanning) @@ -1109,7 +1059,7 @@ namespace swrenderer { rw_offset = -rw_offset; } - R_DrawWallSegment(rw_pic, x1, x2, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, light_list); + R_DrawWallSegment(frontsector, curline, WallC, rw_pic, x1, x2, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list); } fillshort(ceilingclip + x1, x2 - x1, viewheight); fillshort(floorclip + x1, x2 - x1, 0xffff); @@ -1130,7 +1080,7 @@ namespace swrenderer yscale = rw_pic->Scale.Y * rw_toptexturescaley; if (xscale != lwallscale) { - PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); + PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } if (toptexture->bWorldPanning) @@ -1145,7 +1095,7 @@ namespace swrenderer { rw_offset = -rw_offset; } - R_DrawWallSegment(rw_pic, x1, x2, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, light_list); + R_DrawWallSegment(frontsector, curline, WallC, rw_pic, x1, x2, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list); } memcpy(ceilingclip + x1, wallupper + x1, (x2 - x1) * sizeof(short)); } @@ -1169,7 +1119,7 @@ namespace swrenderer yscale = rw_pic->Scale.Y * rw_bottomtexturescaley; if (xscale != lwallscale) { - PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); + PrepLWall(lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } if (bottomtexture->bWorldPanning) @@ -1184,7 +1134,7 @@ namespace swrenderer { rw_offset = -rw_offset; } - R_DrawWallSegment(rw_pic, x1, x2, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, light_list); + R_DrawWallSegment(frontsector, curline, WallC, rw_pic, x1, x2, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list); } memcpy(floorclip + x1, walllower + x1, (x2 - x1) * sizeof(short)); } diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index c071e8e08c..fd245871df 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -35,59 +35,74 @@ namespace swrenderer void InitFromLine(const DVector2 &left, const DVector2 &right); }; - void R_AddLine(seg_t *line); - bool R_StoreWallRange(int start, int stop); - void R_NewWall(bool needlights); - void R_RenderSegLoop(int x1, int x2); + class SWRenderLine + { + public: + void R_AddLine(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector); - bool IsFogBoundary(sector_t *front, sector_t *back); - bool R_SkyboxCompare(sector_t *frontsector, sector_t *backsector); + private: + bool R_StoreWallRange(int start, int stop); + void R_NewWall(bool needlights); + void R_RenderSegLoop(int x1, int x2); - extern subsector_t *InSubsector; - extern sector_t *frontsector; - extern sector_t *backsector; + bool IsFogBoundary(sector_t *front, sector_t *back); + bool R_SkyboxCompare(sector_t *frontsector, sector_t *backsector); - extern seg_t *curline; - extern side_t *sidedef; - extern line_t *linedef; + subsector_t *InSubsector; + sector_t *frontsector; + sector_t *backsector; - extern FWallCoords WallC; - extern FWallTmapVals WallT; + seg_t *curline; + side_t *sidedef; + line_t *linedef; - extern double rw_backcz1; - extern double rw_backcz2; - extern double rw_backfz1; - extern double rw_backfz2; - extern double rw_frontcz1; - extern double rw_frontcz2; - extern double rw_frontfz1; - extern double rw_frontfz2; + FWallCoords WallC; + FWallTmapVals WallT; - extern fixed_t rw_offset_top; - extern fixed_t rw_offset_mid; - extern fixed_t rw_offset_bottom; + double rw_backcz1; + double rw_backcz2; + double rw_backfz1; + double rw_backfz2; + double rw_frontcz1; + double rw_frontcz2; + double rw_frontfz1; + double rw_frontfz2; - extern int rw_ceilstat, rw_floorstat; - extern bool rw_mustmarkfloor, rw_mustmarkceiling; - extern bool rw_prepped; - extern bool rw_markportal; - extern bool rw_havehigh; - extern bool rw_havelow; + fixed_t rw_offset_top; + fixed_t rw_offset_mid; + fixed_t rw_offset_bottom; - extern float rw_light; - extern float rw_lightstep; - extern float rw_lightleft; + int rw_ceilstat, rw_floorstat; + bool rw_mustmarkfloor, rw_mustmarkceiling; + bool rw_prepped; + bool rw_markportal; + bool rw_havehigh; + bool rw_havelow; - extern fixed_t rw_offset; - extern double rw_midtexturemid; - extern double rw_toptexturemid; - extern double rw_bottomtexturemid; - extern double rw_midtexturescalex; - extern double rw_midtexturescaley; - extern double rw_toptexturescalex; - extern double rw_toptexturescaley; - extern double rw_bottomtexturescalex; - extern double rw_bottomtexturescaley; + float rw_light; + float rw_lightstep; + float rw_lightleft; - extern FTexture *rw_pic; + fixed_t rw_offset; + double rw_midtexturemid; + double rw_toptexturemid; + double rw_bottomtexturemid; + double rw_midtexturescalex; + double rw_midtexturescaley; + double rw_toptexturescalex; + double rw_toptexturescaley; + double rw_bottomtexturescalex; + double rw_bottomtexturescaley; + + FTexture *rw_pic; + + bool doorclosed; + int wallshade; + + bool markfloor; // False if the back side is the same plane. + bool markceiling; + FTexture *toptexture; + FTexture *bottomtexture; + FTexture *midtexture; + }; } diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 40173ce226..26f8e923d1 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -51,7 +51,10 @@ namespace swrenderer { using namespace drawerargs; - extern FTexture *rw_pic; + namespace + { + FTexture *rw_pic; + } static const uint8_t *R_GetColumn(FTexture *tex, int col) { @@ -191,9 +194,9 @@ namespace swrenderer } // Draw a column with support for non-power-of-two ranges - static void Draw1Column(int x, int y1, int y2, WallSampler &sampler, DrawerFunc draw1column) + static void Draw1Column(const FWallCoords &WallC, int x, int y1, int y2, WallSampler &sampler, DrawerFunc draw1column) { - if (r_dynlights) + if (r_dynlights && dc_light_list) { // Find column position in view space float w1 = 1.0f / WallC.sz1; @@ -330,14 +333,13 @@ namespace swrenderer } static void ProcessWallWorker( - int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, + const FWallCoords &WallC, + int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const BYTE *(*getcol)(FTexture *tex, int x), DrawerFunc drawcolumn) { if (rw_pic->UseType == FTexture::TEX_Null) return; - fixed_t xoffset = rw_offset; - rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set int fracbits = 32 - rw_pic->HeightBits; if (fracbits == 32) @@ -374,11 +376,9 @@ namespace swrenderer dc_normal.Y = -dx / length; dc_normal.Z = 0.0f; - float light = rw_light; - double xmagnitude = 1.0; - for (int x = x1; x < x2; x++, light += rw_lightstep) + for (int x = x1; x < x2; x++, light += lightstep) { int y1 = uwal[x]; int y2 = dwal[x]; @@ -391,44 +391,44 @@ namespace swrenderer if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); WallSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic, getcol); - Draw1Column(x, y1, y2, sampler, drawcolumn); + Draw1Column(WallC, x, y1, y2, sampler, drawcolumn); } NetUpdate(); } - static void ProcessNormalWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) + static void ProcessNormalWall(const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) { - ProcessWallWorker(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol, &SWPixelFormatDrawers::DrawWallColumn); + ProcessWallWorker(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol, &SWPixelFormatDrawers::DrawWallColumn); } - static void ProcessMaskedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) + static void ProcessMaskedWall(const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) { if (!rw_pic->bMasked) // Textures that aren't masked can use the faster ProcessNormalWall. { - ProcessNormalWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol); + ProcessNormalWall(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol); } else { - ProcessWallWorker(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol, &SWPixelFormatDrawers::DrawWallMaskedColumn); + ProcessWallWorker(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol, &SWPixelFormatDrawers::DrawWallMaskedColumn); } } - static void ProcessTranslucentWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) + static void ProcessTranslucentWall(const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn) { DrawerFunc drawcol1 = R_GetTransMaskDrawer(); if (drawcol1 == nullptr) { // The current translucency is unsupported, so draw with regular ProcessMaskedWall instead. - ProcessMaskedWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol); + ProcessMaskedWall(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol); } else { - ProcessWallWorker(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol, drawcol1); + ProcessWallWorker(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol, drawcol1); } } - static void ProcessStripedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade) + static void ProcessStripedWall(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep) { FDynamicColormap *startcolormap = basecolormap; bool fogginess = foggy; @@ -452,7 +452,7 @@ namespace swrenderer { down[j] = clamp(most3[j], up[j], dwal[j]); } - ProcessNormalWall(x1, x2, up, down, swal, lwal, yrepeat, wallshade); + ProcessNormalWall(WallC, x1, x2, up, down, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); up = down; down = (down == most1) ? most2 : most1; } @@ -462,32 +462,32 @@ namespace swrenderer wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(fogginess, *lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight); } - ProcessNormalWall(x1, x2, up, dwal, swal, lwal, yrepeat, wallshade); + ProcessNormalWall(WallC, x1, x2, up, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); basecolormap = startcolormap; } - static void ProcessWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, bool mask) + static void ProcessWall(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, bool mask) { if (mask) { if (colfunc == basecolfunc) { - ProcessMaskedWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade); + ProcessMaskedWall(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); } else { - ProcessTranslucentWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade); + ProcessTranslucentWall(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); } } else { if (fixedcolormap != NULL || fixedlightlev >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size())) { - ProcessNormalWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade); + ProcessNormalWall(WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); } else { - ProcessStripedWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade); + ProcessStripedWall(frontsector, curline, WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep); } } } @@ -503,7 +503,7 @@ namespace swrenderer // //============================================================================= - static void ProcessWallNP2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, int wallshade, bool mask) + static void ProcessWallNP2(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, int wallshade, fixed_t xoffset, float light, float lightstep, bool mask) { short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH]; short *up, *down; @@ -530,14 +530,14 @@ namespace swrenderer { down[j] = clamp(most3[j], up[j], dwal[j]); } - ProcessWall(x1, x2, up, down, swal, lwal, yrepeat, wallshade, mask); + ProcessWall(frontsector, curline, WallC, x1, x2, up, down, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, mask); up = down; down = (down == most1) ? most2 : most1; } partition -= scaledtexheight; dc_texturemid -= texheight; } - ProcessWall(x1, x2, up, dwal, swal, lwal, yrepeat, wallshade, mask); + ProcessWall(frontsector, curline, WallC, x1, x2, up, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, mask); } else { // upside down: draw strips from bottom to top @@ -554,19 +554,20 @@ namespace swrenderer { up[j] = clamp(most3[j], uwal[j], down[j]); } - ProcessWall(x1, x2, up, down, swal, lwal, yrepeat, wallshade, mask); + ProcessWall(frontsector, curline, WallC, x1, x2, up, down, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, mask); down = up; up = (up == most1) ? most2 : most1; } partition -= scaledtexheight; dc_texturemid -= texheight; } - ProcessWall(x1, x2, uwal, down, swal, lwal, yrepeat, wallshade, mask); + ProcessWall(frontsector, curline, WallC, x1, x2, uwal, down, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, mask); } } - void R_DrawDrawSeg(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade) + void R_DrawDrawSeg(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep) { + rw_pic = pic; if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) { double frontcz1 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v1); @@ -583,31 +584,34 @@ namespace swrenderer { bot = MAX(bot, sclipBottom); } - ProcessWallNP2(x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, wallshade, true); + ProcessWallNP2(frontsector, curline, WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, wallshade, xoffset, light, lightstep, true); } else { - ProcessWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, true); + ProcessWall(frontsector, curline, WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, true); } } - void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, FLightNode *light_list) + void R_DrawWallSegment(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list) { + rw_pic = pic; dc_light_list = light_list; if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) { - ProcessWallNP2(x1, x2, walltop, wallbottom, swall, lwall, yscale, top, bottom, wallshade, false); + ProcessWallNP2(frontsector, curline, WallC, x1, x2, walltop, wallbottom, swall, lwall, yscale, top, bottom, wallshade, xoffset, light, lightstep, false); } else { - ProcessWall(x1, x2, walltop, wallbottom, swall, lwall, yscale, wallshade, false); + ProcessWall(frontsector, curline, WallC, x1, x2, walltop, wallbottom, swall, lwall, yscale, wallshade, xoffset, light, lightstep, false); } dc_light_list = nullptr; } - void R_DrawSkySegment(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, const BYTE *(*getcol)(FTexture *tex, int x)) + void R_DrawSkySegment(FTexture *pic, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const uint8_t *(*getcol)(FTexture *tex, int x)) { - ProcessNormalWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, getcol); + rw_pic = pic; + FWallCoords wallC; // Not used. To do: don't use r_walldraw to draw the sky!! + ProcessNormalWall(wallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, wallshade, xoffset, light, lightstep, getcol); } } diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h index 8cc71f8df1..8ef23438f2 100644 --- a/src/swrenderer/line/r_walldraw.h +++ b/src/swrenderer/line/r_walldraw.h @@ -19,6 +19,7 @@ struct FLightNode; namespace swrenderer { struct drawseg_t; + struct FWallCoords; struct WallSampler { @@ -35,7 +36,7 @@ namespace swrenderer uint32_t height; }; - void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, FLightNode *light_list); - void R_DrawSkySegment(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, const uint8_t *(*getcol)(FTexture *tex, int col)); - void R_DrawDrawSeg(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade); + void R_DrawWallSegment(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list); + void R_DrawSkySegment(FTexture *rw_pic, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep, const uint8_t *(*getcol)(FTexture *tex, int col)); + void R_DrawDrawSeg(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *rw_pic, drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, int wallshade, fixed_t xoffset, float light, float lightstep); } diff --git a/src/swrenderer/line/r_wallsetup.cpp b/src/swrenderer/line/r_wallsetup.cpp index 90ba7793a1..ee32c1bd0d 100644 --- a/src/swrenderer/line/r_wallsetup.cpp +++ b/src/swrenderer/line/r_wallsetup.cpp @@ -153,7 +153,7 @@ namespace swrenderer } } - void PrepWall(float *vstep, fixed_t *upos, double walxrepeat, int x1, int x2) + void PrepWall(float *vstep, fixed_t *upos, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT) { float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - CenterX); float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX); @@ -191,7 +191,7 @@ namespace swrenderer } } - void PrepLWall(fixed_t *upos, double walxrepeat, int x1, int x2) + void PrepLWall(fixed_t *upos, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT) { float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - CenterX); float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX); diff --git a/src/swrenderer/line/r_wallsetup.h b/src/swrenderer/line/r_wallsetup.h index 4e483601f7..5ceac6f65e 100644 --- a/src/swrenderer/line/r_wallsetup.h +++ b/src/swrenderer/line/r_wallsetup.h @@ -6,6 +6,7 @@ namespace swrenderer { struct FWallCoords; + struct FWallTmapVals; extern short walltop[MAXWIDTH]; extern short wallbottom[MAXWIDTH]; @@ -19,6 +20,6 @@ namespace swrenderer int R_CreateWallSegmentYSloped(short *outbuf, const secplane_t &plane, const FWallCoords *wallc, seg_t *line, bool xflip); int R_CreateWallSegmentY(short *outbuf, double z, const FWallCoords *wallc); - void PrepWall(float *swall, fixed_t *lwall, double walxrepeat, int x1, int x2); - void PrepLWall(fixed_t *lwall, double walxrepeat, int x1, int x2); + void PrepWall(float *swall, fixed_t *lwall, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); + void PrepLWall(fixed_t *lwall, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); } diff --git a/src/swrenderer/plane/r_fogboundary.cpp b/src/swrenderer/plane/r_fogboundary.cpp index 68ec3097dc..bef238125e 100644 --- a/src/swrenderer/plane/r_fogboundary.cpp +++ b/src/swrenderer/plane/r_fogboundary.cpp @@ -51,14 +51,13 @@ namespace swrenderer short spanend[MAXHEIGHT]; } - void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip, int wallshade) + void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep) { // This is essentially the same as R_MapVisPlane but with an extra step // to create new horizontal spans whenever the light changes enough that // we need to use a new colormap. - double lightstep = rw_lightstep; - double light = rw_light + rw_lightstep*(x2 - x1 - 1); + float light = lightleft + lightstep*(x2 - x1 - 1); int x = x2 - 1; int t2 = uclip[x]; int b2 = dclip[x]; @@ -82,7 +81,7 @@ namespace swrenderer const int xr = x + 1; int stop; - light -= rw_lightstep; + light -= lightstep; lcolormap = GETPALOOKUP(light, wallshade); if (lcolormap != rcolormap) { diff --git a/src/swrenderer/plane/r_fogboundary.h b/src/swrenderer/plane/r_fogboundary.h index de872fd589..7eaff57b9a 100644 --- a/src/swrenderer/plane/r_fogboundary.h +++ b/src/swrenderer/plane/r_fogboundary.h @@ -17,6 +17,6 @@ namespace swrenderer { - void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip, int wallshade); + void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep); void R_DrawFogBoundarySection(int y, int y2, int x1); } diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index 1f391b331b..3cf4176c9d 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -453,10 +453,7 @@ namespace swrenderer lastskycol_bgra[x] = 0xffffffff; } - rw_pic = frontskytex; - rw_offset = 0; - - frontyScale = rw_pic->Scale.Y; + frontyScale = frontskytex->Scale.Y; dc_texturemid = skymid * frontyScale; if (1 << frontskytex->HeightBits == frontskytex->GetHeight()) @@ -466,8 +463,8 @@ namespace swrenderer lastskycol[x] = 0xffffffff; lastskycol_bgra[x] = 0xffffffff; } - R_DrawSkySegment(pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall, - frontyScale, 0, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); + R_DrawSkySegment(frontskytex, pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall, + frontyScale, 0, 0, 0.0f, 0.0f, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); } else { // The texture does not tile nicely @@ -504,7 +501,7 @@ namespace swrenderer lastskycol[x] = 0xffffffff; lastskycol_bgra[x] = 0xffffffff; } - R_DrawSkySegment(pl->left, pl->right, top, bot, swall, lwall, rw_pic->Scale.Y, 0, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); + R_DrawSkySegment(frontskytex, pl->left, pl->right, top, bot, swall, lwall, frontskytex->Scale.Y, 0, 0, 0.0f, 0.0f, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); yl = yh; yh += drawheight; dc_texturemid = iscale * (centery - yl - 1); diff --git a/src/swrenderer/r_main.cpp b/src/swrenderer/r_main.cpp index 48f9ea2324..1dbae64ba3 100644 --- a/src/swrenderer/r_main.cpp +++ b/src/swrenderer/r_main.cpp @@ -597,8 +597,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) } // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function PO_LinkToSubsectors(); - InSubsector = NULL; - R_RenderBSPNode(nodes + numnodes - 1); // The head node is the last node output. + R_RenderScene(); R_3D_ResetClip(); // reset clips (floor/ceiling) camera->renderflags = savedflags; WallCycles.Unclock(); diff --git a/src/swrenderer/scene/r_bsp.cpp b/src/swrenderer/scene/r_bsp.cpp index 1d0fcfd50e..f7e871572d 100644 --- a/src/swrenderer/scene/r_bsp.cpp +++ b/src/swrenderer/scene/r_bsp.cpp @@ -59,8 +59,13 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - using namespace drawerargs; + namespace + { + subsector_t *InSubsector; + sector_t *frontsector; + SWRenderLine render_line; + } bool r_fakingunderwater; @@ -93,9 +98,7 @@ short ceilingclip[MAXWIDTH]; // killough 4/11/98, 4/13/98: fix bugs, add 'back' parameter // -sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, - int *floorlightlevel, int *ceilinglightlevel, - bool back) +sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2) { // [RH] allow per-plane lighting if (floorlightlevel != NULL) @@ -182,13 +185,13 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, // are underwater but not in a water sector themselves. // Only works if you cannot see the top surface of any deep water // sectors at the same time. - if (back && !r_fakingunderwater && curline->frontsector->heightsec == NULL) + if (backline && !r_fakingunderwater && backline->frontsector->heightsec == NULL) { - if (rw_frontcz1 <= s->floorplane.ZatPoint(curline->v1) && - rw_frontcz2 <= s->floorplane.ZatPoint(curline->v2)) + if (frontcz1 <= s->floorplane.ZatPoint(backline->v1) && + frontcz2 <= s->floorplane.ZatPoint(backline->v2)) { // Check that the window is actually visible - for (int z = WallC.sx1; z < WallC.sx2; ++z) + for (int z = backx1; z < backx2; ++z) { if (floorclip[z] > ceilingclip[z]) { @@ -211,7 +214,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, } // killough 11/98: prevent sudden light changes from non-water sectors: - if ((underwater && !back) || doorunderwater) + if ((underwater && !backline) || doorunderwater) { // head-below-floor hack tempsec->SetTexture(sector_t::floor, diffTex ? sec->GetTexture(sector_t::floor) : s->GetTexture(sector_t::floor), false); tempsec->planes[sector_t::floor].xform = s->planes[sector_t::floor].xform; @@ -427,7 +430,7 @@ void R_FakeDrawLoop(subsector_t *sub) { if ((line->sidedef) && !(line->sidedef->Flags & WALLF_POLYOBJ)) { - R_AddLine (line); + render_line.R_AddLine (line, InSubsector, frontsector, nullptr); } line++; } @@ -489,8 +492,7 @@ void R_Subsector (subsector_t *sub) line = sub->firstline; // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect - frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, - &ceilinglightlevel, false); // killough 4/11/98 + frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, nullptr, 0, 0, 0, 0); fll = floorlightlevel; cll = ceilinglightlevel; @@ -757,20 +759,19 @@ void R_Subsector (subsector_t *sub) tempsec = *fakeFloor->model; tempsec.floorplane = *fakeFloor->top.plane; tempsec.ceilingplane = *fakeFloor->bottom.plane; - backsector = &tempsec; if (fakeFloor->validcount != validcount) { fakeFloor->validcount = validcount; R_3D_NewClip(); } - R_AddLine(line); // fake + render_line.R_AddLine(line, InSubsector, frontsector, &tempsec); // fake } fakeFloor = NULL; fake3D = 0; floorplane = backupfp; ceilingplane = backupcp; } - R_AddLine (line); // now real + render_line.R_AddLine(line, InSubsector, frontsector, nullptr); // now real } line++; } @@ -780,6 +781,12 @@ void R_Subsector (subsector_t *sub) } } +void R_RenderScene() +{ + InSubsector = nullptr; + R_RenderBSPNode(nodes + numnodes - 1); // The head node is the last node output. +} + // // RenderBSPNode // Renders all subsectors below a given node, traversing subtree recursively. diff --git a/src/swrenderer/scene/r_bsp.h b/src/swrenderer/scene/r_bsp.h index ef5d08db19..d45075ba78 100644 --- a/src/swrenderer/scene/r_bsp.h +++ b/src/swrenderer/scene/r_bsp.h @@ -49,10 +49,11 @@ enum extern int WindowLeft, WindowRight; extern WORD MirrorFlags; +void R_RenderScene(); void R_RenderBSPNode (void *node); // killough 4/13/98: fake floors/ceilings for deep water / fake ceilings: -sector_t *R_FakeFlat(sector_t *, sector_t *, int *, int *, bool); +sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2); extern visplane_t *floorplane; extern visplane_t *ceilingplane; diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index 314891b61d..7d5a85f916 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -246,8 +246,7 @@ namespace swrenderer viewposStack.Push(ViewPos); visplaneStack.Push(pl); - InSubsector = nullptr; - R_RenderBSPNode(nodes + numnodes - 1); + R_RenderScene(); R_3D_ResetClip(); // reset clips (floor/ceiling) R_DrawPlanes(); @@ -466,8 +465,7 @@ namespace swrenderer memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip)); memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip)); - InSubsector = nullptr; - R_RenderBSPNode(nodes + numnodes - 1); + R_RenderScene(); R_3D_ResetClip(); // reset clips (floor/ceiling) if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE; diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp index 311f5a867b..6d174ce751 100644 --- a/src/swrenderer/segments/r_drawsegment.cpp +++ b/src/swrenderer/segments/r_drawsegment.cpp @@ -51,6 +51,19 @@ namespace swrenderer namespace { size_t MaxDrawSegs; + + sector_t *frontsector; + sector_t *backsector; + + seg_t *curline; + + FWallCoords WallC; + FWallTmapVals WallT; + + float rw_light; + float rw_lightstep; + fixed_t rw_offset; + FTexture *rw_pic; } void R_FreeDrawSegs() @@ -145,7 +158,7 @@ namespace swrenderer } // killough 4/13/98: get correct lightlevel for 2s normal textures - sec = R_FakeFlat(frontsector, &tempsec, nullptr, nullptr, false); + sec = R_FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); basecolormap = sec->ColorMap; // [RH] Set basecolormap @@ -179,7 +192,7 @@ namespace swrenderer // [RH] Draw fog partition if (ds->bFogBoundary) { - R_DrawFogBoundary(x1, x2, mceilingclip, mfloorclip, wallshade); + R_DrawFogBoundary(x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep); if (ds->maskedtexturecol == -1) { goto clearfog; @@ -397,7 +410,7 @@ namespace swrenderer rw_offset = 0; rw_pic = tex; - R_DrawDrawSeg(ds, x1, x2, mceilingclip, mfloorclip, MaskedSWall, maskedtexturecol, ds->yscale, wallshade); + R_DrawDrawSeg(frontsector, curline, WallC, rw_pic, ds, x1, x2, mceilingclip, mfloorclip, MaskedSWall, maskedtexturecol, ds->yscale, wallshade, rw_offset, rw_light, rw_lightstep); } clearfog: @@ -522,8 +535,8 @@ namespace swrenderer walllower[i] = mfloorclip[i]; } - PrepLWall(lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2); - R_DrawDrawSeg(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale, wallshade); + PrepLWall(lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2, WallT); + R_DrawDrawSeg(frontsector, curline, WallC, rw_pic, ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale, wallshade, rw_offset, rw_light, rw_lightstep); R_FinishSetPatchStyle(); } diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index f992cf13e5..19281d12b9 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -44,11 +44,11 @@ namespace swrenderer { - void R_RenderDecals(side_t *sidedef, drawseg_t *draw_segment, int wallshade) + void R_RenderDecals(side_t *sidedef, drawseg_t *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC) { for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) { - R_RenderDecal(sidedef, decal, draw_segment, wallshade, 0); + R_RenderDecal(sidedef, decal, draw_segment, wallshade, lightleft, lightstep, curline, wallC, 0); } } @@ -56,7 +56,7 @@ namespace swrenderer // = 1: drawing masked textures (including sprites) // Currently, only pass = 0 is done or used - void R_RenderDecal(side_t *wall, DBaseDecal *decal, drawseg_t *clipper, int wallshade, int pass) + void R_RenderDecal(side_t *wall, DBaseDecal *decal, drawseg_t *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, FWallCoords WallC, int pass) { DVector2 decal_left, decal_right, decal_pos; int x1, x2; @@ -150,6 +150,7 @@ namespace swrenderer if (x1 >= clipper->x2 || x2 <= clipper->x1) goto done; + FWallTmapVals WallT; WallT.InitFromWallCoords(&WallC); // Get the top and bottom clipping arrays @@ -217,7 +218,7 @@ namespace swrenderer goto done; } - PrepWall(swall, lwall, WallSpriteTile->GetWidth(), x1, x2); + PrepWall(swall, lwall, WallSpriteTile->GetWidth(), x1, x2, WallT); if (flipx) { @@ -242,7 +243,7 @@ namespace swrenderer rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - savecoord.sx1) * rw_lightstep; + float light = lightleft + (x1 - savecoord.sx1) * lightstep; if (fixedlightlev >= 0) R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev)); else if (fixedcolormap != NULL) @@ -283,9 +284,10 @@ namespace swrenderer { if (calclighting) { // calculate lighting - R_SetColorMapLight(usecolormap, rw_light, wallshade); + R_SetColorMapLight(usecolormap, light, wallshade); } - R_WallSpriteColumn(x, maskedScaleY); + R_DecalColumn(x, maskedScaleY); + light += lightstep; x++; } } @@ -304,4 +306,22 @@ namespace swrenderer done: WallC = savecoord; } + + void R_DecalColumn(int x, float maskedScaleY) + { + using namespace drawerargs; + + dc_x = x; + + float iscale = swall[dc_x] * maskedScaleY; + dc_iscale = FLOAT2FIXED(iscale); + spryscale = 1 / iscale; + if (sprflipvert) + sprtopscreen = CenterY + dc_texturemid * spryscale; + else + sprtopscreen = CenterY - dc_texturemid * spryscale; + + dc_texturefrac = 0; + R_DrawMaskedColumn(WallSpriteTile, lwall[dc_x]); + } } diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index 74871c4b04..7bd4147fa0 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -20,6 +20,7 @@ namespace swrenderer { struct drawseg_t; - void R_RenderDecals(side_t *wall, drawseg_t *draw_segment, int wallshade); - void R_RenderDecal(side_t *wall, DBaseDecal *first, drawseg_t *clipper, int wallshade, int pass); + void R_RenderDecals(side_t *wall, drawseg_t *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC); + void R_RenderDecal(side_t *wall, DBaseDecal *first, drawseg_t *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, FWallCoords wallC, int pass); + void R_DecalColumn(int x, float maskedScaleY); } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 22ae8e99c1..5dad94c707 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -123,8 +123,7 @@ namespace swrenderer else { // This used to use camera->Sector but due to interpolation that can be incorrect // when the interpolated viewpoint is in a different sector than the camera. - sec = R_FakeFlat(viewsector, &tempsec, &floorlight, - &ceilinglight, false); + sec = R_FakeFlat(viewsector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0); // [RH] set basecolormap basecolormap = sec->ColorMap; diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 4073917bb7..b4c60cb95d 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -141,8 +141,9 @@ namespace swrenderer x2 = MIN(spr->x2, spr->wallc.sx2); if (x1 >= x2) return; + FWallTmapVals WallT; WallT.InitFromWallCoords(&spr->wallc); - PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); + PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2, WallT); iyscale = 1 / spr->yscale; dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale; if (spr->renderflags & RF_XFLIP) @@ -168,9 +169,9 @@ namespace swrenderer int shade = LIGHT2SHADE(spr->sector->lightlevel + r_actualextralight); GlobVis = r_WallVisibility; - rw_lightleft = float(GlobVis / spr->wallc.sz1); - rw_lightstep = float((GlobVis / spr->wallc.sz2 - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1)); - rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep; + float lightleft = float(GlobVis / spr->wallc.sz1); + float lightstep = float((GlobVis / spr->wallc.sz2 - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1)); + float light = lightleft + (x1 - spr->wallc.sx1) * lightstep; if (fixedlightlev >= 0) R_SetColorMapLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev)); else if (fixedcolormap != NULL) @@ -215,10 +216,11 @@ namespace swrenderer { if (calclighting) { // calculate lighting - R_SetColorMapLight(usecolormap, rw_light, shade); + R_SetColorMapLight(usecolormap, light, shade); } if (!R_ClipSpriteColumnWithPortals(spr)) R_WallSpriteColumn(x, maskedScaleY); + light += lightstep; x++; } } @@ -241,6 +243,5 @@ namespace swrenderer dc_texturefrac = 0; R_DrawMaskedColumn(WallSpriteTile, lwall[dc_x]); - rw_light += rw_lightstep; } }