mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-16 09:12:05 +00:00
Merge remote-tracking branch 'gzdoom/master' into newmaster
This commit is contained in:
commit
5c11e668eb
13 changed files with 190 additions and 408 deletions
|
@ -54,15 +54,12 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const DrawSegmentClipInfo& clip, const ProjectedWallLight &wallLight)
|
||||
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.
|
||||
|
||||
const short* uclip = clip.sprtopclip;
|
||||
const short* dclip = clip.sprbottomclip;
|
||||
|
||||
int wallshade = LightVisibility::LightLevelToShade(wallLight.GetLightLevel(), wallLight.GetFoggy(), thread->Viewport.get());
|
||||
int x = x2 - 1;
|
||||
int t2 = uclip[x];
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace swrenderer
|
|||
class RenderFogBoundary
|
||||
{
|
||||
public:
|
||||
void Render(RenderThread *thread, int x1, int x2, const DrawSegmentClipInfo &clip, const ProjectedWallLight &wallLight);
|
||||
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);
|
||||
|
|
|
@ -62,7 +62,6 @@
|
|||
|
||||
CVAR(Bool, r_fogboundary, true, 0)
|
||||
CVAR(Bool, r_drawmirrors, true, 0)
|
||||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
|
@ -405,8 +404,6 @@ namespace swrenderer
|
|||
if (draw_segment->HasFogBoundary() || draw_segment->HasTranslucentMidTexture() || draw_segment->Has3DFloorWalls())
|
||||
{
|
||||
draw_segment->drawsegclip.SetBackupClip(Thread, start, stop, Thread->OpaquePass->ceilingclip);
|
||||
draw_segment->light = mLight.GetLightPos(start);
|
||||
draw_segment->lightstep = mLight.GetLightStep();
|
||||
Thread->DrawSegments->PushTranslucent(draw_segment);
|
||||
}
|
||||
}
|
||||
|
@ -446,7 +443,7 @@ namespace swrenderer
|
|||
// [ZZ] Only if not an active mirror
|
||||
if (!markportal)
|
||||
{
|
||||
RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, mLineSegment, mLight, walltop.ScreenY, wallbottom.ScreenY, false);
|
||||
RenderDecal::RenderDecals(Thread, draw_segment, mLineSegment, mFrontSector, walltop.ScreenY, wallbottom.ScreenY, false);
|
||||
}
|
||||
|
||||
if (markportal)
|
||||
|
@ -661,22 +658,6 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
FTexture *ftex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
|
||||
FSoftwareTexture *midtex = ftex && ftex->isValid() ? ftex->GetSoftwareTexture() : nullptr;
|
||||
|
||||
bool segtextured = ftex != NULL || mTopTexture != NULL || mBottomTexture != NULL;
|
||||
|
||||
if (m3DFloor.type == Fake3DOpaque::Normal)
|
||||
{
|
||||
mLight.SetColormap(mFrontSector, mLineSegment);
|
||||
}
|
||||
|
||||
// calculate light table
|
||||
if (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector)))
|
||||
{
|
||||
mLight.SetLightLeft(Thread, WallC);
|
||||
}
|
||||
}
|
||||
|
||||
void SWRenderLine::SetTextures()
|
||||
|
@ -900,7 +881,7 @@ namespace swrenderer
|
|||
texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mTopTexture);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mTopTexture, x1, x2, walltop.ScreenY, wallupper.ScreenY, texcoords, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, mLight, GetLightList());
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mTopTexture, x1, x2, walltop.ScreenY, wallupper.ScreenY, texcoords, false, false, OPAQUE);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
|
||||
|
@ -912,7 +893,7 @@ namespace swrenderer
|
|||
texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mMiddleTexture);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mMiddleTexture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, texcoords, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mMiddleTexture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderBottomTexture(int x1, int x2)
|
||||
|
@ -925,18 +906,7 @@ namespace swrenderer
|
|||
texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mBottomTexture);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
|
||||
}
|
||||
|
||||
FLightNode *SWRenderLine::GetLightList()
|
||||
{
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || cameraLight->FixedColormap())
|
||||
return nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
else if (mLineSegment && mLineSegment->sidedef)
|
||||
return mLineSegment->sidedef->lighthead;
|
||||
else
|
||||
return nullptr;
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -74,8 +74,6 @@ namespace swrenderer
|
|||
void RenderMiddleTexture(int x1, int x2);
|
||||
void RenderBottomTexture(int x1, int x2);
|
||||
|
||||
FLightNode *GetLightList();
|
||||
|
||||
bool IsFogBoundary(sector_t *front, sector_t *back) const;
|
||||
bool SkyboxCompare(sector_t *frontsector, sector_t *backsector) const;
|
||||
|
||||
|
@ -115,8 +113,6 @@ namespace swrenderer
|
|||
|
||||
bool rw_prepped;
|
||||
|
||||
ProjectedWallLight mLight;
|
||||
|
||||
bool markfloor; // False if the back side is the same plane.
|
||||
bool markceiling;
|
||||
|
||||
|
|
|
@ -71,60 +71,25 @@ namespace swrenderer
|
|||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
// killough 4/13/98: get correct lightlevel for 2s normal textures
|
||||
sector_t tempsec;
|
||||
const sector_t *sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
|
||||
|
||||
mLight.SetColormap(sec, curline);
|
||||
mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1);
|
||||
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
double clipTop = m3DFloor.clipTop ? m3DFloor.sclipTop : sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
|
||||
for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (clipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0())
|
||||
{
|
||||
mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ds->HasTranslucentMidTexture() && !ds->HasFogBoundary() && !ds->Has3DFloorWalls())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ds->HasFogBoundary())
|
||||
{
|
||||
RenderFogBoundary renderfog;
|
||||
renderfog.Render(Thread, x1, x2, ds->drawsegclip, mLight);
|
||||
}
|
||||
RenderFog(ds, x1, x2);
|
||||
|
||||
bool notrelevant = false;
|
||||
if (ds->HasTranslucentMidTexture())
|
||||
notrelevant = RenderWall(ds, x1, x2);
|
||||
RenderWall(ds, x1, x2);
|
||||
|
||||
if (ds->Has3DFloorWalls())
|
||||
{
|
||||
Render3DFloorWallRange(ds, x1, x2);
|
||||
}
|
||||
|
||||
if (!notrelevant)
|
||||
{
|
||||
if (ds->HasFogBoundary() || ds->HasTranslucentMidTexture() || ds->Has3DFloorWalls())
|
||||
ds->drawsegclip.SetRangeDrawn(x1, x2);
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2)
|
||||
void RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2)
|
||||
{
|
||||
auto renderstyle = DefaultRenderStyle();
|
||||
auto viewport = Thread->Viewport.get();
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
if (!curline->sidedef->GetTexture(side_t::mid).isValid())
|
||||
return false;
|
||||
|
||||
FTexture *ttex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::mid), true);
|
||||
if (curline->GetLevel()->i_compatflags & COMPATF_MASKEDMIDTEX)
|
||||
{
|
||||
|
@ -139,41 +104,17 @@ namespace swrenderer
|
|||
if (!wrap)
|
||||
{ // Texture does not wrap vertically.
|
||||
|
||||
// find positioning
|
||||
double texheight = tex->GetScaledHeightDouble() / fabs(curline->sidedef->GetTextureYScale(side_t::mid));
|
||||
double texturemid;
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
|
||||
else
|
||||
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
|
||||
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
|
||||
if (tex->useWorldPanning(curline->GetLevel()))
|
||||
rowoffset /= fabs(tex->GetScale().Y * curline->sidedef->GetTextureYScale(side_t::mid));
|
||||
double textop = texturemid + rowoffset - Thread->Viewport->viewpoint.Pos.Z;
|
||||
double ceilZ, floorZ;
|
||||
GetNoWrapMidTextureZ(ds, tex, ceilZ, floorZ);
|
||||
|
||||
// [RH] Don't bother drawing segs that are completely offscreen
|
||||
if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop)
|
||||
{ // Texture top is below the bottom of the screen
|
||||
return false;
|
||||
}
|
||||
// Texture top is below the bottom of the screen
|
||||
if (viewport->globaldclip * ds->WallC.sz1 < -ceilZ && viewport->globaldclip * ds->WallC.sz2 < -ceilZ) return;
|
||||
|
||||
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;
|
||||
}
|
||||
// Texture bottom is above the top of the screen
|
||||
if (viewport->globaluclip * ds->WallC.sz1 > -floorZ && viewport->globaluclip * ds->WallC.sz2 > -floorZ) return;
|
||||
|
||||
if (m3DFloor.clipBottom && textop < m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (m3DFloor.clipTop && textop - texheight > m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unclipped vanilla Doom range for the wall. Relies on ceiling/floor clip to clamp the wall in range.
|
||||
double ceilZ = textop;
|
||||
double floorZ = textop - texheight;
|
||||
if (m3DFloor.clipBottom && ceilZ < m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z) return;
|
||||
if (m3DFloor.clipTop && floorZ > m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z) return;
|
||||
|
||||
// The 3D Floors implementation destroys the ceiling clip when doing its height passes..
|
||||
if (m3DFloor.clipTop || m3DFloor.clipBottom)
|
||||
|
@ -241,35 +182,25 @@ namespace swrenderer
|
|||
if (m3DFloor.clipTop)
|
||||
{
|
||||
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
if (wallupper.ScreenY[i] < mceilingclip[i])
|
||||
wallupper.ScreenY[i] = mceilingclip[i];
|
||||
}
|
||||
wallupper.ClipTop(x1, x2, ds->drawsegclip);
|
||||
mceilingclip = wallupper.ScreenY;
|
||||
}
|
||||
if (m3DFloor.clipBottom)
|
||||
{
|
||||
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
if (walllower.ScreenY[i] > mfloorclip[i])
|
||||
walllower.ScreenY[i] = mfloorclip[i];
|
||||
}
|
||||
walllower.ClipBottom(x1, x2, ds->drawsegclip);
|
||||
mfloorclip = walllower.ScreenY;
|
||||
}
|
||||
}
|
||||
|
||||
double top, bot;
|
||||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
sector_t tempsec;
|
||||
const sector_t* lightsector = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
|
||||
|
||||
float alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
|
||||
fixed_t alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(frontsector, curline, ds->WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
|
||||
|
||||
return false;
|
||||
renderWallpart.Render(lightsector, curline, 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)
|
||||
|
@ -278,9 +209,8 @@ namespace swrenderer
|
|||
if (Alpha <= 0)
|
||||
return;
|
||||
|
||||
mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1);
|
||||
sector_t* lightsector = (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls()) ? backsector : frontsector;
|
||||
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
|
||||
|
@ -290,13 +220,10 @@ namespace swrenderer
|
|||
ProjectedWallTexcoords walltexcoords;
|
||||
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC.sx1, ds->WallC.sx2, ds->tmapvals, rw_pic);
|
||||
|
||||
double top, bot;
|
||||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(frontsector, curline, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, mLight, nullptr);
|
||||
renderWallpart.Render(lightsector, curline, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha);
|
||||
|
||||
RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, mLight, wallupper.ScreenY, walllower.ScreenY, true);
|
||||
RenderDecal::RenderDecals(Thread, ds, curline, lightsector, wallupper.ScreenY, walllower.ScreenY, true);
|
||||
}
|
||||
|
||||
void RenderDrawSegment::Render3DFloorWallRange(DrawSegment *ds, int x1, int x2)
|
||||
|
@ -312,16 +239,11 @@ namespace swrenderer
|
|||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
if (backsector == nullptr)
|
||||
{
|
||||
if (!backsector)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ds->Has3DFloorFrontSectorWalls() && !ds->Has3DFloorBackSectorWalls())
|
||||
{
|
||||
sector_t *sec = backsector;
|
||||
backsector = frontsector;
|
||||
frontsector = sec;
|
||||
}
|
||||
std::swap(frontsector, backsector);
|
||||
|
||||
floorHeight = backsector->CenterFloor();
|
||||
ceilingHeight = backsector->CenterCeiling();
|
||||
|
@ -490,38 +412,6 @@ namespace swrenderer
|
|||
|
||||
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);
|
||||
|
||||
Render3DFloorWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic);
|
||||
}
|
||||
break;
|
||||
|
@ -673,37 +563,6 @@ namespace swrenderer
|
|||
|
||||
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);
|
||||
|
||||
Render3DFloorWall(ds, x1, x2, fover ? fover : rover, clipTop, clipBottom, rw_pic);
|
||||
}
|
||||
break;
|
||||
|
@ -711,6 +570,36 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void RenderDrawSegment::RenderFog(DrawSegment* ds, int x1, int x2)
|
||||
{
|
||||
const short* mfloorclip = ds->drawsegclip.sprbottomclip;
|
||||
const short* mceilingclip = ds->drawsegclip.sprtopclip;
|
||||
|
||||
if (m3DFloor.clipTop)
|
||||
{
|
||||
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
wallupper.ClipTop(x1, x2, ds->drawsegclip);
|
||||
mceilingclip = wallupper.ScreenY;
|
||||
}
|
||||
|
||||
if (m3DFloor.clipBottom)
|
||||
{
|
||||
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
walllower.ClipBottom(x1, x2, ds->drawsegclip);
|
||||
mfloorclip = walllower.ScreenY;
|
||||
}
|
||||
|
||||
sector_t tempsec;
|
||||
const sector_t* lightsector = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
|
||||
|
||||
ProjectedWallLight walllight;
|
||||
walllight.SetColormap(lightsector, curline);
|
||||
walllight.SetLightLeft(Thread, ds->WallC);
|
||||
|
||||
RenderFogBoundary renderfog;
|
||||
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, walllight);
|
||||
}
|
||||
|
||||
// Clip a midtexture to the floor and ceiling of the sector in front of it.
|
||||
void RenderDrawSegment::ClipMidtex(DrawSegment* ds, int x1, int x2)
|
||||
{
|
||||
|
@ -750,4 +639,22 @@ namespace swrenderer
|
|||
bot = MAX(bot, m3DFloor.sclipBottom);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDrawSegment::GetNoWrapMidTextureZ(DrawSegment* ds, FSoftwareTexture* tex, double& ceilZ, double& floorZ)
|
||||
{
|
||||
double texheight = tex->GetScaledHeightDouble() / fabs(curline->sidedef->GetTextureYScale(side_t::mid));
|
||||
double texturemid;
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
|
||||
else
|
||||
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
|
||||
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
|
||||
if (tex->useWorldPanning(curline->GetLevel()))
|
||||
rowoffset /= fabs(tex->GetScale().Y * curline->sidedef->GetTextureYScale(side_t::mid));
|
||||
double textop = texturemid + rowoffset - Thread->Viewport->viewpoint.Pos.Z;
|
||||
|
||||
// Unclipped vanilla Doom range for the wall. Relies on ceiling/floor clip to clamp the wall in range.
|
||||
ceilZ = textop;
|
||||
floorZ = textop - texheight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,12 @@ namespace swrenderer
|
|||
RenderThread *Thread = nullptr;
|
||||
|
||||
private:
|
||||
bool RenderWall(DrawSegment *ds, int x1, int x2);
|
||||
void ClipMidtex(DrawSegment* ds, int x1, int x2);
|
||||
void RenderWall(DrawSegment *ds, int x1, int x2);
|
||||
void Render3DFloorWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic);
|
||||
void Render3DFloorWallRange(DrawSegment *ds, int x1, int x2);
|
||||
void RenderFog(DrawSegment* ds, int x1, int x2);
|
||||
void ClipMidtex(DrawSegment* ds, int x1, int x2);
|
||||
void GetNoWrapMidTextureZ(DrawSegment* ds, FSoftwareTexture* tex, double& ceilZ, double& floorZ);
|
||||
void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
|
||||
|
||||
sector_t *frontsector = nullptr;
|
||||
|
@ -49,8 +51,6 @@ namespace swrenderer
|
|||
seg_t *curline = nullptr;
|
||||
Fake3DTranslucent m3DFloor;
|
||||
|
||||
ProjectedWallLight mLight;
|
||||
|
||||
ProjectedWallLine wallupper;
|
||||
ProjectedWallLine walllower;
|
||||
};
|
||||
|
|
|
@ -54,12 +54,75 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
|
||||
RenderWallPart::RenderWallPart(RenderThread* thread)
|
||||
{
|
||||
if (rw_pic == nullptr)
|
||||
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)
|
||||
{
|
||||
if (pic == nullptr)
|
||||
return;
|
||||
|
||||
int fracbits = 32 - rw_pic->GetHeightBits();
|
||||
this->x1 = x1;
|
||||
this->x2 = x2;
|
||||
this->lightsector = lightsector;
|
||||
this->curline = curline;
|
||||
this->WallC = WallC;
|
||||
this->pic = pic;
|
||||
this->mask = mask;
|
||||
this->additive = additive;
|
||||
this->alpha = alpha;
|
||||
|
||||
light_list = GetLightList();
|
||||
|
||||
mLight.SetColormap(lightsector, curline);
|
||||
mLight.SetLightLeft(Thread, WallC);
|
||||
|
||||
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||
|
||||
CameraLight* cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0 || !(lightsector->e && lightsector->e->XFloor.lightlist.Size()))
|
||||
{
|
||||
ProcessNormalWall(walltop, wallbottom, texcoords);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessStripedWall(walltop, wallbottom, texcoords);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessStripedWall(const short* uwal, const short* dwal, const ProjectedWallTexcoords& texcoords)
|
||||
{
|
||||
RenderPortal* renderportal = Thread->Portal.get();
|
||||
|
||||
ProjectedWallLine most1, most2, most3;
|
||||
const short* up = uwal;
|
||||
short* down = most1.ScreenY;
|
||||
|
||||
for (unsigned int i = 0; i < lightsector->e->XFloor.lightlist.Size(); i++)
|
||||
{
|
||||
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), lightsector->e->XFloor.lightlist[i].plane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
if (j != ProjectedWallCull::OutsideAbove)
|
||||
{
|
||||
for (int j = x1; j < x2; ++j)
|
||||
{
|
||||
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
|
||||
}
|
||||
ProcessNormalWall(up, down, texcoords);
|
||||
up = down;
|
||||
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
|
||||
}
|
||||
|
||||
mLight.SetColormap(lightsector, curline, &lightsector->e->XFloor.lightlist[i]);
|
||||
}
|
||||
|
||||
ProcessNormalWall(up, dwal, texcoords);
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
|
||||
{
|
||||
int fracbits = 32 - pic->GetHeightBits();
|
||||
if (fracbits == 32)
|
||||
{ // Hack for one pixel tall textures
|
||||
fracbits = 0;
|
||||
|
@ -69,7 +132,7 @@ namespace swrenderer
|
|||
drawerargs.SetTextureFracBits(Thread->Viewport->RenderTarget->IsBgra() ? FRACBITS : fracbits);
|
||||
|
||||
// Textures that aren't masked can use the faster opaque drawer
|
||||
if (!rw_pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive)
|
||||
if (!pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive)
|
||||
{
|
||||
drawerargs.SetStyle(true, false, OPAQUE, mLight.GetBaseColormap());
|
||||
}
|
||||
|
@ -114,13 +177,13 @@ namespace swrenderer
|
|||
|
||||
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(texcoords.UPos(x + 1)) - FIXED2DBL(texcoords.UPos(x)));
|
||||
|
||||
fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
|
||||
fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * pic->GetPhysicalScale();
|
||||
|
||||
// Normalize to 0-1 range:
|
||||
double uv_stepd = texcoords.VStep(x) * texcoords.yscale;
|
||||
double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
|
||||
double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / pic->GetHeight();
|
||||
v = v - floor(v);
|
||||
double v_step = uv_stepd / rw_pic->GetHeight();
|
||||
double v_step = uv_stepd / pic->GetHeight();
|
||||
|
||||
if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does..
|
||||
{
|
||||
|
@ -141,9 +204,9 @@ namespace swrenderer
|
|||
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)
|
||||
int mip_width = pic->GetPhysicalWidth();
|
||||
int mip_height = pic->GetPhysicalHeight();
|
||||
if (r_mipmap && pic->Mipmapped() && mip_width > 1 && mip_height > 1)
|
||||
{
|
||||
uint32_t xpos = (uint32_t)((((uint64_t)xxoffset) << FRACBITS) / mip_width);
|
||||
|
||||
|
@ -158,7 +221,7 @@ namespace swrenderer
|
|||
xxoffset = (xpos >> FRACBITS) * mip_width;
|
||||
}
|
||||
|
||||
const uint32_t *pixels = rw_pic->GetPixelsBgra() + mipmap_offset;
|
||||
const uint32_t *pixels = pic->GetPixelsBgra() + mipmap_offset;
|
||||
|
||||
const uint8_t *source;
|
||||
const uint8_t *source2;
|
||||
|
@ -208,10 +271,10 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t height = rw_pic->GetPhysicalHeight();
|
||||
uint32_t height = pic->GetPhysicalHeight();
|
||||
|
||||
uint32_t uv_max;
|
||||
int uv_fracbits = 32 - rw_pic->GetHeightBits();
|
||||
int uv_fracbits = 32 - pic->GetHeightBits();
|
||||
if (uv_fracbits != 32)
|
||||
uv_max = height << uv_fracbits;
|
||||
|
||||
|
@ -230,20 +293,20 @@ namespace swrenderer
|
|||
uint32_t uv_pos;
|
||||
uint32_t uv_step;
|
||||
|
||||
fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
|
||||
fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * 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 = texcoords.VStep(x) * texcoords.yscale;
|
||||
double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
|
||||
double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / 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());
|
||||
uv_step = xs_ToFixed(uv_fracbits, uv_stepd * pic->GetPhysicalScale());
|
||||
if (uv_step == 0) // To prevent divide by zero elsewhere
|
||||
uv_step = 1;
|
||||
}
|
||||
|
@ -259,12 +322,12 @@ namespace swrenderer
|
|||
// 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()))
|
||||
if (col < 0 && (width = pic->GetPhysicalWidth()) != (1 << pic->GetWidthBits()))
|
||||
{
|
||||
col = width + (col % width);
|
||||
}
|
||||
|
||||
drawerargs.SetTexture(rw_pic->GetColumn(DefaultRenderStyle(), col, nullptr), nullptr, height);
|
||||
drawerargs.SetTexture(pic->GetColumn(DefaultRenderStyle(), col, nullptr), nullptr, height);
|
||||
|
||||
if (haslights)
|
||||
SetLights(drawerargs, x, y1);
|
||||
|
@ -408,154 +471,14 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
|
||||
FLightNode* RenderWallPart::GetLightList()
|
||||
{
|
||||
ProjectedWallLine most1, most2, most3;
|
||||
const short *up;
|
||||
short *down;
|
||||
|
||||
up = uwal;
|
||||
down = most1.ScreenY;
|
||||
|
||||
assert(WallC.sx1 <= x1);
|
||||
assert(WallC.sx2 >= x2);
|
||||
|
||||
RenderPortal *renderportal = Thread->Portal.get();
|
||||
|
||||
// kg3D - fake floors instead of zdoom light list
|
||||
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
|
||||
{
|
||||
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), frontsector->e->XFloor.lightlist[i].plane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
if (j != ProjectedWallCull::OutsideAbove)
|
||||
{
|
||||
for (int j = x1; j < x2; ++j)
|
||||
{
|
||||
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
|
||||
}
|
||||
ProcessNormalWall(up, down, texcoords);
|
||||
up = down;
|
||||
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
|
||||
}
|
||||
|
||||
mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]);
|
||||
}
|
||||
|
||||
ProcessNormalWall(up, dwal, texcoords);
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
|
||||
{
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
||||
{
|
||||
ProcessNormalWall(uwal, dwal, texcoords);
|
||||
}
|
||||
CameraLight* cameraLight = CameraLight::Instance();
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || cameraLight->FixedColormap())
|
||||
return nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
else if (curline && curline->sidedef)
|
||||
return curline->sidedef->lighthead;
|
||||
else
|
||||
{
|
||||
ProcessStripedWall(uwal, dwal, texcoords);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// ProcessWallNP2
|
||||
//
|
||||
// This is a wrapper around ProcessWall that helps it tile textures whose heights
|
||||
// are not powers of 2. It divides the wall into texture-sized strips and calls
|
||||
// ProcessNormalWall for each of those. Since only one repetition of the texture fits
|
||||
// in each strip, ProcessWall will not tile.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, ProjectedWallTexcoords texcoords, double top, double bot)
|
||||
{
|
||||
ProjectedWallLine most1, most2, most3;
|
||||
double texheight = rw_pic->GetHeight();
|
||||
double partition;
|
||||
double scaledtexheight = texheight / texcoords.yscale;
|
||||
|
||||
if (texcoords.yscale >= 0)
|
||||
{ // normal orientation: draw strips from top to bottom
|
||||
partition = top - fmod(top - texcoords.texturemid / texcoords.yscale - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight);
|
||||
if (partition == top)
|
||||
{
|
||||
partition -= scaledtexheight;
|
||||
}
|
||||
const short *up = uwal;
|
||||
short *down = most1.ScreenY;
|
||||
texcoords.texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * texcoords.yscale + texheight;
|
||||
while (partition > bot)
|
||||
{
|
||||
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
if (j != ProjectedWallCull::OutsideAbove)
|
||||
{
|
||||
for (int j = x1; j < x2; ++j)
|
||||
{
|
||||
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
|
||||
}
|
||||
ProcessWall(up, down, texcoords);
|
||||
up = down;
|
||||
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
|
||||
}
|
||||
partition -= scaledtexheight;
|
||||
texcoords.texturemid -= texheight;
|
||||
}
|
||||
ProcessWall(up, dwal, texcoords);
|
||||
}
|
||||
else
|
||||
{ // upside down: draw strips from bottom to top
|
||||
partition = bot - fmod(bot - texcoords.texturemid / texcoords.yscale - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight);
|
||||
short *up = most1.ScreenY;
|
||||
const short *down = dwal;
|
||||
texcoords.texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * texcoords.yscale + texheight;
|
||||
while (partition < top)
|
||||
{
|
||||
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
if (j != ProjectedWallCull::OutsideBelow)
|
||||
{
|
||||
for (int j = x1; j < x2; ++j)
|
||||
{
|
||||
up[j] = clamp(most3.ScreenY[j], uwal[j], down[j]);
|
||||
}
|
||||
ProcessWall(up, down, texcoords);
|
||||
down = up;
|
||||
up = (up == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
|
||||
}
|
||||
partition -= scaledtexheight;
|
||||
texcoords.texturemid -= texheight;
|
||||
}
|
||||
ProcessWall(uwal, down, texcoords);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::Render(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, const ProjectedWallTexcoords& texcoords, double top, double bottom, bool mask, bool additive, fixed_t alpha, const ProjectedWallLight &light, FLightNode *light_list)
|
||||
{
|
||||
this->x1 = x1;
|
||||
this->x2 = x2;
|
||||
this->frontsector = frontsector;
|
||||
this->curline = curline;
|
||||
this->WallC = WallC;
|
||||
this->mLight = light;
|
||||
this->light_list = light_list;
|
||||
this->rw_pic = pic;
|
||||
this->mask = mask;
|
||||
this->additive = additive;
|
||||
this->alpha = alpha;
|
||||
|
||||
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||
|
||||
if (rw_pic->GetHeight() != (1 << rw_pic->GetHeightBits()))
|
||||
{
|
||||
ProcessWallNP2(walltop, wallbottom, texcoords, top, bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessWall(walltop, wallbottom, texcoords);
|
||||
}
|
||||
}
|
||||
|
||||
RenderWallPart::RenderWallPart(RenderThread *thread)
|
||||
{
|
||||
Thread = thread;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,36 +46,31 @@ namespace swrenderer
|
|||
RenderWallPart(RenderThread *thread);
|
||||
|
||||
void Render(
|
||||
sector_t *frontsector,
|
||||
const sector_t *lightsector,
|
||||
seg_t *curline,
|
||||
const FWallCoords &WallC,
|
||||
FSoftwareTexture *rw_pic,
|
||||
FSoftwareTexture *pic,
|
||||
int x1,
|
||||
int x2,
|
||||
const short *walltop,
|
||||
const short *wallbottom,
|
||||
const ProjectedWallTexcoords &texcoords,
|
||||
double top,
|
||||
double bottom,
|
||||
bool mask,
|
||||
bool additive,
|
||||
fixed_t alpha,
|
||||
const ProjectedWallLight &light,
|
||||
FLightNode *light_list);
|
||||
|
||||
RenderThread *Thread = nullptr;
|
||||
fixed_t alpha);
|
||||
|
||||
private:
|
||||
void ProcessWallNP2(const short *uwal, const short *dwal, ProjectedWallTexcoords texcoords, double top, double bot);
|
||||
void ProcessWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
|
||||
FLightNode* GetLightList();
|
||||
|
||||
RenderThread* Thread = nullptr;
|
||||
|
||||
int x1 = 0;
|
||||
int x2 = 0;
|
||||
FSoftwareTexture *rw_pic = nullptr;
|
||||
sector_t *frontsector = nullptr;
|
||||
FSoftwareTexture *pic = nullptr;
|
||||
const sector_t *lightsector = nullptr;
|
||||
seg_t *curline = nullptr;
|
||||
FWallCoords WallC;
|
||||
|
||||
|
|
|
@ -110,8 +110,6 @@ namespace swrenderer
|
|||
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, const FWallCoords &wallc);
|
||||
|
||||
private:
|
||||
|
|
|
@ -161,11 +161,9 @@ namespace swrenderer
|
|||
{
|
||||
RenderDrawSegment renderer(Thread);
|
||||
renderer.Render(ds, ds->x1, ds->x2, clip3DFloor);
|
||||
|
||||
if (renew)
|
||||
{
|
||||
ds->ClearFogBoundary(); // don't draw fogboundary again
|
||||
ds->drawsegclip.SetRangeUndrawn(ds->x1, ds->x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,8 +51,7 @@ namespace swrenderer
|
|||
struct DrawSegment
|
||||
{
|
||||
seg_t *curline;
|
||||
float light, lightstep;
|
||||
short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg
|
||||
short x1, x2;
|
||||
|
||||
FWallCoords WallC;
|
||||
FWallTmapVals tmapvals;
|
||||
|
@ -71,8 +70,6 @@ namespace swrenderer
|
|||
void SetHas3DFloorBackSectorWalls() { flags |= 1; }
|
||||
void SetHasTranslucentMidTexture() { flags |= 4; }
|
||||
|
||||
void ClearFogBoundary() { flags &= ~8; } // Note: this shouldn't be needed as fog boundaries should be able to clip same way as 3dfloor walls
|
||||
|
||||
private:
|
||||
int flags = 0; // 1=backsector, 2=frontsector, 4=midtexture, 8=fogboundary
|
||||
};
|
||||
|
|
|
@ -53,19 +53,17 @@
|
|||
#include "swrenderer/r_memory.h"
|
||||
#include "swrenderer/r_renderthread.h"
|
||||
|
||||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
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)
|
||||
void RenderDecal::RenderDecals(RenderThread *thread, DrawSegment *draw_segment, seg_t *curline, const sector_t* lightsector, const short *walltop, const short *wallbottom, bool drawsegPass)
|
||||
{
|
||||
for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext)
|
||||
for (DBaseDecal *decal = curline->sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext)
|
||||
{
|
||||
Render(thread, sidedef, decal, draw_segment, curline, light, walltop, wallbottom, drawsegPass);
|
||||
Render(thread, decal, draw_segment, curline, lightsector, walltop, wallbottom, 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)
|
||||
void RenderDecal::Render(RenderThread *thread, DBaseDecal *decal, DrawSegment *clipper, seg_t *curline, const sector_t* lightsector, const short *walltop, const short *wallbottom, bool drawsegPass)
|
||||
{
|
||||
DVector2 decal_left, decal_right, decal_pos;
|
||||
int x1, x2;
|
||||
|
@ -142,7 +140,7 @@ namespace swrenderer
|
|||
edge_left *= decal->ScaleX;
|
||||
|
||||
double dcx, dcy;
|
||||
decal->GetXY(wall, dcx, dcy);
|
||||
decal->GetXY(curline->sidedef, dcx, dcy);
|
||||
decal_pos = { dcx, dcy };
|
||||
|
||||
DVector2 angvec = (curline->v2->fPos() - curline->v1->fPos()).Unit();
|
||||
|
@ -231,6 +229,9 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
// Prepare lighting
|
||||
ProjectedWallLight light;
|
||||
light.SetColormap(lightsector, curline);
|
||||
light.SetLightLeft(thread, WallC);
|
||||
usecolormap = light.GetBaseColormap();
|
||||
|
||||
// Decals that are added to the scene must fade to black.
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace swrenderer
|
|||
class RenderDecal
|
||||
{
|
||||
public:
|
||||
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);
|
||||
static void RenderDecals(RenderThread *thread, DrawSegment *draw_segment, seg_t *curline, const sector_t* lightsector, 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 ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass);
|
||||
static void Render(RenderThread *thread, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const sector_t* lightsector, const short *walltop, const short *wallbottom, bool drawsegPass);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue