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
commit df976e218e
13 changed files with 150 additions and 69 deletions

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);
}
}
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 orglightlevel = hw_ClampLight(frontsector->lightlevel);
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;
RenderStyle = STYLE_Normal;
@ -2161,6 +2164,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
else
{
// 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);
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)
{
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);
if (texture && texture->isValid())
{
@ -2279,6 +2286,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
texture = tex;
}
else texture = nullptr;
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::mid, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
if (isportal)
{
@ -2297,6 +2306,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
}
else
{
if (texture || drawfogboundary)
{
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())
{
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);
}
}
@ -2319,6 +2331,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
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);
if (texture && texture->isValid())
{

View file

@ -873,7 +873,7 @@ namespace swrenderer
texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mTopTexture);
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)
@ -885,7 +885,7 @@ namespace swrenderer
texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC, mMiddleTexture);
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)
@ -898,6 +898,6 @@ namespace swrenderer
texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mBottomTexture);
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;
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)
@ -216,7 +216,7 @@ namespace swrenderer
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC, rw_pic);
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);
}
@ -580,7 +580,7 @@ namespace swrenderer
const sector_t* lightsector = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
ProjectedWallLight walllight;
walllight.SetColormap(lightsector, curline);
walllight.SetColormap(lightsector, curline, side_t::mid);
walllight.SetLightLeft(Thread, ds->WallC);
RenderFogBoundary renderfog;

View file

@ -61,7 +61,7 @@ namespace swrenderer
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)
return;
@ -70,6 +70,7 @@ namespace swrenderer
this->x2 = x2;
this->lightsector = lightsector;
this->curline = curline;
this->tier = tier;
this->WallC = WallC;
this->pic = pic;
this->mask = mask;
@ -78,7 +79,7 @@ namespace swrenderer
light_list = GetLightList();
mLight.SetColormap(lightsector, curline);
mLight.SetColormap(lightsector, curline, tier);
mLight.SetLightLeft(Thread, WallC);
CameraLight* cameraLight = CameraLight::Instance();
@ -114,7 +115,7 @@ namespace swrenderer
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);

View file

@ -47,6 +47,7 @@ namespace swrenderer
void Render(
const sector_t *lightsector,
seg_t *curline,
int tier,
const FWallCoords &WallC,
FSoftwareTexture *pic,
int x1,
@ -70,6 +71,7 @@ namespace swrenderer
FSoftwareTexture *pic = nullptr;
const sector_t *lightsector = nullptr;
seg_t *curline = nullptr;
int tier;
FWallCoords WallC;
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)
{
@ -695,7 +695,7 @@ namespace swrenderer
foggy = frontsector->Level->fadeto || frontsector->Colormap.FadeColor || (frontsector->Level->flags & LEVEL_HASFADETABLE);
if (!(lineseg->sidedef->Flags & WALLF_POLYOBJ))
lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel);
lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel, tier);
else
lightlevel = frontsector->GetLightLevel();
}
@ -703,7 +703,7 @@ namespace swrenderer
{
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
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; }
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 SetSpriteLight() { lightleft = 0.0f; lightstep = 0.0f; spritelight = true; }

View file

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