Add per-tier sidedef light levels to UDMF maps

This commit is contained in:
Nikolay Ambartsumov 2021-02-26 08:01:09 +02:00 committed by Rachael Alexanderson
parent a9eaae074f
commit df976e218e
13 changed files with 150 additions and 69 deletions

View file

@ -156,31 +156,40 @@ Note: All <bool> fields default to false unless mentioned otherwise.
sidedef sidedef
{ {
scalex_top = <float>; // X scale for upper texture, Default = 1.0. scalex_top = <float>; // X scale for upper texture, Default = 1.0.
scaley_top = <float>; // y scale for upper texture, Default = 1.0. scaley_top = <float>; // Y scale for upper texture, Default = 1.0.
scalex_mid = <float>; // X scale for mid texture, Default = 1.0. scalex_mid = <float>; // X scale for mid texture, Default = 1.0.
scaley_mid = <float>; // y scale for mid texture, Default = 1.0. scaley_mid = <float>; // Y scale for mid texture, Default = 1.0.
scalex_bottom = <float>; // X scale for lower texture, Default = 1.0. scalex_bottom = <float>; // X scale for lower texture, Default = 1.0.
scaley_bottom = <float>; // y scale for lower texture, Default = 1.0. scaley_bottom = <float>; // Y scale for lower texture, Default = 1.0.
offsetx_top = <float>; // X offset for upper texture, Default = 0.0. offsetx_top = <float>; // X offset for upper texture, Default = 0.0.
offsety_top = <float>; // y offset for upper texture, Default = 0.0. offsety_top = <float>; // Y offset for upper texture, Default = 0.0.
offsetx_mid = <float>; // X offset for mid texture, Default = 0.0. offsetx_mid = <float>; // X offset for mid texture, Default = 0.0.
offsety_mid = <float>; // y offset for mid texture, Default = 0.0. offsety_mid = <float>; // Y offset for mid texture, Default = 0.0.
offsetx_bottom = <float>; // X offset for lower texture, Default = 0.0. offsetx_bottom = <float>; // X offset for lower texture, Default = 0.0.
offsety_bottom = <float>; // y offset for lower texture, Default = 0.0. offsety_bottom = <float>; // Y offset for lower texture, Default = 0.0.
// When global texture offsets are used they will // When global texture offsets are used they will
// be added on top of these values. // be added on top of these values.
light = <integer>; // This side's light level. Default is 0. light = <integer>; // This side's light level. Default is 0.
lightabsolute = <bool>; // true = 'light' is an absolute value. Default is lightabsolute = <bool>; // true = 'light' is an absolute value. Default is
// relative to the owning sector's light level. // relative to the owning sector's light level.
lightfog = <bool>; // true = This side's relative lighting is used even in light_top = <integer>; // This side's top tier light level. Default is 0.
// foggy sectors. Default is to disable relative lightabsolute_top = <bool>; // true = 'light_top' is an absolute value. Default is
// lighting in foggy sectors. // relative to the sidedef's resulting light level.
nofakecontrast = <bool>; // Disables use of fake contrast on this sidedef. light_mid = <integer>; // This side's mid tier light level. Default is 0.
smoothlighting = <bool>; // Use smooth fake contrast. lightabsolute_mid = <bool>; // true = 'light_mid' is an absolute value. Default is
clipmidtex = <bool>; // Side's mid textures are clipped to floor and ceiling. // relative to the sidedef's resulting light level.
wrapmidtex = <bool>; // Side's mid textures are wrapped. light_bottom = <integer>; // This side's bottom tier light level. Default is 0.
nodecals = <bool>; // Disables decals on the sidedef. lightabsolute_bottom = <bool>; // true = 'light_bottom' is an absolute value. Default is
// relative to the sidedef's resulting light level.
lightfog = <bool>; // true = This side's relative lighting is used even in
// foggy sectors. Default is to disable relative
// lighting in foggy sectors.
nofakecontrast = <bool>; // Disables use of fake contrast on this sidedef.
smoothlighting = <bool>; // Use smooth fake contrast.
clipmidtex = <bool>; // Side's mid textures are clipped to floor and ceiling.
wrapmidtex = <bool>; // Side's mid textures are wrapped.
nodecals = <bool>; // Disables decals on the sidedef.
nogradient_top = <bool>; // disables color gradient on upper tier. (Hardware rendering only.) nogradient_top = <bool>; // disables color gradient on upper tier. (Hardware rendering only.)
flipgradient_top = <bool>; // flips gradient colors on upper tier. (Hardware rendering only.) flipgradient_top = <bool>; // flips gradient colors on upper tier. (Hardware rendering only.)
@ -510,6 +519,9 @@ Coloriation options added
1.32 28.06.2021 1.32 28.06.2021
Blocklandmonsters MBF21 flag Blocklandmonsters MBF21 flag
1.33 06.11.2021
Added separate light levels for sidedef tiers (top/mid/bottom)
=============================================================================== ===============================================================================
EOF EOF
=============================================================================== ===============================================================================

View file

@ -1151,15 +1151,20 @@ class DBaseDecal;
enum enum
{ {
WALLF_ABSLIGHTING = 1, // Light is absolute instead of relative WALLF_ABSLIGHTING = 1, // Light is absolute instead of relative
WALLF_NOAUTODECALS = 2, // Do not attach impact decals to this wall WALLF_NOAUTODECALS = 2, // Do not attach impact decals to this wall
WALLF_NOFAKECONTRAST = 4, // Don't do fake contrast for this wall in side_t::GetLightLevel WALLF_NOFAKECONTRAST = 4, // Don't do fake contrast for this wall in side_t::GetLightLevel
WALLF_SMOOTHLIGHTING = 8, // Similar to autocontrast but applies to all angles. WALLF_SMOOTHLIGHTING = 8, // Similar to autocontrast but applies to all angles.
WALLF_CLIP_MIDTEX = 16, // Like the line counterpart, but only for this side. WALLF_CLIP_MIDTEX = 16, // Like the line counterpart, but only for this side.
WALLF_WRAP_MIDTEX = 32, // Like the line counterpart, but only for this side. WALLF_WRAP_MIDTEX = 32, // Like the line counterpart, but only for this side.
WALLF_POLYOBJ = 64, // This wall belongs to a polyobject. WALLF_POLYOBJ = 64, // This wall belongs to a polyobject.
WALLF_LIGHT_FOG = 128, // This wall's Light is used even in fog. WALLF_LIGHT_FOG = 128, // This wall's Light is used even in fog.
WALLF_EXTCOLOR = 256, // enables the extended color options (flagged to allow the renderer to easily skip the relevant code) WALLF_EXTCOLOR = 256, // enables the extended color options (flagged to allow the renderer to easily skip the relevant code)
WALLF_ABSLIGHTING_TIER = 512, // Per-tier absolute lighting flags
WALLF_ABSLIGHTING_TOP = WALLF_ABSLIGHTING_TIER << 0, // Top tier light is absolute instead of relative
WALLF_ABSLIGHTING_MID = WALLF_ABSLIGHTING_TIER << 1, // Mid tier light is absolute instead of relative
WALLF_ABSLIGHTING_BOTTOM = WALLF_ABSLIGHTING_TIER << 2, // Bottom tier light is absolute instead of relative
}; };
struct side_t struct side_t
@ -1216,6 +1221,7 @@ struct side_t
uint32_t LeftSide, RightSide; // [RH] Group walls into loops uint32_t LeftSide, RightSide; // [RH] Group walls into loops
uint16_t TexelLength; uint16_t TexelLength;
int16_t Light; int16_t Light;
int16_t TierLights[3]; // per-tier light levels
uint16_t Flags; uint16_t Flags;
int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order. int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order.
FLightNode * lighthead; // all dynamic lights that may affect this wall FLightNode * lighthead; // all dynamic lights that may affect this wall
@ -1224,13 +1230,19 @@ struct side_t
int numsegs; int numsegs;
int sidenum; int sidenum;
int GetLightLevel (bool foggy, int baselight, bool is3dlight=false, int *pfakecontrast_usedbygzdoom=NULL) const; int GetLightLevel (bool foggy, int baselight, int which, bool is3dlight=false, int *pfakecontrast_usedbygzdoom=NULL) const;
void SetLight(int16_t l) void SetLight(int16_t l)
{ {
Light = l; Light = l;
} }
void SetLight(int16_t l, int which)
{
TierLights[which] = l;
}
FLevelLocals *GetLevel() FLevelLocals *GetLevel()
{ {
return sector->Level; return sector->Level;

View file

@ -1323,6 +1323,30 @@ public:
Flag(sd->Flags, WALLF_ABSLIGHTING, key); Flag(sd->Flags, WALLF_ABSLIGHTING, key);
continue; continue;
case NAME_light_top:
sd->SetLight(CheckInt(key), side_t::top);
continue;
case NAME_lightabsolute_top:
Flag(sd->Flags, WALLF_ABSLIGHTING_TOP, key);
continue;
case NAME_light_mid:
sd->SetLight(CheckInt(key), side_t::mid);
continue;
case NAME_lightabsolute_mid:
Flag(sd->Flags, WALLF_ABSLIGHTING_MID, key);
continue;
case NAME_light_bottom:
sd->SetLight(CheckInt(key), side_t::bottom);
continue;
case NAME_lightabsolute_bottom:
Flag(sd->Flags, WALLF_ABSLIGHTING_BOTTOM, key);
continue;
case NAME_lightfog: case NAME_lightfog:
Flag(sd->Flags, WALLF_LIGHT_FOG, key); Flag(sd->Flags, WALLF_LIGHT_FOG, key);
continue; continue;

View file

@ -746,6 +746,12 @@ xx(scaley_bottom)
xx(light) xx(light)
xx(lightabsolute) xx(lightabsolute)
xx(lightfog) xx(lightfog)
xx(light_top)
xx(lightabsolute_top)
xx(light_mid)
xx(lightabsolute_mid)
xx(light_bottom)
xx(lightabsolute_bottom)
xx(nofakecontrast) xx(nofakecontrast)
xx(smoothlighting) xx(smoothlighting)
xx(blockprojectiles) xx(blockprojectiles)

View file

@ -1533,11 +1533,18 @@ void line_t::AdjustLine()
// //
//========================================================================== //==========================================================================
int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfakecontrast) const int side_t::GetLightLevel (bool foggy, int baselight, int which, bool is3dlight, int *pfakecontrast) const
{ {
if (!is3dlight && (Flags & WALLF_ABSLIGHTING)) if (!is3dlight)
{ {
baselight = Light; if (Flags & (WALLF_ABSLIGHTING_TIER << which))
{
baselight = TierLights[which];
}
else if (Flags & WALLF_ABSLIGHTING)
{
baselight = Light + TierLights[which];
}
} }
if (pfakecontrast != NULL) if (pfakecontrast != NULL)
@ -1576,9 +1583,9 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake
} }
} }
} }
if (!is3dlight && !(Flags & WALLF_ABSLIGHTING) && (!foggy || (Flags & WALLF_LIGHT_FOG))) if (!is3dlight && !(Flags & WALLF_ABSLIGHTING) && !(Flags & (WALLF_ABSLIGHTING_TIER << which)) && (!foggy || (Flags & WALLF_LIGHT_FOG)))
{ {
baselight += this->Light; baselight += this->Light + this->TierLights[which];
} }
return baselight; return baselight;
} }
@ -1619,4 +1626,3 @@ void vertex_t::RecalcVertexHeights()
if (numheights <= 2) numheights = 0; // is not in need of any special attention if (numheights <= 2) numheights = 0; // is not in need of any special attention
dirty = false; dirty = false;
} }

