Remove the sprite drawer from wall drawing

This commit is contained in:
Magnus Norddahl 2019-11-11 05:37:02 +01:00
parent 3944ee5b67
commit fec280a5fc
3 changed files with 67 additions and 159 deletions

View File

@ -412,14 +412,13 @@ namespace swrenderer
memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start)); memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector); draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector);
bool is_translucent = sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls();
if (is_translucent)
{
if (sidedef->GetTexture(side_t::mid).isValid()) if (sidedef->GetTexture(side_t::mid).isValid())
draw_segment->SetHas3DFloorMidTexture(); {
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
if (pic)
{
draw_segment->SetHas3DFloorMidTexture();
double yscale = GetYScale(sidedef, pic, side_t::mid); double yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z; double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
@ -458,11 +457,12 @@ namespace swrenderer
draw_segment->texcoords.yscale = yscale; draw_segment->texcoords.yscale = yscale;
draw_segment->texcoords.texturemid = TextureMid; draw_segment->texcoords.texturemid = TextureMid;
} }
}
draw_segment->light = mLight.GetLightPos(start); draw_segment->light = mLight.GetLightPos(start);
draw_segment->lightstep = mLight.GetLightStep(); draw_segment->lightstep = mLight.GetLightStep();
if (draw_segment->bFogBoundary || is_translucent) if (draw_segment->bFogBoundary || draw_segment->texcoords || draw_segment->Has3DFloorWalls())
{ {
Thread->DrawSegments->PushTranslucent(draw_segment); Thread->DrawSegments->PushTranslucent(draw_segment);
} }

View File

