From 9ee0271320d1e65863104b2ad06b9b427b705050 Mon Sep 17 00:00:00 2001 From: Erick Tenorio Date: Thu, 27 Dec 2018 11:40:18 -0600 Subject: [PATCH 1/9] - Have Plutonia MAP16 pit kill player --- wadsrc/static/zscript/level_compatibility.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt index 170b98ed5..98de44851 100644 --- a/wadsrc/static/zscript/level_compatibility.txt +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -232,6 +232,15 @@ class LevelCompatibility play break; } + case 'ECA0559E85EFFB6966ECB8DE01E3A35B': // Plutonia Experiment MAP16 + { + // Have it so that the slime pit at the end of the level can + // actually kill the player. + SetSectorSpecial(95, 768); + SetSectorSpecial(96, 768); + break; + } + case '9D84B423D8FD28553DDE23B55F97CF4A': // Plutonia Experiment MAP25 { // Missing texture at level exit. From 0a6ec054d2e3f101d1ec425abb949ba1f8545dda Mon Sep 17 00:00:00 2001 From: Erick Tenorio Date: Thu, 27 Dec 2018 12:02:49 -0600 Subject: [PATCH 2/9] - TNT.WAD fixes --- wadsrc/static/zscript/level_compatibility.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt index 98de44851..4b7f987ac 100644 --- a/wadsrc/static/zscript/level_compatibility.txt +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -144,6 +144,12 @@ class LevelCompatibility play SetLineActivation(959, SPAC_Cross); SetLineSpecial(960, Floor_RaiseToNearest, 16, 32); SetLineActivation(960, SPAC_Cross); + // Dropping into the holes themselves raises sectors + for(int i=0; i<9; i++) + { + SetLineSpecial(999+i, Floor_RaiseToNearest, 16, 32); + SetLineActivation(999+i, SPAC_Cross); + } break; } @@ -177,6 +183,7 @@ class LevelCompatibility play } case 'A53AE580A4AF2B5D0B0893F86914781E': // TNT: Evilution map31 + case '55192065F7FAA7D161767145DA008293': // TNT Anthology/GOG MAP31 { // The famous missing yellow key... SetThingFlags(470, 2016); From ed094d0b2f68f7fe32597de0a88874ddc257e7b3 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 27 Dec 2018 22:03:02 +0100 Subject: [PATCH 3/9] - create a ProjectedWallLight class for the variables used to calculate light for columns --- src/swrenderer/line/r_line.cpp | 38 +++++----- src/swrenderer/line/r_line.h | 7 +- src/swrenderer/line/r_renderdrawsegment.cpp | 81 ++++++++++----------- src/swrenderer/line/r_renderdrawsegment.h | 8 +- src/swrenderer/line/r_walldraw.cpp | 22 +++--- src/swrenderer/line/r_walldraw.h | 15 +--- src/swrenderer/line/r_wallsetup.h | 12 +++ src/swrenderer/things/r_decal.cpp | 17 ++--- src/swrenderer/things/r_decal.h | 4 +- 9 files changed, 99 insertions(+), 105 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 8c937966b..52277204e 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -78,8 +78,8 @@ namespace swrenderer mBackSector = fakebacksector; mFloorPlane = linefloorplane; mCeilingPlane = lineceilingplane; - foggy = infog; - basecolormap = colormap; + mLight.foggy = infog; + mLight.basecolormap = colormap; mLineSegment = line; m3DFloor = opaque3dfloor; @@ -345,7 +345,7 @@ namespace swrenderer draw_segment->x1 = start; draw_segment->x2 = stop; draw_segment->curline = mLineSegment; - draw_segment->foggy = foggy; + draw_segment->foggy = mLight.foggy; draw_segment->SubsectorDepth = Thread->OpaquePass->GetSubsectorDepth(mSubsector->Index()); bool markportal = ShouldMarkPortal(); @@ -490,8 +490,8 @@ namespace swrenderer draw_segment->iscalestep = 0; } } - draw_segment->light = rw_lightleft + rw_lightstep * (start - WallC.sx1); - draw_segment->lightstep = rw_lightstep; + draw_segment->light = mLight.lightleft + mLight.lightstep * (start - WallC.sx1); + draw_segment->lightstep = mLight.lightstep; // Masked mMiddlePart.Textures should get the light level from the sector they reference, // not from the current subsector, which is what the current lightlevel value @@ -499,11 +499,11 @@ namespace swrenderer // sector should be whichever one they move into. if (mLineSegment->sidedef->Flags & WALLF_POLYOBJ) { - draw_segment->lightlevel = lightlevel; + draw_segment->lightlevel = mLight.lightlevel; } else { - draw_segment->lightlevel = mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel); + draw_segment->lightlevel = mLineSegment->sidedef->GetLightLevel(mLight.foggy, mLineSegment->frontsector->lightlevel); } if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) @@ -552,7 +552,7 @@ namespace swrenderer // [ZZ] Only if not an active mirror if (!markportal) { - RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, lightlevel, rw_lightleft, rw_lightstep, mLineSegment, WallC, foggy, basecolormap, walltop.ScreenY, wallbottom.ScreenY, false); + RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, mLineSegment, WallC, mLight, walltop.ScreenY, wallbottom.ScreenY, false); } if (markportal) @@ -789,14 +789,14 @@ namespace swrenderer CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { - lightlevel = mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel); - rw_lightleft = float(Thread->Light->WallVis(WallC.sz1, foggy)); - rw_lightstep = float((Thread->Light->WallVis(WallC.sz2, foggy) - rw_lightleft) / (WallC.sx2 - WallC.sx1)); + mLight.lightlevel = mLineSegment->sidedef->GetLightLevel(mLight.foggy, mFrontSector->lightlevel); + mLight.lightleft = float(Thread->Light->WallVis(WallC.sz1, mLight.foggy)); + mLight.lightstep = float((Thread->Light->WallVis(WallC.sz2, mLight.foggy) - mLight.lightleft) / (WallC.sx2 - WallC.sx1)); } else { - rw_lightleft = 1; - rw_lightstep = 0; + mLight.lightleft = 1; + mLight.lightstep = 0; } } } @@ -1164,10 +1164,10 @@ namespace swrenderer offset = -offset; } - float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1); + mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap); + renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } void SWRenderLine::RenderMiddleTexture(int x1, int x2) @@ -1197,10 +1197,10 @@ namespace swrenderer offset = -offset; } - float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1); + mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap); + renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } void SWRenderLine::RenderBottomTexture(int x1, int x2) @@ -1231,10 +1231,10 @@ namespace swrenderer offset = -offset; } - float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1); + mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap); + renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } FLightNode *SWRenderLine::GetLightList() diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index d06adf35a..900dfe98f 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -128,16 +128,11 @@ namespace swrenderer FWallCoords WallC; FWallTmapVals WallT; - bool foggy; - FDynamicColormap *basecolormap; - // Wall segment variables: bool rw_prepped; - int lightlevel; - float rw_lightstep; - float rw_lightleft; + ProjectedWallLight mLight; double lwallscale; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 7065445a6..567354cde 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -80,12 +80,11 @@ namespace swrenderer sector_t tempsec; const sector_t *sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); - FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap - - bool foggy = ds->foggy; - int lightlevel = ds->lightlevel; - rw_lightstep = ds->lightstep; - rw_light = ds->light + (x1 - ds->x1) * rw_lightstep; + mLight.basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap + mLight.foggy = ds->foggy; + mLight.lightlevel = ds->lightlevel; + mLight.lightstep = ds->lightstep; + mLight.light = ds->light + (x1 - ds->x1) * mLight.lightstep; Clip3DFloors *clip3d = Thread->Clip3D.get(); @@ -95,9 +94,9 @@ namespace swrenderer if (clipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -107,7 +106,7 @@ namespace swrenderer SpriteDrawerArgs columndrawerargs; ColormapLight cmlight; - cmlight.SetColormap(Thread, MINZ, lightlevel, foggy, basecolormap, false, false, false, false, false); + cmlight.SetColormap(Thread, MINZ, mLight.lightlevel, mLight.foggy, mLight.basecolormap, false, false, false, false, false); bool visible = columndrawerargs.SetStyle(viewport, LegacyRenderStyles[additive ? STYLE_Add : STYLE_Translucent], alpha, 0, 0, cmlight); if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls()) { @@ -123,7 +122,7 @@ namespace swrenderer const short *mceilingclip = ds->sprtopclip - ds->x1; RenderFogBoundary renderfog; - renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, lightlevel, ds->foggy, rw_light, rw_lightstep, basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight.lightlevel, ds->foggy, mLight.light, mLight.lightstep, mLight.basecolormap); if (ds->maskedtexturecol == nullptr) renderwall = false; @@ -134,7 +133,7 @@ namespace swrenderer } if (renderwall) - notrelevant = RenderWall(ds, x1, x2, basecolormap, columndrawerargs, visible, lightlevel, foggy); + notrelevant = RenderWall(ds, x1, x2, columndrawerargs, visible); if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls()) { @@ -147,7 +146,7 @@ namespace swrenderer } } - bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, FDynamicColormap *basecolormap, SpriteDrawerArgs &columndrawerargs, bool visible, int lightlevel, bool foggy) + bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible) { auto renderstyle = DefaultRenderStyle(); auto viewport = Thread->Viewport.get(); @@ -320,7 +319,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { if (needslight) - columndrawerargs.SetLight(rw_light, lightlevel, foggy, Thread->Viewport.get()); + columndrawerargs.SetLight(mLight.light, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY); double sprtopscreen; @@ -331,7 +330,7 @@ namespace swrenderer columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, renderstyle); - rw_light += rw_lightstep; + mLight.light += mLight.lightstep; spryscale += rw_scalestep; } } @@ -399,14 +398,14 @@ namespace swrenderer bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0; RenderWallPart renderWallpart(Thread); - renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, additive, alpha, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); + renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, additive, alpha, rw_offset, mLight, nullptr); } return false; } // kg3D - render one fake wall - void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int lightlevel, FDynamicColormap *basecolormap, double clipTop, double clipBottom, FSoftwareTexture *rw_pic) + void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic) { int i; double xscale; @@ -416,8 +415,8 @@ namespace swrenderer if (Alpha <= 0) return; - rw_lightstep = ds->lightstep; - rw_light = ds->light + (x1 - ds->x1) * rw_lightstep; + mLight.lightstep = ds->lightstep; + mLight.light = ds->light + (x1 - ds->x1) * mLight.lightstep; const short *mfloorclip = ds->sprbottomclip - ds->x1; const short *mceilingclip = ds->sprtopclip - ds->x1; @@ -501,9 +500,9 @@ namespace swrenderer GetMaskedWallTopBottom(ds, top, bot); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); + renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, rw_offset, mLight, nullptr); - RenderDecal::RenderDecals(Thread, curline->sidedef, ds, lightlevel, rw_light, rw_lightstep, curline, WallC, ds->foggy, basecolormap, wallupper.ScreenY, walllower.ScreenY, true); + RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, WallC, mLight, wallupper.ScreenY, walllower.ScreenY, true); } // kg3D - walls of fake floors @@ -696,8 +695,8 @@ namespace swrenderer rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } // correct colors now - FDynamicColormap *basecolormap = nullptr; - int lightlevel = ds->lightlevel; + mLight.basecolormap = nullptr; + mLight.lightlevel = ds->lightlevel; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) { @@ -708,9 +707,9 @@ namespace swrenderer if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - //bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -722,19 +721,19 @@ namespace swrenderer if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - //bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } } } - if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); + if (mLight.basecolormap == nullptr) mLight.basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic && !swimmable_found) { - RenderFakeWall(ds, x1, x2, fover ? fover : rover, lightlevel, basecolormap, clipTop, clipBottom, rw_pic); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic); } break; } @@ -883,8 +882,8 @@ namespace swrenderer rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } // correct colors now - FDynamicColormap *basecolormap = nullptr; - int lightlevel = ds->lightlevel; + mLight.basecolormap = nullptr; + mLight.lightlevel = ds->lightlevel; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) { @@ -895,9 +894,9 @@ namespace swrenderer if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -909,19 +908,19 @@ namespace swrenderer if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } } } - if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); + if (mLight.basecolormap == nullptr) mLight.basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic && !swimmable_found) { - RenderFakeWall(ds, x1, x2, fover ? fover : rover, lightlevel, basecolormap, clipTop, clipBottom, rw_pic); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic); } break; } diff --git a/src/swrenderer/line/r_renderdrawsegment.h b/src/swrenderer/line/r_renderdrawsegment.h index d07ac050f..c6a0a467e 100644 --- a/src/swrenderer/line/r_renderdrawsegment.h +++ b/src/swrenderer/line/r_renderdrawsegment.h @@ -37,9 +37,9 @@ namespace swrenderer RenderThread *Thread = nullptr; private: - bool RenderWall(DrawSegment *ds, int x1, int x2, FDynamicColormap *basecolormap, SpriteDrawerArgs &columndrawerargs, bool visible, int lightlevel, bool foggy); + bool RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible); void ClipMidtex(int x1, int x2); - void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int lightlevel, FDynamicColormap *basecolormap, double clipTop, double clipBottom, FSoftwareTexture *rw_pic); + void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic); void RenderFakeWallRange(DrawSegment *ds, int x1, int x2); void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot); @@ -52,8 +52,8 @@ namespace swrenderer FWallCoords WallC; FWallTmapVals WallT; - float rw_light = 0.0f; - float rw_lightstep = 0.0f; + ProjectedWallLight mLight; + fixed_t rw_offset = 0; ProjectedWallLine wallupper; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 02673f2b9..8bdb57add 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -349,11 +349,11 @@ namespace swrenderer // Textures that aren't masked can use the faster opaque drawer if (!rw_pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive) { - drawerargs.SetStyle(true, false, OPAQUE, basecolormap); + drawerargs.SetStyle(true, false, OPAQUE, mLight.basecolormap); } else { - drawerargs.SetStyle(mask, additive, alpha, basecolormap); + drawerargs.SetStyle(mask, additive, alpha, mLight.basecolormap); } CameraLight *cameraLight = CameraLight::Instance(); @@ -368,8 +368,8 @@ namespace swrenderer double xmagnitude = 1.0; - float curlight = light; - for (int x = x1; x < x2; x++, curlight += lightstep) + float curlight = mLight.light; + for (int x = x1; x < x2; x++, curlight += mLight.lightstep) { int y1 = uwal[x]; int y2 = dwal[x]; @@ -377,7 +377,7 @@ namespace swrenderer continue; if (!fixed) - drawerargs.SetLight(curlight, lightlevel, foggy, Thread->Viewport.get()); + drawerargs.SetLight(curlight, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); @@ -424,8 +424,8 @@ namespace swrenderer } lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - lightlevel = curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL); + mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + mLight.lightlevel = curline->sidedef->GetLightLevel(mLight.foggy, *lit->p_lightlevel, lit->lightsource != NULL); } ProcessNormalWall(up, dwal, texturemid, swal, lwal); @@ -516,7 +516,7 @@ namespace swrenderer } } - void RenderWallPart::Render(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, int lightlevel, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap) + void RenderWallPart::Render(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, fixed_t xoffset, const ProjectedWallLight &light, FLightNode *light_list) { this->x1 = x1; this->x2 = x2; @@ -524,12 +524,8 @@ namespace swrenderer this->curline = curline; this->WallC = WallC; this->yrepeat = yscale; - this->lightlevel = lightlevel; + this->mLight = light; this->xoffset = xoffset; - this->light = light; - this->lightstep = lightstep; - this->foggy = foggy; - this->basecolormap = basecolormap; this->light_list = light_list; this->rw_pic = pic; this->mask = mask; diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h index fa6074b8e..57e5a9540 100644 --- a/src/swrenderer/line/r_walldraw.h +++ b/src/swrenderer/line/r_walldraw.h @@ -63,13 +63,9 @@ namespace swrenderer bool mask, bool additive, fixed_t alpha, - int lightlevel, fixed_t xoffset, - float light, - float lightstep, - FLightNode *light_list, - bool foggy, - FDynamicColormap *basecolormap); + const ProjectedWallLight &light, + FLightNode *light_list); RenderThread *Thread = nullptr; @@ -88,13 +84,10 @@ namespace swrenderer seg_t *curline = nullptr; FWallCoords WallC; + ProjectedWallLight mLight; + double yrepeat = 0.0; - int lightlevel = 0; fixed_t xoffset = 0; - float light = 0.0f; - float lightstep = 0.0f; - bool foggy = false; - FDynamicColormap *basecolormap = nullptr; FLightNode *light_list = nullptr; bool mask = false; bool additive = false; diff --git a/src/swrenderer/line/r_wallsetup.h b/src/swrenderer/line/r_wallsetup.h index f0035fa43..11a356f81 100644 --- a/src/swrenderer/line/r_wallsetup.h +++ b/src/swrenderer/line/r_wallsetup.h @@ -56,4 +56,16 @@ namespace swrenderer void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); void ProjectPos(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); }; + + class ProjectedWallLight + { + public: + int lightlevel; + bool foggy; + FDynamicColormap *basecolormap; + + float lightleft; + float lightstep; + float light; + }; } diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index db42a0a2e..189f2b59c 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -57,15 +57,15 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) { for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) { - Render(thread, sidedef, decal, draw_segment, lightlevel, lightleft, lightstep, curline, wallC, foggy, basecolormap, walltop, wallbottom, drawsegPass); + Render(thread, sidedef, decal, draw_segment, curline, wallC, light, walltop, wallbottom, drawsegPass); } } - void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, seg_t *curline, const FWallCoords &savecoord, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) { DVector2 decal_left, decal_right, decal_pos; int x1, x2; @@ -75,7 +75,6 @@ namespace swrenderer int needrepeat = 0; sector_t *back; FDynamicColormap *usecolormap; - float light = 0; const short *mfloorclip; const short *mceilingclip; @@ -257,7 +256,7 @@ namespace swrenderer } // Prepare lighting - usecolormap = basecolormap; + usecolormap = light.basecolormap; // Decals that are added to the scene must fade to black. if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0) @@ -265,7 +264,7 @@ namespace swrenderer usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate); } - light = lightleft + (x1 - savecoord.sx1) * lightstep; + float lightpos = light.lightleft + (x1 - savecoord.sx1) * light.lightstep; cameraLight = CameraLight::Instance(); @@ -288,7 +287,7 @@ namespace swrenderer int x = x1; ColormapLight cmlight; - cmlight.SetColormap(thread, MINZ, lightlevel, foggy, usecolormap, decal->RenderFlags & RF_FULLBRIGHT, false, false, false, false); + cmlight.SetColormap(thread, MINZ, light.lightlevel, light.foggy, usecolormap, decal->RenderFlags & RF_FULLBRIGHT, false, false, false, false); SpriteDrawerArgs drawerargs; bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight); @@ -301,10 +300,10 @@ namespace swrenderer { if (calclighting) { // calculate lighting - drawerargs.SetLight(light, lightlevel, foggy, thread->Viewport.get()); + drawerargs.SetLight(lightpos, light.lightlevel, light.foggy, thread->Viewport.get()); } DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); - light += lightstep; + lightpos += light.lightstep; x++; } } diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index 3fe3956b1..79379df21 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -12,10 +12,10 @@ namespace swrenderer class RenderDecal { public: - static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass); + static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); private: - static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass); + static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); }; } From c0a4ba5e82f6e21ef7d4621ee3709ff964ce2bfb Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 27 Dec 2018 22:52:33 +0100 Subject: [PATCH 4/9] - Simplify ProjectedWallLight light step setup and positioning --- src/swrenderer/line/r_line.cpp | 25 ++++----------------- src/swrenderer/line/r_renderdrawsegment.cpp | 15 ++++++------- src/swrenderer/line/r_walldraw.cpp | 4 ++-- src/swrenderer/line/r_wallsetup.cpp | 20 +++++++++++++++++ src/swrenderer/line/r_wallsetup.h | 9 +++++++- src/swrenderer/things/r_decal.cpp | 10 ++++----- src/swrenderer/things/r_decal.h | 4 ++-- 7 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 52277204e..22dd1472d 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -490,8 +490,8 @@ namespace swrenderer draw_segment->iscalestep = 0; } } - draw_segment->light = mLight.lightleft + mLight.lightstep * (start - WallC.sx1); - draw_segment->lightstep = mLight.lightstep; + draw_segment->light = mLight.GetLightPos(start); + draw_segment->lightstep = mLight.GetLightStep(); // Masked mMiddlePart.Textures should get the light level from the sector they reference, // not from the current subsector, which is what the current lightlevel value @@ -552,7 +552,7 @@ namespace swrenderer // [ZZ] Only if not an active mirror if (!markportal) { - RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, mLineSegment, WallC, mLight, walltop.ScreenY, wallbottom.ScreenY, false); + RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, mLineSegment, mLight, walltop.ScreenY, wallbottom.ScreenY, false); } if (markportal) @@ -786,18 +786,7 @@ namespace swrenderer walltexcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT); - CameraLight *cameraLight = CameraLight::Instance(); - if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) - { - mLight.lightlevel = mLineSegment->sidedef->GetLightLevel(mLight.foggy, mFrontSector->lightlevel); - mLight.lightleft = float(Thread->Light->WallVis(WallC.sz1, mLight.foggy)); - mLight.lightstep = float((Thread->Light->WallVis(WallC.sz2, mLight.foggy) - mLight.lightleft) / (WallC.sx2 - WallC.sx1)); - } - else - { - mLight.lightleft = 1; - mLight.lightstep = 0; - } + mLight.SetLightLeft(Thread, mLineSegment, mFrontSector, WallC); } } @@ -1164,8 +1153,6 @@ namespace swrenderer offset = -offset; } - mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); - RenderWallPart renderWallpart(Thread); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } @@ -1197,8 +1184,6 @@ namespace swrenderer offset = -offset; } - mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); - RenderWallPart renderWallpart(Thread); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } @@ -1231,8 +1216,6 @@ namespace swrenderer offset = -offset; } - mLight.light = mLight.lightleft + mLight.lightstep * (x1 - WallC.sx1); - RenderWallPart renderWallpart(Thread); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); } diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 567354cde..f42f47b07 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -83,8 +83,7 @@ namespace swrenderer mLight.basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap mLight.foggy = ds->foggy; mLight.lightlevel = ds->lightlevel; - mLight.lightstep = ds->lightstep; - mLight.light = ds->light + (x1 - ds->x1) * mLight.lightstep; + mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1); Clip3DFloors *clip3d = Thread->Clip3D.get(); @@ -122,7 +121,7 @@ namespace swrenderer const short *mceilingclip = ds->sprtopclip - ds->x1; RenderFogBoundary renderfog; - renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight.lightlevel, ds->foggy, mLight.light, mLight.lightstep, mLight.basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight.lightlevel, ds->foggy, mLight.GetLightPos(x1), mLight.GetLightStep(), mLight.basecolormap); if (ds->maskedtexturecol == nullptr) renderwall = false; @@ -316,10 +315,11 @@ namespace swrenderer if (visible) { Thread->PrepareTexture(tex, renderstyle); + float lightpos = mLight.GetLightPos(x1); for (int x = x1; x < x2; ++x) { if (needslight) - columndrawerargs.SetLight(mLight.light, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); + columndrawerargs.SetLight(lightpos, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY); double sprtopscreen; @@ -330,7 +330,7 @@ namespace swrenderer columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, renderstyle); - mLight.light += mLight.lightstep; + lightpos += mLight.GetLightStep(); spryscale += rw_scalestep; } } @@ -415,8 +415,7 @@ namespace swrenderer if (Alpha <= 0) return; - mLight.lightstep = ds->lightstep; - mLight.light = ds->light + (x1 - ds->x1) * mLight.lightstep; + mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1); const short *mfloorclip = ds->sprbottomclip - ds->x1; const short *mceilingclip = ds->sprtopclip - ds->x1; @@ -502,7 +501,7 @@ namespace swrenderer RenderWallPart renderWallpart(Thread); renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, rw_offset, mLight, nullptr); - RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, WallC, mLight, wallupper.ScreenY, walllower.ScreenY, true); + RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, mLight, wallupper.ScreenY, walllower.ScreenY, true); } // kg3D - walls of fake floors diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 8bdb57add..f9559411e 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -368,8 +368,8 @@ namespace swrenderer double xmagnitude = 1.0; - float curlight = mLight.light; - for (int x = x1; x < x2; x++, curlight += mLight.lightstep) + float curlight = mLight.GetLightPos(x1); + for (int x = x1; x < x2; x++, curlight += mLight.GetLightStep()) { int y1 = uwal[x]; int y2 = dwal[x]; diff --git a/src/swrenderer/line/r_wallsetup.cpp b/src/swrenderer/line/r_wallsetup.cpp index b910bfec8..a7b1c91ea 100644 --- a/src/swrenderer/line/r_wallsetup.cpp +++ b/src/swrenderer/line/r_wallsetup.cpp @@ -241,4 +241,24 @@ namespace swrenderer } } } + + ///////////////////////////////////////////////////////////////////////// + + void ProjectedWallLight::SetLightLeft(RenderThread *thread, seg_t *lineseg, sector_t *frontsector, const FWallCoords &wallc) + { + x1 = wallc.sx1; + + CameraLight *cameraLight = CameraLight::Instance(); + if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) + { + lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel); + lightleft = float(thread->Light->WallVis(wallc.sz1, foggy)); + lightstep = float((thread->Light->WallVis(wallc.sz2, foggy) - lightleft) / (wallc.sx2 - wallc.sx1)); + } + else + { + lightleft = 1; + lightstep = 0; + } + } } diff --git a/src/swrenderer/line/r_wallsetup.h b/src/swrenderer/line/r_wallsetup.h index 11a356f81..53ca73897 100644 --- a/src/swrenderer/line/r_wallsetup.h +++ b/src/swrenderer/line/r_wallsetup.h @@ -64,8 +64,15 @@ namespace swrenderer bool foggy; FDynamicColormap *basecolormap; + float GetLightPos(int x) const { return lightleft + lightstep * (x - x1); } + float GetLightStep() const { return lightstep; } + + void SetLightLeft(float left, float step, int startx) { lightleft = left; lightstep = step; x1 = startx; } + void SetLightLeft(RenderThread *thread, seg_t *lineseg, sector_t *frontsector, const FWallCoords &wallc); + + private: + int x1; float lightleft; float lightstep; - float light; }; } diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 189f2b59c..227bb5aa2 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -57,15 +57,15 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) { for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) { - Render(thread, sidedef, decal, draw_segment, curline, wallC, light, walltop, wallbottom, drawsegPass); + Render(thread, sidedef, decal, draw_segment, curline, light, walltop, wallbottom, drawsegPass); } } - void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, seg_t *curline, const FWallCoords &savecoord, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass) { DVector2 decal_left, decal_right, decal_pos; int x1, x2; @@ -264,7 +264,7 @@ namespace swrenderer usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate); } - float lightpos = light.lightleft + (x1 - savecoord.sx1) * light.lightstep; + float lightpos = light.GetLightPos(x1); cameraLight = CameraLight::Instance(); @@ -303,7 +303,7 @@ namespace swrenderer drawerargs.SetLight(lightpos, light.lightlevel, light.foggy, thread->Viewport.get()); } DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); - lightpos += light.lightstep; + lightpos += light.GetLightStep(); x++; } } diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index 79379df21..69a97f6d0 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -12,10 +12,10 @@ namespace swrenderer class RenderDecal { public: - static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); + static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); private: - static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const FWallCoords &wallC, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); + static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass); static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); }; } From 4d3d4ea746e6e91cd06703bfb3aaba7c4359e6f7 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 28 Dec 2018 00:55:44 +0100 Subject: [PATCH 5/9] - simplify colormap selection to a single function --- src/swrenderer/line/r_fogboundary.cpp | 11 +- src/swrenderer/line/r_fogboundary.h | 2 +- src/swrenderer/line/r_line.cpp | 77 +++++----- src/swrenderer/line/r_line.h | 4 +- src/swrenderer/line/r_renderdrawsegment.cpp | 150 +++++++++----------- src/swrenderer/line/r_walldraw.cpp | 10 +- src/swrenderer/line/r_wallsetup.cpp | 23 ++- src/swrenderer/line/r_wallsetup.h | 14 +- src/swrenderer/scene/r_opaque_pass.cpp | 18 ++- src/swrenderer/scene/r_opaque_pass.h | 4 +- src/swrenderer/scene/r_portal.cpp | 1 - src/swrenderer/segments/r_drawsegment.h | 2 - src/swrenderer/things/r_decal.cpp | 6 +- 13 files changed, 159 insertions(+), 163 deletions(-) diff --git a/src/swrenderer/line/r_fogboundary.cpp b/src/swrenderer/line/r_fogboundary.cpp index ab970d8e0..8a20b9028 100644 --- a/src/swrenderer/line/r_fogboundary.cpp +++ b/src/swrenderer/line/r_fogboundary.cpp @@ -54,19 +54,20 @@ namespace swrenderer { - void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int lightlevel, bool foggy, float lightleft, float lightstep, FDynamicColormap *basecolormap) + void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, const ProjectedWallLight &wallLight) { // 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. - int wallshade = LightVisibility::LightLevelToShade(lightlevel, foggy, thread->Viewport.get()); - float light = lightleft + lightstep*(x2 - x1 - 1); + int wallshade = LightVisibility::LightLevelToShade(wallLight.GetLightLevel(), wallLight.GetFoggy(), thread->Viewport.get()); int x = x2 - 1; int t2 = uclip[x]; int b2 = dclip[x]; + float light = wallLight.GetLightPos(x); int rcolormap = GETPALOOKUP(light, wallshade); int lcolormap; + FDynamicColormap *basecolormap = wallLight.GetBaseColormap(); uint8_t *basecolormapdata = basecolormap->Maps; if (b2 > t2) @@ -75,7 +76,7 @@ namespace swrenderer } drawerargs.SetBaseColormap(basecolormap); - drawerargs.SetLight(light, lightlevel, foggy, thread->Viewport.get()); + drawerargs.SetLight(light, wallLight.GetLightLevel(), wallLight.GetFoggy(), thread->Viewport.get()); uint8_t *fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); @@ -86,7 +87,7 @@ namespace swrenderer const int xr = x + 1; int stop; - light -= lightstep; + light -= wallLight.GetLightStep(); lcolormap = GETPALOOKUP(light, wallshade); if (lcolormap != rcolormap) { diff --git a/src/swrenderer/line/r_fogboundary.h b/src/swrenderer/line/r_fogboundary.h index 3da57d583..a98f96996 100644 --- a/src/swrenderer/line/r_fogboundary.h +++ b/src/swrenderer/line/r_fogboundary.h @@ -31,7 +31,7 @@ namespace swrenderer class RenderFogBoundary { public: - void Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int lightlevel, bool foggy, float lightleft, float lightstep, FDynamicColormap *basecolormap); + void Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, const ProjectedWallLight &wallLight); private: void RenderSection(RenderThread *thread, int y, int y2, int x1); diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 22dd1472d..fba3868bd 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -71,15 +71,13 @@ namespace swrenderer Thread = thread; } - void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap, Fake3DOpaque opaque3dfloor) + void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor) { mSubsector = subsector; mFrontSector = sector; mBackSector = fakebacksector; mFloorPlane = linefloorplane; mCeilingPlane = lineceilingplane; - mLight.foggy = infog; - mLight.basecolormap = colormap; mLineSegment = line; m3DFloor = opaque3dfloor; @@ -314,7 +312,7 @@ namespace swrenderer if (!rw_prepped) { rw_prepped = true; - SetWallVariables(true); + SetWallVariables(); } side_t *sidedef = mLineSegment->sidedef; @@ -326,8 +324,7 @@ namespace swrenderer // 3D floors code abuses the line render code to update plane clipping // lists but doesn't actually draw anything. - bool onlyUpdatePlaneClip = (m3DFloor.type != Fake3DOpaque::Normal); - if (!onlyUpdatePlaneClip) + if (m3DFloor.type == Fake3DOpaque::Normal) Thread->DrawSegments->Push(draw_segment); draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq; @@ -345,7 +342,6 @@ namespace swrenderer draw_segment->x1 = start; draw_segment->x2 = stop; draw_segment->curline = mLineSegment; - draw_segment->foggy = mLight.foggy; draw_segment->SubsectorDepth = Thread->OpaquePass->GetSubsectorDepth(mSubsector->Index()); bool markportal = ShouldMarkPortal(); @@ -400,29 +396,30 @@ namespace swrenderer } } - if (!onlyUpdatePlaneClip && r_3dfloors) + if (m3DFloor.type == Fake3DOpaque::Normal) { - if (mBackSector->e && mBackSector->e->XFloor.ffloors.Size()) { - for (i = 0; i < (int)mBackSector->e->XFloor.ffloors.Size(); i++) { - F3DFloor *rover = mBackSector->e->XFloor.ffloors[i]; - if (rover->flags & FF_RENDERSIDES && (!(rover->flags & FF_INVERTSIDES) || rover->flags & FF_ALLSIDES)) { - draw_segment->SetHas3DFloorBackSectorWalls(); - break; + if (r_3dfloors) + { + if (mBackSector->e && mBackSector->e->XFloor.ffloors.Size()) { + for (i = 0; i < (int)mBackSector->e->XFloor.ffloors.Size(); i++) { + F3DFloor *rover = mBackSector->e->XFloor.ffloors[i]; + if (rover->flags & FF_RENDERSIDES && (!(rover->flags & FF_INVERTSIDES) || rover->flags & FF_ALLSIDES)) { + draw_segment->SetHas3DFloorBackSectorWalls(); + break; + } + } + } + if (mFrontSector->e && mFrontSector->e->XFloor.ffloors.Size()) { + for (i = 0; i < (int)mFrontSector->e->XFloor.ffloors.Size(); i++) { + F3DFloor *rover = mFrontSector->e->XFloor.ffloors[i]; + if (rover->flags & FF_RENDERSIDES && (rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) { + draw_segment->SetHas3DFloorFrontSectorWalls(); + break; + } } } } - if (mFrontSector->e && mFrontSector->e->XFloor.ffloors.Size()) { - for (i = 0; i < (int)mFrontSector->e->XFloor.ffloors.Size(); i++) { - F3DFloor *rover = mFrontSector->e->XFloor.ffloors[i]; - if (rover->flags & FF_RENDERSIDES && (rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) { - draw_segment->SetHas3DFloorFrontSectorWalls(); - break; - } - } - } - } - if (!onlyUpdatePlaneClip) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. if ((sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls() || IsFogBoundary(mFrontSector, mBackSector)) && @@ -452,8 +449,8 @@ namespace swrenderer lwal = draw_segment->maskedtexturecol; swal = draw_segment->swall; FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); - FSoftwareTexture *pic = tex && tex->isValid()? tex->GetSoftwareTexture() : nullptr; - double yscale = (pic? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid); + FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; + double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); if (pic && pic->useWorldPanning()) @@ -490,27 +487,16 @@ namespace swrenderer draw_segment->iscalestep = 0; } } + draw_segment->light = mLight.GetLightPos(start); draw_segment->lightstep = mLight.GetLightStep(); - // Masked mMiddlePart.Textures should get the light level from the sector they reference, - // not from the current subsector, which is what the current lightlevel value - // comes from. We make an exeption for polyobjects, however, since their "home" - // sector should be whichever one they move into. - if (mLineSegment->sidedef->Flags & WALLF_POLYOBJ) - { - draw_segment->lightlevel = mLight.lightlevel; - } - else - { - draw_segment->lightlevel = mLineSegment->sidedef->GetLightLevel(mLight.foggy, mLineSegment->frontsector->lightlevel); - } - if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) { Thread->DrawSegments->PushTranslucent(draw_segment); } } + } } ClipSegmentTopBottom(start, stop); @@ -700,7 +686,7 @@ namespace swrenderer } } - void SWRenderLine::SetWallVariables(bool needlights) + void SWRenderLine::SetWallVariables() { RenderPortal *renderportal = Thread->Portal.get(); @@ -775,8 +761,13 @@ namespace swrenderer bool segtextured = ftex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL; + if (m3DFloor.type == Fake3DOpaque::Normal) + { + mLight.SetColormap(mFrontSector, mLineSegment); + } + // calculate light table - if (needlights && (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector)))) + if (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector))) { lwallscale = ftex ? ((midtex? midtex->GetScale().X : 1.0) * sidedef->GetTextureXScale(side_t::mid)) : @@ -786,7 +777,7 @@ namespace swrenderer walltexcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT); - mLight.SetLightLeft(Thread, mLineSegment, mFrontSector, WallC); + mLight.SetLightLeft(Thread, WallC); } } diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index 900dfe98f..95ef84f7e 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -72,13 +72,13 @@ namespace swrenderer { public: SWRenderLine(RenderThread *thread); - void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque fake3DOpaque); + void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, Fake3DOpaque fake3DOpaque); RenderThread *Thread = nullptr; private: bool RenderWallSegment(int x1, int x2) override; - void SetWallVariables(bool needlights); + void SetWallVariables(); void SetTopTexture(); void SetMiddleTexture(); void SetBottomTexture(); diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index f42f47b07..8b8dd361f 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -80,9 +80,7 @@ namespace swrenderer sector_t tempsec; const sector_t *sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); - mLight.basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap - mLight.foggy = ds->foggy; - mLight.lightlevel = ds->lightlevel; + mLight.SetColormap(sec, curline); mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1); Clip3DFloors *clip3d = Thread->Clip3D.get(); @@ -92,10 +90,7 @@ namespace swrenderer { if (clipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) { - lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]); break; } } @@ -105,7 +100,7 @@ namespace swrenderer SpriteDrawerArgs columndrawerargs; ColormapLight cmlight; - cmlight.SetColormap(Thread, MINZ, mLight.lightlevel, mLight.foggy, mLight.basecolormap, false, false, false, false, false); + cmlight.SetColormap(Thread, MINZ, mLight.GetLightLevel(), mLight.GetFoggy(), mLight.GetBaseColormap(), false, false, false, false, false); bool visible = columndrawerargs.SetStyle(viewport, LegacyRenderStyles[additive ? STYLE_Add : STYLE_Translucent], alpha, 0, 0, cmlight); if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls()) { @@ -121,7 +116,7 @@ namespace swrenderer const short *mceilingclip = ds->sprtopclip - ds->x1; RenderFogBoundary renderfog; - renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight.lightlevel, ds->foggy, mLight.GetLightPos(x1), mLight.GetLightStep(), mLight.basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight); if (ds->maskedtexturecol == nullptr) renderwall = false; @@ -319,7 +314,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { if (needslight) - columndrawerargs.SetLight(lightpos, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); + columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get()); fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY); double sprtopscreen; @@ -693,45 +688,41 @@ namespace swrenderer } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } - // correct colors now - mLight.basecolormap = nullptr; - mLight.lightlevel = ds->lightlevel; - CameraLight *cameraLight = CameraLight::Instance(); - if (cameraLight->FixedLightLevel() < 0) - { - if (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls()) - { - for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) - { - if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) - { - lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); - break; - } - } - } - else - { - for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) - { - if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) - { - lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); - break; - } - } - } - } - if (mLight.basecolormap == nullptr) mLight.basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic && !swimmable_found) { + // correct colors now + lightlist_t *lit = nullptr; + CameraLight *cameraLight = CameraLight::Instance(); + if (cameraLight->FixedLightLevel() < 0) + { + if (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls()) + { + for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) + { + if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) + { + lit = &backsector->e->XFloor.lightlist[j]; + break; + } + } + } + else + { + for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) + { + if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) + { + lit = &frontsector->e->XFloor.lightlist[j]; + break; + } + } + } + } + + //mLight.lightlevel = ds->lightlevel; + mLight.SetColormap(frontsector, curline, lit); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic); } break; @@ -880,45 +871,40 @@ namespace swrenderer } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } - // correct colors now - mLight.basecolormap = nullptr; - mLight.lightlevel = ds->lightlevel; - CameraLight *cameraLight = CameraLight::Instance(); - if (cameraLight->FixedLightLevel() < 0) - { - if (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls()) - { - for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) - { - if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) - { - lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); - break; - } - } - } - else - { - for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) - { - if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) - { - lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.foggy = (level.fadeto || mLight.basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - mLight.lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); - break; - } - } - } - } - if (mLight.basecolormap == nullptr) mLight.basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic && !swimmable_found) { + // correct colors now + lightlist_t *lit = nullptr; + CameraLight *cameraLight = CameraLight::Instance(); + if (cameraLight->FixedLightLevel() < 0) + { + if (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls()) + { + for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) + { + if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) + { + lit = &backsector->e->XFloor.lightlist[j]; + break; + } + } + } + else + { + for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) + { + if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) + { + lit = &frontsector->e->XFloor.lightlist[j]; + break; + } + } + } + } + //mLight.lightlevel = ds->lightlevel; + mLight.SetColormap(frontsector, curline, lit); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic); } break; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index f9559411e..b7405736d 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -349,11 +349,11 @@ namespace swrenderer // Textures that aren't masked can use the faster opaque drawer if (!rw_pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive) { - drawerargs.SetStyle(true, false, OPAQUE, mLight.basecolormap); + drawerargs.SetStyle(true, false, OPAQUE, mLight.GetBaseColormap()); } else { - drawerargs.SetStyle(mask, additive, alpha, mLight.basecolormap); + drawerargs.SetStyle(mask, additive, alpha, mLight.GetBaseColormap()); } CameraLight *cameraLight = CameraLight::Instance(); @@ -377,7 +377,7 @@ namespace swrenderer continue; if (!fixed) - drawerargs.SetLight(curlight, mLight.lightlevel, mLight.foggy, Thread->Viewport.get()); + drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get()); if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); @@ -423,9 +423,7 @@ namespace swrenderer down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY; } - lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - mLight.basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - mLight.lightlevel = curline->sidedef->GetLightLevel(mLight.foggy, *lit->p_lightlevel, lit->lightsource != NULL); + mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]); } ProcessNormalWall(up, dwal, texturemid, swal, lwal); diff --git a/src/swrenderer/line/r_wallsetup.cpp b/src/swrenderer/line/r_wallsetup.cpp index a7b1c91ea..87c491b67 100644 --- a/src/swrenderer/line/r_wallsetup.cpp +++ b/src/swrenderer/line/r_wallsetup.cpp @@ -244,14 +244,13 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - void ProjectedWallLight::SetLightLeft(RenderThread *thread, seg_t *lineseg, sector_t *frontsector, const FWallCoords &wallc) + void ProjectedWallLight::SetLightLeft(RenderThread *thread, const FWallCoords &wallc) { x1 = wallc.sx1; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { - lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel); lightleft = float(thread->Light->WallVis(wallc.sz1, foggy)); lightstep = float((thread->Light->WallVis(wallc.sz2, foggy) - lightleft) / (wallc.sx2 - wallc.sx1)); } @@ -261,4 +260,24 @@ namespace swrenderer lightstep = 0; } } + + void ProjectedWallLight::SetColormap(const sector_t *frontsector, seg_t *lineseg, lightlist_t *lit) + { + if (!lit) + { + basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); + foggy = level.fadeto || frontsector->Colormap.FadeColor || (level.flags & LEVEL_HASFADETABLE); + + if (!(lineseg->sidedef->Flags & WALLF_POLYOBJ)) + lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel); + else + lightlevel = frontsector->GetLightLevel(); + } + else + { + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); + foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE); + lightlevel = lineseg->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != nullptr); + } + } } diff --git a/src/swrenderer/line/r_wallsetup.h b/src/swrenderer/line/r_wallsetup.h index 53ca73897..46bee0def 100644 --- a/src/swrenderer/line/r_wallsetup.h +++ b/src/swrenderer/line/r_wallsetup.h @@ -60,17 +60,23 @@ namespace swrenderer class ProjectedWallLight { public: - int lightlevel; - bool foggy; - FDynamicColormap *basecolormap; + int GetLightLevel() const { return lightlevel; } + bool GetFoggy() const { return foggy; } + FDynamicColormap *GetBaseColormap() const { return basecolormap; } float GetLightPos(int x) const { return lightleft + lightstep * (x - x1); } float GetLightStep() const { return lightstep; } + void SetColormap(const sector_t *frontsector, seg_t *lineseg, lightlist_t *lit = nullptr); + void SetLightLeft(float left, float step, int startx) { lightleft = left; lightstep = step; x1 = startx; } - void SetLightLeft(RenderThread *thread, seg_t *lineseg, sector_t *frontsector, const FWallCoords &wallc); + void SetLightLeft(RenderThread *thread, const FWallCoords &wallc); private: + int lightlevel; + bool foggy; + FDynamicColormap *basecolormap; + int x1; float lightleft; float lightstep; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 30f656296..115d37daf 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -451,7 +451,7 @@ namespace swrenderer } // kg3D - add fake segs, never rendered - void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, sector_t *frontsector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor) + void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, sector_t *frontsector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, Fake3DOpaque opaque3dfloor) { int count; seg_t* line; @@ -463,7 +463,7 @@ namespace swrenderer { if ((line->sidedef) && !(line->sidedef->Flags & WALLF_POLYOBJ)) { - renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, opaque3dfloor); + renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, opaque3dfloor); } line++; } @@ -622,8 +622,6 @@ namespace swrenderer DVector2 viewpointPos = Thread->Viewport->viewpoint.Pos.XY(); - basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); - seg_t *line = sub->firstline; int count = sub->numlines; while (count--) @@ -637,8 +635,8 @@ namespace swrenderer } else if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) { - Add3DFloorLine(line, frontsector, basecolormap, foggy); - renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::Normal); // now real + Add3DFloorLine(line, frontsector); + renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, Fake3DOpaque::Normal); // now real } line++; } @@ -648,7 +646,7 @@ namespace swrenderer } } - void RenderOpaquePass::Add3DFloorLine(seg_t *line, sector_t *frontsector, FDynamicColormap *basecolormap, bool foggy) + void RenderOpaquePass::Add3DFloorLine(seg_t *line, sector_t *frontsector) { // kg3D - fake planes bounding calculation if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size()) @@ -669,7 +667,7 @@ namespace swrenderer clip3d->fakeFloor->validcount = validcount; clip3d->NewClip(); } - renderline.Render(line, InSubsector, frontsector, &tempsec, nullptr, nullptr, foggy, basecolormap, opaque3dfloor); // fake + renderline.Render(line, InSubsector, frontsector, &tempsec, nullptr, nullptr, opaque3dfloor); // fake } clip3d->fakeFloor = nullptr; } @@ -744,7 +742,7 @@ namespace swrenderer floorplane3d->AddLights(Thread, sub->section->lighthead); - FakeDrawLoop(sub, &tempsec, floorplane3d, nullptr, foggy, basecolormap, Fake3DOpaque::FakeFloor); + FakeDrawLoop(sub, &tempsec, floorplane3d, nullptr, Fake3DOpaque::FakeFloor); } } // and now ceilings @@ -812,7 +810,7 @@ namespace swrenderer ceilingplane3d->AddLights(Thread, sub->section->lighthead); - FakeDrawLoop(sub, &tempsec, nullptr, ceilingplane3d, foggy, basecolormap, Fake3DOpaque::FakeCeiling); + FakeDrawLoop(sub, &tempsec, nullptr, ceilingplane3d, Fake3DOpaque::FakeCeiling); } } clip3d->fakeFloor = nullptr; diff --git a/src/swrenderer/scene/r_opaque_pass.h b/src/swrenderer/scene/r_opaque_pass.h index 92cb352dc..a02b1d6dd 100644 --- a/src/swrenderer/scene/r_opaque_pass.h +++ b/src/swrenderer/scene/r_opaque_pass.h @@ -86,8 +86,8 @@ namespace swrenderer void AddPolyobjs(subsector_t *sub); void Add3DFloorPlanes(subsector_t *sub, sector_t *frontsector, FDynamicColormap *basecolormap, bool foggy, int adjusted_ceilinglightlevel, int adjusted_floorlightlevel); - void FakeDrawLoop(subsector_t *sub, sector_t *frontsector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor); - void Add3DFloorLine(seg_t *line, sector_t *frontsector, FDynamicColormap *basecolormap, bool foggy); + void FakeDrawLoop(subsector_t *sub, sector_t *frontsector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, Fake3DOpaque opaque3dfloor); + void Add3DFloorLine(seg_t *line, sector_t *frontsector); void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap); bool IsPotentiallyVisible(AActor *thing); diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index b56ddc457..a13df7ebb 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -219,7 +219,6 @@ namespace swrenderer draw_segment->swall = nullptr; draw_segment->bFogBoundary = false; draw_segment->curline = nullptr; - draw_segment->foggy = false; memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short)); memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short)); drawseglist->Push(draw_segment); diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h index 8df4153ca..d489bfcda 100644 --- a/src/swrenderer/segments/r_drawsegment.h +++ b/src/swrenderer/segments/r_drawsegment.h @@ -38,8 +38,6 @@ namespace swrenderer float yscale; uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both bool bFogBoundary = false; - int lightlevel = 0; - bool foggy = false; // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. short *sprtopclip = nullptr; diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 227bb5aa2..4340358ea 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -256,7 +256,7 @@ namespace swrenderer } // Prepare lighting - usecolormap = light.basecolormap; + usecolormap = light.GetBaseColormap(); // Decals that are added to the scene must fade to black. if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0) @@ -287,7 +287,7 @@ namespace swrenderer int x = x1; ColormapLight cmlight; - cmlight.SetColormap(thread, MINZ, light.lightlevel, light.foggy, usecolormap, decal->RenderFlags & RF_FULLBRIGHT, false, false, false, false); + cmlight.SetColormap(thread, MINZ, light.GetLightLevel(), light.GetFoggy(), usecolormap, decal->RenderFlags & RF_FULLBRIGHT, false, false, false, false); SpriteDrawerArgs drawerargs; bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight); @@ -300,7 +300,7 @@ namespace swrenderer { if (calclighting) { // calculate lighting - drawerargs.SetLight(lightpos, light.lightlevel, light.foggy, thread->Viewport.get()); + drawerargs.SetLight(lightpos, light.GetLightLevel(), light.GetFoggy(), thread->Viewport.get()); } DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); lightpos += light.GetLightStep(); From 45d3df9df199b64c96a28df2acbc222765865a98 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 28 Dec 2018 01:13:58 +0100 Subject: [PATCH 6/9] - remove pointless duplication of FWallCoords member variables --- src/swrenderer/line/r_line.cpp | 11 +------- src/swrenderer/line/r_renderdrawsegment.cpp | 31 ++++++++------------- src/swrenderer/scene/r_portal.cpp | 6 ++-- src/swrenderer/segments/r_drawsegment.cpp | 12 ++++---- src/swrenderer/segments/r_drawsegment.h | 5 +--- src/swrenderer/things/r_particle.cpp | 4 ++- src/swrenderer/things/r_visiblesprite.cpp | 8 +++--- 7 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index fba3868bd..528da5d6e 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -328,17 +328,8 @@ namespace swrenderer Thread->DrawSegments->Push(draw_segment); draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq; - draw_segment->sx1 = WallC.sx1; - draw_segment->sx2 = WallC.sx2; - draw_segment->sz1 = WallC.sz1; - draw_segment->sz2 = WallC.sz2; - draw_segment->cx = WallC.tleft.X; - draw_segment->cy = WallC.tleft.Y; - draw_segment->cdx = WallC.tright.X - WallC.tleft.X; - draw_segment->cdy = WallC.tright.Y - WallC.tleft.Y; + draw_segment->WallC = WallC; draw_segment->tmapvals = WallT; - draw_segment->siz1 = 1 / WallC.sz1; - draw_segment->siz2 = 1 / WallC.sz2; draw_segment->x1 = start; draw_segment->x2 = stop; draw_segment->curline = mLineSegment; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 8b8dd361f..4f404dcb2 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -219,12 +219,12 @@ namespace swrenderer } // [RH] Don't bother drawing segs that are completely offscreen - if (viewport->globaldclip * ds->sz1 < -textop && viewport->globaldclip * ds->sz2 < -textop) + if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop) { // Texture top is below the bottom of the screen return false; } - if (viewport->globaluclip * ds->sz1 > texheight - textop && viewport->globaluclip * ds->sz2 > texheight - textop) + if (viewport->globaluclip * ds->WallC.sz1 > texheight - textop && viewport->globaluclip * ds->WallC.sz2 > texheight - textop) { // Texture bottom is above the top of the screen return false; } @@ -238,10 +238,10 @@ namespace swrenderer return true; } - WallC.sz1 = ds->sz1; - WallC.sz2 = ds->sz2; - WallC.sx1 = ds->sx1; - WallC.sx2 = ds->sx2; + WallC.sz1 = ds->WallC.sz1; + WallC.sz2 = ds->WallC.sz2; + WallC.sx1 = ds->WallC.sx1; + WallC.sx2 = ds->WallC.sx2; // Unclipped vanilla Doom range for the wall. Relies on ceiling/floor clip to clamp the wall in range. double ceilZ = textop; @@ -345,10 +345,10 @@ namespace swrenderer texturemid = (texturemid - Thread->Viewport->viewpoint.Pos.Z) * MaskedScaleY + rowoffset; } - WallC.sz1 = ds->sz1; - WallC.sz2 = ds->sz2; - WallC.sx1 = ds->sx1; - WallC.sx2 = ds->sx2; + WallC.sz1 = ds->WallC.sz1; + WallC.sz2 = ds->WallC.sz2; + WallC.sx1 = ds->WallC.sx1; + WallC.sx2 = ds->WallC.sx2; if (clip3d->CurrentSkybox) { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor @@ -462,14 +462,7 @@ namespace swrenderer texturemid += rowoffset; } - WallC.sz1 = ds->sz1; - WallC.sz2 = ds->sz2; - WallC.sx1 = ds->sx1; - WallC.sx2 = ds->sx2; - WallC.tleft.X = ds->cx; - WallC.tleft.Y = ds->cy; - WallC.tright.X = ds->cx + ds->cdx; - WallC.tright.Y = ds->cy + ds->cdy; + WallC = ds->WallC; WallT = ds->tmapvals; Clip3DFloors *clip3d = Thread->Clip3D.get(); @@ -488,7 +481,7 @@ namespace swrenderer } ProjectedWallTexcoords walltexcoords; - walltexcoords.ProjectPos(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2, WallT); + walltexcoords.ProjectPos(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->WallC.sx1, ds->WallC.sx2, WallT); double top, bot; GetMaskedWallTopBottom(ds, top, bot); diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index a13df7ebb..61fc4fc3a 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -206,10 +206,8 @@ namespace swrenderer // Create a drawseg to clip sprites to the sky plane DrawSegment *draw_segment = Thread->FrameMemory->NewObject(); draw_segment->CurrentPortalUniq = CurrentPortalUniq; - draw_segment->siz1 = INT_MAX; - draw_segment->siz2 = INT_MAX; - draw_segment->sz1 = 0; - draw_segment->sz2 = 0; + draw_segment->WallC.sz1 = 0; + draw_segment->WallC.sz2 = 0; draw_segment->x1 = pl->left; draw_segment->x2 = pl->right; draw_segment->silhouette = SIL_BOTH; diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp index 76b13df97..a613ce60f 100644 --- a/src/swrenderer/segments/r_drawsegment.cpp +++ b/src/swrenderer/segments/r_drawsegment.cpp @@ -107,18 +107,18 @@ namespace swrenderer group.EndIndex = MIN(index + groupSize, SegmentsCount()); group.x1 = ds->x1; group.x2 = ds->x2; - group.neardepth = MIN(ds->sz1, ds->sz2); - group.fardepth = MAX(ds->sz1, ds->sz2); + group.neardepth = MIN(ds->WallC.sz1, ds->WallC.sz2); + group.fardepth = MAX(ds->WallC.sz1, ds->WallC.sz2); for (unsigned int groupIndex = group.BeginIndex + 1; groupIndex < group.EndIndex; groupIndex++) { ds = Segment(groupIndex); group.x1 = MIN(group.x1, ds->x1); group.x2 = MAX(group.x2, ds->x2); - group.neardepth = MIN(group.neardepth, ds->sz1); - group.neardepth = MIN(group.neardepth, ds->sz2); - group.fardepth = MAX(ds->sz1, group.fardepth); - group.fardepth = MAX(ds->sz2, group.fardepth); + group.neardepth = MIN(group.neardepth, ds->WallC.sz1); + group.neardepth = MIN(group.neardepth, ds->WallC.sz2); + group.fardepth = MAX(ds->WallC.sz1, group.fardepth); + group.fardepth = MAX(ds->WallC.sz2, group.fardepth); } for (int x = group.x1; x < group.x2; x++) diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h index d489bfcda..85e34768c 100644 --- a/src/swrenderer/segments/r_drawsegment.h +++ b/src/swrenderer/segments/r_drawsegment.h @@ -31,10 +31,7 @@ namespace swrenderer float light, lightstep; float iscale, iscalestep; short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg - short sx1, sx2; // left, right of parent seg on screen - float sz1, sz2; // z for left, right of parent seg on screen - float siz1, siz2; // 1/z for left, right of parent seg on screen - float cx, cy, cdx, cdy; + FWallCoords WallC; float yscale; uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both bool bFogBoundary = false; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index c3b53fcf1..07d460b42 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -291,7 +291,9 @@ namespace swrenderer { continue; } - if ((ds->siz2 - ds->siz1) * ((x2 + x1) / 2 - ds->sx1) / (ds->sx2 - ds->sx1) + ds->siz1 < idepth) + float siz1 = 1 / ds->WallC.sz1; + float siz2 = 1 / ds->WallC.sz2; + if ((siz2 - siz1) * ((x2 + x1) / 2 - ds->WallC.sx1) / (ds->WallC.sx2 - ds->WallC.sx1) + siz1 < idepth) { // [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves if (ds->CurrentPortalUniq == CurrentPortalUniq) diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index 7145e2b1e..adf058875 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -340,8 +340,8 @@ namespace swrenderer continue; } - float neardepth = MIN(ds->sz1, ds->sz2); - float fardepth = MAX(ds->sz1, ds->sz2); + float neardepth = MIN(ds->WallC.sz1, ds->WallC.sz2); + float fardepth = MAX(ds->WallC.sz1, ds->WallC.sz2); // Check if sprite is in front of draw seg: if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) && @@ -414,8 +414,8 @@ namespace swrenderer int r1 = MAX(ds->x1, x1); int r2 = MIN(ds->x2, x2); - float neardepth = MIN(ds->sz1, ds->sz2); - float fardepth = MAX(ds->sz1, ds->sz2); + float neardepth = MIN(ds->WallC.sz1, ds->WallC.sz2); + float fardepth = MAX(ds->WallC.sz1, ds->WallC.sz2); // Check if sprite is in front of draw seg: if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) && From c980f1c27fc834f9df88ec3b2d2ece4f8e2d56c4 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 27 Dec 2018 23:46:21 -0500 Subject: [PATCH 7/9] - g3.8pre --- src/version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/version.h b/src/version.h index 7cd576e3a..de26a0209 100644 --- a/src/version.h +++ b/src/version.h @@ -48,16 +48,16 @@ const char *GetVersionString(); #ifdef GIT_DESCRIPTION #define VERSIONSTR GIT_DESCRIPTION #else -#define VERSIONSTR "3.7pre" +#define VERSIONSTR "3.8pre" #endif // The version as seen in the Windows resource -#define RC_FILEVERSION 3,6,9999,0 -#define RC_PRODUCTVERSION 3,6,9999,0 +#define RC_FILEVERSION 3,7,9999,0 +#define RC_PRODUCTVERSION 3,7,9999,0 #define RC_PRODUCTVERSION2 VERSIONSTR // These are for content versioning. #define VER_MAJOR 3 -#define VER_MINOR 7 +#define VER_MINOR 8 #define VER_REVISION 0 // Version identifier for network games. From c499c563a0e497eaab8b614e16028b5abd7e01da Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 28 Dec 2018 13:04:54 +0100 Subject: [PATCH 8/9] - remove WallSampler --- src/swrenderer/line/r_walldraw.cpp | 619 +++++++++++++++-------------- src/swrenderer/line/r_walldraw.h | 20 +- 2 files changed, 320 insertions(+), 319 deletions(-) diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index b7405736d..0cd3fa705 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -54,284 +54,7 @@ namespace swrenderer { - WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture) - { - xoffset += FLOAT2FIXED(xmagnitude * 0.5); - xoffset *= texture->GetPhysicalScale(); - - if (!viewport->RenderTarget->IsBgra()) - { - height = texture->GetPhysicalHeight(); - - int uv_fracbits = 32 - texture->GetHeightBits(); - if (uv_fracbits != 32) - { - uv_max = height << uv_fracbits; - - // Find start uv in [0-base_height[ range. - // Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range. - double uv_stepd = swal * yrepeat; - double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / texture->GetHeight(); - v = v - floor(v); - v *= height; - v *= (1 << uv_fracbits); - - uv_pos = (uint32_t)(int64_t)v; - uv_step = xs_ToFixed(uv_fracbits, uv_stepd * texture->GetPhysicalScale()); - if (uv_step == 0) // To prevent divide by zero elsewhere - uv_step = 1; - } - else - { // Hack for one pixel tall textures - uv_pos = 0; - uv_step = 0; - uv_max = 1; - } - - int col = xoffset >> FRACBITS; - - // If the texture's width isn't a power of 2, then we need to make it a - // positive offset for proper clamping. - int width; - if (col < 0 && (width = texture->GetPhysicalWidth()) != (1 << texture->GetWidthBits())) - { - col = width + (col % width); - } - - source = texture->GetColumn(DefaultRenderStyle(), col, nullptr); - source2 = nullptr; - texturefracx = 0; - } - else - { - // Normalize to 0-1 range: - double uv_stepd = swal * yrepeat; - double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / texture->GetHeight(); - v = v - floor(v); - double v_step = uv_stepd / texture->GetHeight(); - - if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does.. - { - uv_stepd = 0.0; - v = 0.0; - v_step = 0.0; - } - - // Convert to uint32_t: - uv_pos = (uint32_t)(int64_t)(v * 0x100000000LL); - uv_step = (uint32_t)(int64_t)(v_step * 0x100000000LL); - uv_max = 0; - - // Texture mipmap and filter selection: - double ymagnitude = fabs(uv_stepd); - double magnitude = MAX(ymagnitude, xmagnitude); - double min_lod = -1000.0; - double lod = MAX(log2(magnitude) + r_lod_bias, min_lod); - bool magnifying = lod < 0.0f; - - int mipmap_offset = 0; - int mip_width = texture->GetPhysicalWidth(); - int mip_height = texture->GetPhysicalHeight(); - if (r_mipmap && texture->Mipmapped() && mip_width > 1 && mip_height > 1) - { - uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width); - - int level = (int)lod; - while (level > 0 && mip_width > 1 && mip_height > 1) - { - mipmap_offset += mip_width * mip_height; - level--; - mip_width = MAX(mip_width >> 1, 1); - mip_height = MAX(mip_height >> 1, 1); - } - xoffset = (xpos >> FRACBITS) * mip_width; - } - - const uint32_t *pixels = texture->GetPixelsBgra() + mipmap_offset; - - bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter); - if (filter_nearest) - { - int tx = (xoffset >> FRACBITS) % mip_width; - if (tx < 0) - tx += mip_width; - source = (uint8_t*)(pixels + tx * mip_height); - source2 = nullptr; - height = mip_height; - texturefracx = 0; - } - else - { - xoffset -= FRACUNIT / 2; - int tx0 = (xoffset >> FRACBITS) % mip_width; - if (tx0 < 0) - tx0 += mip_width; - int tx1 = (tx0 + 1) % mip_width; - source = (uint8_t*)(pixels + tx0 * mip_height); - source2 = (uint8_t*)(pixels + tx1 * mip_height); - height = mip_height; - texturefracx = (xoffset >> (FRACBITS - 4)) & 15; - } - } - } - - // Draw a column with support for non-power-of-two ranges - void RenderWallPart::Draw1Column(int x, int y1, int y2, WallSampler &sampler) - { - // Find column position in view space - float w1 = 1.0f / WallC.sz1; - float w2 = 1.0f / WallC.sz2; - float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1); - float wcol = w1 * (1.0f - t) + w2 * t; - float zcol = 1.0f / wcol; - float zbufferdepth = 1.0f / (zcol / Thread->Viewport->viewwindow.FocalTangent); - - if (r_dynlights && light_list) - { - auto viewport = Thread->Viewport.get(); - - int tx = x; - bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP); - if (mirror) - tx = viewwidth - tx - 1; - - drawerargs.dc_viewpos.X = (float)((tx + 0.5 - viewport->CenterX) / viewport->CenterX * zcol); - drawerargs.dc_viewpos.Y = zcol; - drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol); - drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale); - - // Calculate max lights that can touch column so we can allocate memory for the list - int max_lights = 0; - FLightNode *cur_node = light_list; - while (cur_node) - { - if (!(cur_node->lightsource->flags2&MF2_DORMANT)) - max_lights++; - cur_node = cur_node->nextLight; - } - - drawerargs.dc_num_lights = 0; - drawerargs.dc_lights = Thread->FrameMemory->AllocMemory(max_lights); - - // Setup lights for column - cur_node = light_list; - while (cur_node) - { - if (!(cur_node->lightsource->flags2&MF2_DORMANT)) - { - double lightX = cur_node->lightsource->X() - Thread->Viewport->viewpoint.Pos.X; - double lightY = cur_node->lightsource->Y() - Thread->Viewport->viewpoint.Pos.Y; - double lightZ = cur_node->lightsource->Z() - Thread->Viewport->viewpoint.Pos.Z; - - float lx = (float)(lightX * Thread->Viewport->viewpoint.Sin - lightY * Thread->Viewport->viewpoint.Cos) - drawerargs.dc_viewpos.X; - float ly = (float)(lightX * Thread->Viewport->viewpoint.TanCos + lightY * Thread->Viewport->viewpoint.TanSin) - drawerargs.dc_viewpos.Y; - float lz = (float)lightZ; - - // Precalculate the constant part of the dot here so the drawer doesn't have to. - bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0; - float lconstant = lx * lx + ly * ly; - float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f; - - // Include light only if it touches this column - float radius = cur_node->lightsource->GetRadius(); - if (radius * radius >= lconstant && nlconstant >= 0.0f) - { - uint32_t red = cur_node->lightsource->GetRed(); - uint32_t green = cur_node->lightsource->GetGreen(); - uint32_t blue = cur_node->lightsource->GetBlue(); - - auto &light = drawerargs.dc_lights[drawerargs.dc_num_lights++]; - light.x = lconstant; - light.y = nlconstant; - light.z = lz; - light.radius = 256.0f / cur_node->lightsource->GetRadius(); - light.color = (red << 16) | (green << 8) | blue; - } - } - - cur_node = cur_node->nextLight; - } - } - else - { - drawerargs.dc_num_lights = 0; - } - - if (Thread->Viewport->RenderTarget->IsBgra()) - { - int count = y2 - y1; - - drawerargs.SetTexture(sampler.source, sampler.source2, sampler.height); - drawerargs.SetTextureUPos(sampler.texturefracx); - drawerargs.SetDest(Thread->Viewport.get(), x, y1); - drawerargs.SetCount(count); - drawerargs.SetTextureVStep(sampler.uv_step); - drawerargs.SetTextureVPos(sampler.uv_pos); - drawerargs.DrawColumn(Thread); - if (r_modelscene) - drawerargs.DrawDepthColumn(Thread, zbufferdepth); - - uint64_t step64 = sampler.uv_step; - uint64_t pos64 = sampler.uv_pos; - sampler.uv_pos = (uint32_t)(pos64 + step64 * count); - } - else - { - if (sampler.uv_max == 0 || sampler.uv_step == 0) // power of two - { - int count = y2 - y1; - - drawerargs.SetTexture(sampler.source, sampler.source2, sampler.height); - drawerargs.SetTextureUPos(sampler.texturefracx); - drawerargs.SetDest(Thread->Viewport.get(), x, y1); - drawerargs.SetCount(count); - drawerargs.SetTextureVStep(sampler.uv_step); - drawerargs.SetTextureVPos(sampler.uv_pos); - drawerargs.DrawColumn(Thread); - if (r_modelscene) - drawerargs.DrawDepthColumn(Thread, zbufferdepth); - - uint64_t step64 = sampler.uv_step; - uint64_t pos64 = sampler.uv_pos; - sampler.uv_pos = (uint32_t)(pos64 + step64 * count); - } - else - { - uint32_t uv_pos = sampler.uv_pos; - - uint32_t left = y2 - y1; - int y = y1; - while (left > 0) - { - uint32_t available = sampler.uv_max - uv_pos; - uint32_t next_uv_wrap = available / sampler.uv_step; - if (available % sampler.uv_step != 0) - next_uv_wrap++; - uint32_t count = MIN(left, next_uv_wrap); - - drawerargs.SetTexture(sampler.source, sampler.source2, sampler.height); - drawerargs.SetTextureUPos(sampler.texturefracx); - drawerargs.SetDest(Thread->Viewport.get(), x, y); - drawerargs.SetCount(count); - drawerargs.SetTextureVStep(sampler.uv_step); - drawerargs.SetTextureVPos(uv_pos); - drawerargs.DrawColumn(Thread); - if (r_modelscene) - drawerargs.DrawDepthColumn(Thread, zbufferdepth); - - y += count; - left -= count; - uv_pos += sampler.uv_step * count; - if (uv_pos >= sampler.uv_max) - uv_pos -= sampler.uv_max; - } - - sampler.uv_pos = uv_pos; - } - } - } - - void RenderWallPart::ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) + void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) { if (rw_pic == nullptr) return; @@ -344,6 +67,7 @@ namespace swrenderer texturemid = 0; } + WallDrawerArgs drawerargs; drawerargs.SetTextureFracBits(Thread->Viewport->RenderTarget->IsBgra() ? FRACBITS : fracbits); // Textures that aren't masked can use the faster opaque drawer @@ -356,42 +80,334 @@ namespace swrenderer drawerargs.SetStyle(mask, additive, alpha, mLight.GetBaseColormap()); } - CameraLight *cameraLight = CameraLight::Instance(); - bool fixed = (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0); + RenderViewport *viewport = Thread->Viewport.get(); - float dx = WallC.tright.X - WallC.tleft.X; - float dy = WallC.tright.Y - WallC.tleft.Y; - float length = sqrt(dx * dx + dy * dy); - drawerargs.dc_normal.X = dy / length; - drawerargs.dc_normal.Y = -dx / length; - drawerargs.dc_normal.Z = 0.0f; + CameraLight *cameraLight = CameraLight::Instance(); + bool fixed = (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0); + + bool haslights = r_dynlights && light_list; + + if (haslights) + { + float dx = WallC.tright.X - WallC.tleft.X; + float dy = WallC.tright.Y - WallC.tleft.Y; + float length = sqrt(dx * dx + dy * dy); + drawerargs.dc_normal.X = dy / length; + drawerargs.dc_normal.Y = -dx / length; + drawerargs.dc_normal.Z = 0.0f; + } double xmagnitude = 1.0; float curlight = mLight.GetLightPos(x1); - for (int x = x1; x < x2; x++, curlight += mLight.GetLightStep()) + float lightstep = mLight.GetLightStep(); + + if (viewport->RenderTarget->IsBgra()) { - int y1 = uwal[x]; - int y2 = dwal[x]; - if (y2 <= y1) - continue; + for (int x = x1; x < x2; x++, curlight += lightstep) + { + int y1 = uwal[x]; + int y2 = dwal[x]; + if (y2 <= y1) + continue; - if (!fixed) - drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get()); + if (!fixed) + drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), viewport); - if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); + if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); - WallSampler sampler(Thread->Viewport.get(), y1, texturemid, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic); - Draw1Column(x, y1, y2, sampler); + fixed_t xxoffset = (lwal[x] + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale(); + + // Normalize to 0-1 range: + double uv_stepd = swal[x] * yrepeat; + double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight(); + v = v - floor(v); + double v_step = uv_stepd / rw_pic->GetHeight(); + + if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does.. + { + uv_stepd = 0.0; + v = 0.0; + v_step = 0.0; + } + + // Convert to uint32_t: + uint32_t uv_pos = (uint32_t)(int64_t)(v * 0x100000000LL); + uint32_t uv_step = (uint32_t)(int64_t)(v_step * 0x100000000LL); + + // Texture mipmap and filter selection: + double ymagnitude = fabs(uv_stepd); + double magnitude = MAX(ymagnitude, xmagnitude); + double min_lod = -1000.0; + double lod = MAX(log2(magnitude) + r_lod_bias, min_lod); + bool magnifying = lod < 0.0f; + + int mipmap_offset = 0; + int mip_width = rw_pic->GetPhysicalWidth(); + int mip_height = rw_pic->GetPhysicalHeight(); + if (r_mipmap && rw_pic->Mipmapped() && mip_width > 1 && mip_height > 1) + { + uint32_t xpos = (uint32_t)((((uint64_t)xxoffset) << FRACBITS) / mip_width); + + int level = (int)lod; + while (level > 0 && mip_width > 1 && mip_height > 1) + { + mipmap_offset += mip_width * mip_height; + level--; + mip_width = MAX(mip_width >> 1, 1); + mip_height = MAX(mip_height >> 1, 1); + } + xxoffset = (xpos >> FRACBITS) * mip_width; + } + + const uint32_t *pixels = rw_pic->GetPixelsBgra() + mipmap_offset; + + const uint8_t *source; + const uint8_t *source2; + uint32_t texturefracx; + uint32_t height; + bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter); + if (filter_nearest) + { + int tx = (xxoffset >> FRACBITS) % mip_width; + if (tx < 0) + tx += mip_width; + source = (uint8_t*)(pixels + tx * mip_height); + source2 = nullptr; + height = mip_height; + texturefracx = 0; + } + else + { + xxoffset -= FRACUNIT / 2; + int tx0 = (xxoffset >> FRACBITS) % mip_width; + if (tx0 < 0) + tx0 += mip_width; + int tx1 = (tx0 + 1) % mip_width; + source = (uint8_t*)(pixels + tx0 * mip_height); + source2 = (uint8_t*)(pixels + tx1 * mip_height); + height = mip_height; + texturefracx = (xxoffset >> (FRACBITS - 4)) & 15; + } + + drawerargs.SetTexture(source, source2, height); + + if (haslights) + SetLights(drawerargs, x, y1); + else + drawerargs.dc_num_lights = 0; + + drawerargs.SetTextureUPos(texturefracx); + drawerargs.SetTextureVStep(uv_step); + + int count = y2 - y1; + + drawerargs.SetDest(viewport, x, y1); + drawerargs.SetCount(count); + drawerargs.SetTextureVPos(uv_pos); + drawerargs.DrawColumn(Thread); + } + } + else + { + uint32_t height = rw_pic->GetPhysicalHeight(); + + uint32_t uv_max; + int uv_fracbits = 32 - rw_pic->GetHeightBits(); + if (uv_fracbits != 32) + uv_max = height << uv_fracbits; + + for (int x = x1; x < x2; x++, curlight += lightstep) + { + int y1 = uwal[x]; + int y2 = dwal[x]; + if (y2 <= y1) + continue; + + if (!fixed) + drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), viewport); + + if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); + + uint32_t uv_pos; + uint32_t uv_step; + + fixed_t xxoffset = (lwal[x] + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale(); + + if (uv_fracbits != 32) + { + // Find start uv in [0-base_height[ range. + // Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range. + double uv_stepd = swal[x] * yrepeat; + double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight(); + v = v - floor(v); + v *= height; + v *= (1 << uv_fracbits); + + uv_pos = (uint32_t)(int64_t)v; + uv_step = xs_ToFixed(uv_fracbits, uv_stepd * rw_pic->GetPhysicalScale()); + if (uv_step == 0) // To prevent divide by zero elsewhere + uv_step = 1; + } + else + { // Hack for one pixel tall textures + uv_pos = 0; + uv_step = 0; + uv_max = 1; + } + + int col = xxoffset >> FRACBITS; + + // If the texture's width isn't a power of 2, then we need to make it a + // positive offset for proper clamping. + int width; + if (col < 0 && (width = rw_pic->GetPhysicalWidth()) != (1 << rw_pic->GetWidthBits())) + { + col = width + (col % width); + } + + drawerargs.SetTexture(rw_pic->GetColumn(DefaultRenderStyle(), col, nullptr), nullptr, height); + + if (haslights) + SetLights(drawerargs, x, y1); + else + drawerargs.dc_num_lights = 0; + + drawerargs.SetTextureVStep(uv_step); + + if (uv_max == 0 || uv_step == 0) // power of two + { + int count = y2 - y1; + + drawerargs.SetDest(viewport, x, y1); + drawerargs.SetCount(count); + drawerargs.SetTextureVPos(uv_pos); + drawerargs.DrawColumn(Thread); + } + else + { + uint32_t left = y2 - y1; + int y = y1; + while (left > 0) + { + uint32_t available = uv_max - uv_pos; + uint32_t next_uv_wrap = available / uv_step; + if (available % uv_step != 0) + next_uv_wrap++; + uint32_t count = MIN(left, next_uv_wrap); + + drawerargs.SetDest(viewport, x, y); + drawerargs.SetCount(count); + drawerargs.SetTextureVPos(uv_pos); + drawerargs.DrawColumn(Thread); + + y += count; + left -= count; + uv_pos += uv_step * count; + if (uv_pos >= uv_max) + uv_pos -= uv_max; + } + } + } } - if (Thread->MainThread) - NetUpdate(); + if (r_modelscene) + { + for (int x = x1; x < x2; x++) + { + int y1 = uwal[x]; + int y2 = dwal[x]; + if (y2 > y1) + { + int count = y2 - y1; + + float w1 = 1.0f / WallC.sz1; + float w2 = 1.0f / WallC.sz2; + float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1); + float wcol = w1 * (1.0f - t) + w2 * t; + float zcol = 1.0f / wcol; + float zbufferdepth = 1.0f / (zcol / viewport->viewwindow.FocalTangent); + + drawerargs.SetDest(viewport, x, y1); + drawerargs.SetCount(count); + drawerargs.DrawDepthColumn(Thread, zbufferdepth); + } + } + } } - void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) + void RenderWallPart::SetLights(WallDrawerArgs &drawerargs, int x, int y1) { - ProcessWallWorker(uwal, dwal, texturemid, swal, lwal); + bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP); + int tx = x; + if (mirror) + tx = viewwidth - tx - 1; + + RenderViewport *viewport = Thread->Viewport.get(); + + // Find column position in view space + float w1 = 1.0f / WallC.sz1; + float w2 = 1.0f / WallC.sz2; + float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1); + float wcol = w1 * (1.0f - t) + w2 * t; + float zcol = 1.0f / wcol; + + drawerargs.dc_viewpos.X = (float)((tx + 0.5 - viewport->CenterX) / viewport->CenterX * zcol); + drawerargs.dc_viewpos.Y = zcol; + drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol); + drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale); + + // Calculate max lights that can touch column so we can allocate memory for the list + int max_lights = 0; + FLightNode *cur_node = light_list; + while (cur_node) + { + if (!(cur_node->lightsource->flags2&MF2_DORMANT)) + max_lights++; + cur_node = cur_node->nextLight; + } + + drawerargs.dc_num_lights = 0; + drawerargs.dc_lights = Thread->FrameMemory->AllocMemory(max_lights); + + // Setup lights for column + cur_node = light_list; + while (cur_node) + { + if (!(cur_node->lightsource->flags2&MF2_DORMANT)) + { + double lightX = cur_node->lightsource->X() - viewport->viewpoint.Pos.X; + double lightY = cur_node->lightsource->Y() - viewport->viewpoint.Pos.Y; + double lightZ = cur_node->lightsource->Z() - viewport->viewpoint.Pos.Z; + + float lx = (float)(lightX * viewport->viewpoint.Sin - lightY * viewport->viewpoint.Cos) - drawerargs.dc_viewpos.X; + float ly = (float)(lightX * viewport->viewpoint.TanCos + lightY * viewport->viewpoint.TanSin) - drawerargs.dc_viewpos.Y; + float lz = (float)lightZ; + + // Precalculate the constant part of the dot here so the drawer doesn't have to. + bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0; + float lconstant = lx * lx + ly * ly; + float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f; + + // Include light only if it touches this column + float radius = cur_node->lightsource->GetRadius(); + if (radius * radius >= lconstant && nlconstant >= 0.0f) + { + uint32_t red = cur_node->lightsource->GetRed(); + uint32_t green = cur_node->lightsource->GetGreen(); + uint32_t blue = cur_node->lightsource->GetBlue(); + + auto &light = drawerargs.dc_lights[drawerargs.dc_num_lights++]; + light.x = lconstant; + light.y = nlconstant; + light.z = lz; + light.radius = 256.0f / cur_node->lightsource->GetRadius(); + light.color = (red << 16) | (green << 8) | blue; + } + } + + cur_node = cur_node->nextLight; + } } void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) @@ -530,6 +546,9 @@ namespace swrenderer this->additive = additive; this->alpha = alpha; + if (Thread->MainThread) + NetUpdate(); + Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here. if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits()) diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h index 57e5a9540..bff80f8f4 100644 --- a/src/swrenderer/line/r_walldraw.h +++ b/src/swrenderer/line/r_walldraw.h @@ -74,8 +74,7 @@ namespace swrenderer void ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); - void ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); - void Draw1Column(int x, int y1, int y2, WallSampler &sampler); + void SetLights(WallDrawerArgs &drawerargs, int x, int y1); int x1 = 0; int x2 = 0; @@ -92,22 +91,5 @@ namespace swrenderer bool mask = false; bool additive = false; fixed_t alpha = 0; - - WallDrawerArgs drawerargs; - }; - - struct WallSampler - { - WallSampler() { } - WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture); - - uint32_t uv_pos; - uint32_t uv_step; - uint32_t uv_max; - - const uint8_t *source; - const uint8_t *source2; - uint32_t texturefracx; - uint32_t height; }; } From 7acf43741adf16f8360f093859cf533bdb25464b Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Fri, 28 Dec 2018 10:20:12 -0600 Subject: [PATCH 9/9] Fixed: IsFakePain received the modified damage instead of the raw, preventing ALLOWPAIN from working as intended. --- src/p_interaction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index e926de50a..1cac172b3 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -801,7 +801,7 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) } // [MC] Completely ripped out of DamageMobj to make it less messy. -static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags) +static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, int originaldamage) { bool justhit = false; int painchance = 0; @@ -827,7 +827,7 @@ static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int // Are we attempting to cause pain? if (!noPain) { - fakedPain = (isFakePain(target, inflictor, damage)); + fakedPain = (isFakePain(target, inflictor, originaldamage)); forcedPain = (MustForcePain(target, inflictor)); } @@ -1456,7 +1456,7 @@ static int DoDamageMobj(AActor *target, AActor *inflictor, AActor *source, int d bool needevent = true; int realdamage = DamageMobj(target, inflictor, source, damage, mod, flags, angle, needevent); if (realdamage >= 0) //Keep this check separated. Mods relying upon negative numbers may break otherwise. - ReactToDamage(target, inflictor, source, realdamage, mod, flags); + ReactToDamage(target, inflictor, source, realdamage, mod, flags, damage); if (realdamage > 0 && needevent) {