View file

@ -1996,7 +1996,23 @@ void HWWall::DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector,
InverseFloors(di, seg, frontsector, topleft, topright, bottomleft, bottomright); InverseFloors(di, seg, frontsector, topleft, topright, bottomleft, bottomright);
} }
} }
inline int CalcRelLight(int lightlevel, int orglightlevel, int rel)
{
if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this.
{
return 0;
}
else if (lightlevel - rel > 256) // the brighter part of fake contrast will be clamped so also clamp the darker part by the same amount for better looks
{
return 256 - lightlevel + rel;
}
else
{
return rel;
}
}
//========================================================================== //==========================================================================
// //
// //
@ -2103,19 +2119,6 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
int rel = 0; int rel = 0;
int orglightlevel = hw_ClampLight(frontsector->lightlevel); int orglightlevel = hw_ClampLight(frontsector->lightlevel);
bool foggy = (!Colormap.FadeColor.isBlack() || di->Level->flags&LEVEL_HASFADETABLE); // fog disables fake contrast bool foggy = (!Colormap.FadeColor.isBlack() || di->Level->flags&LEVEL_HASFADETABLE); // fog disables fake contrast
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel));
if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this.
{
rellight = 0;
}
else if (lightlevel - rel > 256) // the brighter part of fake contrast will be clamped so also clamp the darker part by the same amount for better looks
{
rellight = 256 - lightlevel + rel;
}
else
{
rellight = rel;
}
alpha = 1.0f; alpha = 1.0f;
RenderStyle = STYLE_Normal; RenderStyle = STYLE_Normal;
@ -2161,6 +2164,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
else else
{ {
// normal texture // normal texture
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::mid, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true); texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true);
if (texture && texture->isValid()) if (texture && texture->isValid())
{ {
@ -2229,6 +2234,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
if (bch1a < fch1 || bch2a < fch2) if (bch1a < fch1 || bch2a < fch2)
{ {
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::top, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true); texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true);
if (texture && texture->isValid()) if (texture && texture->isValid())
{ {
@ -2279,6 +2286,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
texture = tex; texture = tex;
} }
else texture = nullptr; else texture = nullptr;
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::mid, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
if (isportal) if (isportal)
{ {
@ -2297,6 +2306,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
} }
else else
{ {
if (texture || drawfogboundary) if (texture || drawfogboundary)
{ {
DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback, DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback,
@ -2305,6 +2315,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
{ {
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::top, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
DoFFloorBlocks(di, seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); DoFFloorBlocks(di, seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
} }
} }
@ -2319,6 +2331,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
if (bfh1 > ffh1 || bfh2 > ffh2) if (bfh1 > ffh1 || bfh2 > ffh2)
{ {
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::bottom, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true); texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true);
if (texture && texture->isValid()) if (texture && texture->isValid())
{ {

View file

@ -873,7 +873,7 @@ namespace swrenderer
texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mTopTexture); texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mTopTexture);
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mTopTexture, x1, x2, walltop.ScreenY, wallupper.ScreenY, texcoords, false, false, OPAQUE); renderWallpart.Render(mFrontSector, mLineSegment, side_t::top, WallC, mTopTexture, x1, x2, walltop.ScreenY, wallupper.ScreenY, texcoords, false, false, OPAQUE);
} }
void SWRenderLine::RenderMiddleTexture(int x1, int x2) void SWRenderLine::RenderMiddleTexture(int x1, int x2)
@ -885,7 +885,7 @@ namespace swrenderer
texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC, mMiddleTexture); texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC, mMiddleTexture);
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mMiddleTexture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE); renderWallpart.Render(mFrontSector, mLineSegment, side_t::mid, WallC, mMiddleTexture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
} }
void SWRenderLine::RenderBottomTexture(int x1, int x2) void SWRenderLine::RenderBottomTexture(int x1, int x2)
@ -898,6 +898,6 @@ namespace swrenderer
texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mBottomTexture); texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mBottomTexture);
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE); renderWallpart.Render(mFrontSector, mLineSegment, side_t::bottom, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
} }
} }