@ -54,8 +54,6 @@
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h" #include "swrenderer/viewport/r_spritedrawer.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
RenderDrawSegment::RenderDrawSegment(RenderThread *thread) RenderDrawSegment::RenderDrawSegment(RenderThread *thread)
@ -95,18 +93,13 @@ namespace swrenderer
float alpha = (float)MIN(curline->linedef->alpha, 1.); float alpha = (float)MIN(curline->linedef->alpha, 1.);
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0; bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
SpriteDrawerArgs columndrawerargs; bool visible = alpha > 0.0f;
ColormapLight cmlight;
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()) if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls())
{ {
return; return;
} }
// [RH] Draw fog partition // [RH] Draw fog partition
bool renderwall = true;
bool notrelevant = false;
if (ds->bFogBoundary) if (ds->bFogBoundary)
{ {
const short *mfloorclip = ds->sprbottomclip - ds->x1; const short *mfloorclip = ds->sprbottomclip - ds->x1;
@ -114,22 +107,17 @@ namespace swrenderer
RenderFogBoundary renderfog; RenderFogBoundary renderfog;
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight); renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight);
if (!ds->texcoords)
renderwall = false;
}
else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible)
{
renderwall = false;
} }
if (renderwall) bool notrelevant = false;
notrelevant = RenderWall(ds, x1, x2, columndrawerargs, visible); if (ds->texcoords && visible)
notrelevant = RenderWall(ds, x1, x2);
if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls()) if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls())
{ {
RenderFakeWallRange(ds, x1, x2); RenderFakeWallRange(ds, x1, x2);
} }
if (!notrelevant) if (!notrelevant)
{ {
ds->sprclipped = true; ds->sprclipped = true;
@ -137,7 +125,7 @@ namespace swrenderer
} }
} }
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible) bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2)
{ {
auto renderstyle = DefaultRenderStyle(); auto renderstyle = DefaultRenderStyle();
auto viewport = Thread->Viewport.get(); auto viewport = Thread->Viewport.get();
@ -159,9 +147,6 @@ namespace swrenderer
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
if (!wrap) if (!wrap)
{ // Texture does not wrap vertically. { // Texture does not wrap vertically.
double textop;
float MaskedScaleY = ds->texcoords.yscale;
// find positioning // find positioning
double texheight = tex->GetScaledHeightDouble(); double texheight = tex->GetScaledHeightDouble();
@ -171,45 +156,8 @@ namespace swrenderer
texheight = texheight / texheightscale; texheight = texheight / texheightscale;
} }
double texturemid; bool sprflipvert = ds->texcoords.yscale < 0;
if (curline->linedef->flags & ML_DONTPEGBOTTOM) double textop = ds->texcoords.texturemid / ds->texcoords.yscale;
{
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);
bool sprflipvert = false;
if (MaskedScaleY < 0)
{
MaskedScaleY = -MaskedScaleY;
sprflipvert = true;
}
if (tex->useWorldPanning(curline->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.
texturemid += rowoffset - Thread->Viewport->viewpoint.Pos.Z;
textop = texturemid;
texturemid *= MaskedScaleY;
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
textop = texturemid + rowoffset / MaskedScaleY - Thread->Viewport->viewpoint.Pos.Z;
texturemid = (texturemid - Thread->Viewport->viewpoint.Pos.Z) * MaskedScaleY + rowoffset;
}
if (sprflipvert)
{
MaskedScaleY = -MaskedScaleY;
texturemid -= tex->GetHeight() << FRACBITS;
}
// [RH] Don't bother drawing segs that are completely offscreen // [RH] Don't bother drawing segs that are completely offscreen
if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop) if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop)
@ -231,11 +179,6 @@ namespace swrenderer
return true; return true;
} }
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. // Unclipped vanilla Doom range for the wall. Relies on ceiling/floor clip to clamp the wall in range.
double ceilZ = textop; double ceilZ = textop;
double floorZ = textop - texheight; double floorZ = textop - texheight;
@ -267,8 +210,8 @@ namespace swrenderer
floorZ = MAX(floorZ, clipZ); floorZ = MAX(floorZ, clipZ);
} }
wallupper.Project(Thread->Viewport.get(), ceilZ, &WallC); wallupper.Project(Thread->Viewport.get(), ceilZ, &ds->WallC);
walllower.Project(Thread->Viewport.get(), floorZ, &WallC); walllower.Project(Thread->Viewport.get(), floorZ, &ds->WallC);
for (int i = x1; i < x2; i++) for (int i = x1; i < x2; i++)
{ {
@ -289,43 +232,15 @@ namespace swrenderer
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) || (curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
(curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX)) (curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{ {
ClipMidtex(x1, x2); ClipMidtex(ds, x1, x2);
} }
} }
mfloorclip = walllower.ScreenY; mfloorclip = walllower.ScreenY;
mceilingclip = wallupper.ScreenY; mceilingclip = wallupper.ScreenY;
auto cameraLight = CameraLight::Instance();
bool needslight = (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0);
ProjectedWallTexcoords texcoords = ds->texcoords;
texcoords.texturemid = texturemid;
texcoords.yscale = MaskedScaleY;
// draw the columns one at a time
if (visible)
{
Thread->PrepareTexture(tex, renderstyle);
float lightpos = mLight.GetLightPos(x1);
for (int x = x1; x < x2; ++x)
{
if (needslight)
{
columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get());
lightpos += mLight.GetLightStep();
}
columndrawerargs.DrawMaskedColumn(Thread, x, tex, texcoords, sprflipvert, mfloorclip, mceilingclip, renderstyle);
}
}
} }
else else
{ // Texture does wrap vertically. { // Texture does wrap vertically.
WallC.sz1 = ds->WallC.sz1;
WallC.sz2 = ds->WallC.sz2;
WallC.sx1 = ds->WallC.sx1;
WallC.sx2 = ds->WallC.sx2;
if (clip3d->CurrentSkybox) if (clip3d->CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
@ -335,13 +250,13 @@ namespace swrenderer
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) || (curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
(curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX)) (curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{ {
ClipMidtex(x1, x2); ClipMidtex(ds, x1, x2);
} }
} }
if (m3DFloor.clipTop) if (m3DFloor.clipTop)
{ {
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
for (int i = x1; i < x2; i++) for (int i = x1; i < x2; i++)
{ {
if (wallupper.ScreenY[i] < mceilingclip[i]) if (wallupper.ScreenY[i] < mceilingclip[i])
@ -351,7 +266,7 @@ namespace swrenderer
} }
if (m3DFloor.clipBottom) if (m3DFloor.clipBottom)
{ {
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
for (int i = x1; i < x2; i++) for (int i = x1; i < x2; i++)
{ {
if (walllower.ScreenY[i] > mfloorclip[i]) if (walllower.ScreenY[i] > mfloorclip[i])
@ -359,6 +274,7 @@ namespace swrenderer
} }
mfloorclip = walllower.ScreenY; mfloorclip = walllower.ScreenY;
} }
}
double top, bot; double top, bot;
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
@ -367,8 +283,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(frontsector, curline, WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr); renderWallpart.Render(frontsector, curline, ds->WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
}
return false; return false;
} }
@ -433,12 +348,9 @@ namespace swrenderer
texturemid += rowoffset; texturemid += rowoffset;
} }
WallC = ds->WallC;
WallT = ds->tmapvals;
Clip3DFloors *clip3d = Thread->Clip3D.get(); Clip3DFloors *clip3d = Thread->Clip3D.get();
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
for (i = x1; i < x2; i++) for (i = x1; i < x2; i++)
{ {
@ -452,7 +364,7 @@ namespace swrenderer
} }
ProjectedWallTexcoords walltexcoords; ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->WallC.sx1, ds->WallC.sx2, WallT); walltexcoords.Project(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->WallC.sx1, ds->WallC.sx2, ds->tmapvals);
walltexcoords.texturemid = texturemid; walltexcoords.texturemid = texturemid;
walltexcoords.yscale = yscale; walltexcoords.yscale = yscale;
walltexcoords.xoffset = rw_offset; walltexcoords.xoffset = rw_offset;
@ -461,7 +373,7 @@ namespace swrenderer
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, mLight, nullptr); 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);
RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, mLight, wallupper.ScreenY, walllower.ScreenY, true); RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, mLight, wallupper.ScreenY, walllower.ScreenY, true);
} }
@ -880,19 +792,19 @@ namespace swrenderer
} }
// Clip a midtexture to the floor and ceiling of the sector in front of it. // Clip a midtexture to the floor and ceiling of the sector in front of it.
void RenderDrawSegment::ClipMidtex(int x1, int x2) void RenderDrawSegment::ClipMidtex(DrawSegment* ds, int x1, int x2)
{ {
ProjectedWallLine most; ProjectedWallLine most;
RenderPortal *renderportal = Thread->Portal.get(); RenderPortal *renderportal = Thread->Portal.get();
most.Project(Thread->Viewport.get(), curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); most.Project(Thread->Viewport.get(), curline->frontsector->ceilingplane, &ds->WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
for (int i = x1; i < x2; ++i) for (int i = x1; i < x2; ++i)
{ {
if (wallupper.ScreenY[i] < most.ScreenY[i]) if (wallupper.ScreenY[i] < most.ScreenY[i])
wallupper.ScreenY[i] = most.ScreenY[i]; wallupper.ScreenY[i] = most.ScreenY[i];
} }
most.Project(Thread->Viewport.get(), curline->frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); most.Project(Thread->Viewport.get(), curline->frontsector->floorplane, &ds->WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
for (int i = x1; i < x2; ++i) for (int i = x1; i < x2; ++i)
{ {
if (walllower.ScreenY[i] > most.ScreenY[i]) if (walllower.ScreenY[i] > most.ScreenY[i])

View File

@ -37,9 +37,8 @@ namespace swrenderer
RenderThread *Thread = nullptr; RenderThread *Thread = nullptr;
private: private:
bool RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible); bool RenderWall(DrawSegment *ds, int x1, int x2);
void RenderWrapWall(DrawSegment* ds, int x1, int x2, FSoftwareTexture* tex); void ClipMidtex(DrawSegment* ds, int x1, int x2);
void ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, 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 RenderFakeWallRange(DrawSegment *ds, int x1, int x2);
void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot); void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
@ -50,9 +49,6 @@ namespace swrenderer
seg_t *curline = nullptr; seg_t *curline = nullptr;
Fake3DTranslucent m3DFloor; Fake3DTranslucent m3DFloor;
FWallCoords WallC;
FWallTmapVals WallT;
ProjectedWallLight mLight; ProjectedWallLight mLight;
ProjectedWallLine wallupper; ProjectedWallLine wallupper;