View file

@ -195,7 +195,7 @@ namespace swrenderer
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0; bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(lightsector, curline, ds->WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, true, additive, alpha); renderWallpart.Render(lightsector, curline, side_t::mid, ds->WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, true, additive, alpha);
} }
void RenderDrawSegment::Render3DFloorWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic) void RenderDrawSegment::Render3DFloorWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic)
@ -216,7 +216,7 @@ namespace swrenderer
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC, rw_pic); walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC, rw_pic);
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(lightsector, curline, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha); renderWallpart.Render(lightsector, curline, side_t::top, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha);
RenderDecal::RenderDecals(Thread, ds, curline, lightsector, wallupper.ScreenY, walllower.ScreenY, true); RenderDecal::RenderDecals(Thread, ds, curline, lightsector, wallupper.ScreenY, walllower.ScreenY, true);
} }
@ -580,7 +580,7 @@ namespace swrenderer
const sector_t* lightsector = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); const sector_t* lightsector = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
ProjectedWallLight walllight; ProjectedWallLight walllight;
walllight.SetColormap(lightsector, curline); walllight.SetColormap(lightsector, curline, side_t::mid);
walllight.SetLightLeft(Thread, ds->WallC); walllight.SetLightLeft(Thread, ds->WallC);
RenderFogBoundary renderfog; RenderFogBoundary renderfog;

View file

@ -61,7 +61,7 @@ namespace swrenderer
Thread = thread; Thread = thread;
} }
void RenderWallPart::Render(const sector_t* lightsector, seg_t* curline, const FWallCoords& WallC, FSoftwareTexture* pic, int x1, int x2, const short* walltop, const short* wallbottom, const ProjectedWallTexcoords& texcoords, bool mask, bool additive, fixed_t alpha) void RenderWallPart::Render(const sector_t* lightsector, seg_t* curline, int tier, const FWallCoords& WallC, FSoftwareTexture* pic, int x1, int x2, const short* walltop, const short* wallbottom, const ProjectedWallTexcoords& texcoords, bool mask, bool additive, fixed_t alpha)
{ {
if (pic == nullptr) if (pic == nullptr)
return; return;
@ -70,6 +70,7 @@ namespace swrenderer
this->x2 = x2; this->x2 = x2;
this->lightsector = lightsector; this->lightsector = lightsector;
this->curline = curline; this->curline = curline;
this->tier = tier;
this->WallC = WallC; this->WallC = WallC;
this->pic = pic; this->pic = pic;
this->mask = mask; this->mask = mask;
@ -78,7 +79,7 @@ namespace swrenderer
light_list = GetLightList(); light_list = GetLightList();
mLight.SetColormap(lightsector, curline); mLight.SetColormap(lightsector, curline, tier);
mLight.SetLightLeft(Thread, WallC); mLight.SetLightLeft(Thread, WallC);
CameraLight* cameraLight = CameraLight::Instance(); CameraLight* cameraLight = CameraLight::Instance();
@ -114,7 +115,7 @@ namespace swrenderer
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY; down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
} }
mLight.SetColormap(lightsector, curline, &lightsector->e->XFloor.lightlist[i]); mLight.SetColormap(lightsector, curline, tier, &lightsector->e->XFloor.lightlist[i]);
} }
ProcessNormalWall(up, dwal, texcoords); ProcessNormalWall(up, dwal, texcoords);

View file

@ -47,6 +47,7 @@ namespace swrenderer
void Render( void Render(
const sector_t *lightsector, const sector_t *lightsector,
seg_t *curline, seg_t *curline,
int tier,
const FWallCoords &WallC, const FWallCoords &WallC,
FSoftwareTexture *pic, FSoftwareTexture *pic,
int x1, int x1,
@ -70,6 +71,7 @@ namespace swrenderer
FSoftwareTexture *pic = nullptr; FSoftwareTexture *pic = nullptr;
const sector_t *lightsector = nullptr; const sector_t *lightsector = nullptr;
seg_t *curline = nullptr; seg_t *curline = nullptr;
int tier;
FWallCoords WallC; FWallCoords WallC;
ProjectedWallLight mLight; ProjectedWallLight mLight;

View file

@ -687,7 +687,7 @@ namespace swrenderer
} }
} }
void ProjectedWallLight::SetColormap(const sector_t *frontsector, seg_t *lineseg, lightlist_t *lit) void ProjectedWallLight::SetColormap(const sector_t *frontsector, seg_t *lineseg, int tier, lightlist_t *lit)
{ {
if (!lit) if (!lit)
{ {
@ -695,7 +695,7 @@ namespace swrenderer
foggy = frontsector->Level->fadeto || frontsector->Colormap.FadeColor || (frontsector->Level->flags & LEVEL_HASFADETABLE); foggy = frontsector->Level->fadeto || frontsector->Colormap.FadeColor || (frontsector->Level->flags & LEVEL_HASFADETABLE);
if (!(lineseg->sidedef->Flags & WALLF_POLYOBJ)) if (!(lineseg->sidedef->Flags & WALLF_POLYOBJ))
lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel); lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel, tier);
else else
lightlevel = frontsector->GetLightLevel(); lightlevel = frontsector->GetLightLevel();
} }
@ -703,7 +703,7 @@ namespace swrenderer
{ {
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
foggy = frontsector->Level->fadeto || basecolormap->Fade || (frontsector->Level->flags & LEVEL_HASFADETABLE); foggy = frontsector->Level->fadeto || basecolormap->Fade || (frontsector->Level->flags & LEVEL_HASFADETABLE);
lightlevel = lineseg->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != nullptr); lightlevel = lineseg->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, tier, lit->lightsource != nullptr);
} }
} }
} }

View file

@ -119,7 +119,7 @@ namespace swrenderer
float GetLightStep() const { return lightstep; } float GetLightStep() const { return lightstep; }
bool IsSpriteLight() const { return spritelight; } bool IsSpriteLight() const { return spritelight; }
void SetColormap(const sector_t *frontsector, seg_t *lineseg, lightlist_t *lit = nullptr); void SetColormap(const sector_t *frontsector, seg_t *lineseg, int tier, lightlist_t *lit = nullptr);
void SetLightLeft(RenderThread *thread, const FWallCoords &wallc); void SetLightLeft(RenderThread *thread, const FWallCoords &wallc);
void SetSpriteLight() { lightleft = 0.0f; lightstep = 0.0f; spritelight = true; } void SetSpriteLight() { lightleft = 0.0f; lightstep = 0.0f; spritelight = true; }

View file

@ -157,6 +157,8 @@ namespace swrenderer
if (x1 >= clipper->x2 || x2 <= clipper->x1) if (x1 >= clipper->x2 || x2 <= clipper->x1)
return; return;
int tier = side_t::mid;
if (drawsegPass) if (drawsegPass)
{ {
uint32_t clipMode = decal->RenderFlags & RF_CLIPMASK; uint32_t clipMode = decal->RenderFlags & RF_CLIPMASK;
@ -203,6 +205,7 @@ namespace swrenderer
break; break;
case RF_CLIPUPPER: case RF_CLIPUPPER:
tier = side_t::top;
mceilingclip = walltop; mceilingclip = walltop;
mfloorclip = thread->OpaquePass->ceilingclip; mfloorclip = thread->OpaquePass->ceilingclip;
break; break;
@ -211,6 +214,7 @@ namespace swrenderer
return; return;
case RF_CLIPLOWER: case RF_CLIPLOWER:
tier = side_t::bottom;
mceilingclip = thread->OpaquePass->floorclip; mceilingclip = thread->OpaquePass->floorclip;
mfloorclip = wallbottom; mfloorclip = wallbottom;
break; break;
@ -219,7 +223,7 @@ namespace swrenderer
// Prepare lighting // Prepare lighting
ProjectedWallLight light; ProjectedWallLight light;
light.SetColormap(lightsector, curline); light.SetColormap(lightsector, curline, tier);
light.SetLightLeft(thread, WallC); light.SetLightLeft(thread, WallC);
usecolormap = light.GetBaseColormap(); usecolormap = light.GetBaseColormap();