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,57 +412,57 @@ namespace swrenderer
memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
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);
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
if (pic)
{
draw_segment->SetHas3DFloorMidTexture();
double yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
double yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
double texZFloor = MAX(mFrontSector->GetPlaneTexZ(sector_t::floor), mBackSector->GetPlaneTexZ(sector_t::floor));
double texZCeiling = MIN(mFrontSector->GetPlaneTexZ(sector_t::ceiling), mBackSector->GetPlaneTexZ(sector_t::ceiling));
double texZFloor = MAX(mFrontSector->GetPlaneTexZ(sector_t::floor), mBackSector->GetPlaneTexZ(sector_t::floor));
double texZCeiling = MIN(mFrontSector->GetPlaneTexZ(sector_t::ceiling), mBackSector->GetPlaneTexZ(sector_t::ceiling));
double TextureMid;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (texZFloor - cameraZ) * yscale + pic->GetHeight();
double TextureMid;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (texZFloor - cameraZ) * yscale + pic->GetHeight();
}
else
{ // top of texture at top
TextureMid = (texZCeiling - cameraZ) * yscale;
}
}
else
{ // top of texture at top
TextureMid = (texZCeiling - cameraZ) * yscale;
{ // upside down
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (texZFloor - cameraZ) * yscale;
}
else
{ // bottom of texture at top
TextureMid = (texZCeiling - cameraZ) * yscale + pic->GetHeight();
}
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (texZFloor - cameraZ) * yscale;
}
else
{ // bottom of texture at top
TextureMid = (texZCeiling - cameraZ) * yscale + pic->GetHeight();
}
}
TextureMid += GetRowOffset(linedef, sidedef, pic, side_t::mid);
TextureMid += GetRowOffset(linedef, sidedef, pic, side_t::mid);
draw_segment->texcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), WallC.sx1, WallC.sx2, WallT);
draw_segment->texcoords.xoffset = GetXOffset(sidedef, pic, side_t::mid);
draw_segment->texcoords.yscale = yscale;
draw_segment->texcoords.texturemid = TextureMid;
draw_segment->texcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), WallC.sx1, WallC.sx2, WallT);
draw_segment->texcoords.xoffset = GetXOffset(sidedef, pic, side_t::mid);
draw_segment->texcoords.yscale = yscale;
draw_segment->texcoords.texturemid = TextureMid;
}
}
draw_segment->light = mLight.GetLightPos(start);
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);
}

View file

@ -54,8 +54,6 @@
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
RenderDrawSegment::RenderDrawSegment(RenderThread *thread)
@ -95,18 +93,13 @@ namespace swrenderer
float alpha = (float)MIN(curline->linedef->alpha, 1.);
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
SpriteDrawerArgs columndrawerargs;
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);
bool visible = alpha > 0.0f;
if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls())
{
return;
}
// [RH] Draw fog partition
bool renderwall = true;
bool notrelevant = false;
if (ds->bFogBoundary)
{
const short *mfloorclip = ds->sprbottomclip - ds->x1;
@ -114,22 +107,17 @@ namespace swrenderer
RenderFogBoundary renderfog;
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight);
if (!ds->texcoords)
renderwall = false;
}
else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible)
{
renderwall = false;
}
if (renderwall)
notrelevant = RenderWall(ds, x1, x2, columndrawerargs, visible);
bool notrelevant = false;
if (ds->texcoords && visible)
notrelevant = RenderWall(ds, x1, x2);
if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls())
{
RenderFakeWallRange(ds, x1, x2);
}
if (!notrelevant)
{
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 viewport = Thread->Viewport.get();
@ -159,9 +147,6 @@ namespace swrenderer
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
if (!wrap)
{ // Texture does not wrap vertically.
double textop;
float MaskedScaleY = ds->texcoords.yscale;
// find positioning
double texheight = tex->GetScaledHeightDouble();
@ -171,45 +156,8 @@ namespace swrenderer
texheight = texheight / texheightscale;
}
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);
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;
}
bool sprflipvert = ds->texcoords.yscale < 0;
double textop = ds->texcoords.texturemid / ds->texcoords.yscale;
// [RH] Don't bother drawing segs that are completely offscreen
if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop)
@ -231,11 +179,6 @@ namespace swrenderer
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.
double ceilZ = textop;
double floorZ = textop - texheight;
@ -267,8 +210,8 @@ namespace swrenderer
floorZ = MAX(floorZ, clipZ);
}
wallupper.Project(Thread->Viewport.get(), ceilZ, &WallC);
walllower.Project(Thread->Viewport.get(), floorZ, &WallC);
wallupper.Project(Thread->Viewport.get(), ceilZ, &ds->WallC);
walllower.Project(Thread->Viewport.get(), floorZ, &ds->WallC);
for (int i = x1; i < x2; i++)
{
@ -289,43 +232,15 @@ namespace swrenderer
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
(curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{
ClipMidtex(x1, x2);
ClipMidtex(ds, x1, x2);
}
}
mfloorclip = walllower.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
{ // 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)
{ // 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->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{
ClipMidtex(x1, x2);
ClipMidtex(ds, x1, x2);
}
}
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++)
{
if (wallupper.ScreenY[i] < mceilingclip[i])
@ -351,7 +266,7 @@ namespace swrenderer
}
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++)
{
if (walllower.ScreenY[i] > mfloorclip[i])
@ -359,17 +274,17 @@ namespace swrenderer
}
mfloorclip = walllower.ScreenY;
}
double top, bot;
GetMaskedWallTopBottom(ds, top, bot);
float alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
RenderWallPart renderWallpart(Thread);
renderWallpart.Render(frontsector, curline, WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
}
double top, bot;
GetMaskedWallTopBottom(ds, top, bot);
float 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;
}
@ -433,12 +348,9 @@ namespace swrenderer
texturemid += rowoffset;
}
WallC = ds->WallC;
WallT = ds->tmapvals;
Clip3DFloors *clip3d = Thread->Clip3D.get();
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
walllower.Project(Thread->Viewport.get(), clipBottom - 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, &ds->WallC);
for (i = x1; i < x2; i++)
{
@ -452,7 +364,7 @@ namespace swrenderer
}
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.yscale = yscale;
walltexcoords.xoffset = rw_offset;
@ -461,7 +373,7 @@ namespace swrenderer
GetMaskedWallTopBottom(ds, top, bot);
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);
}
@ -880,19 +792,19 @@ namespace swrenderer
}
// 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;
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)
{
if (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)
{
if (walllower.ScreenY[i] > most.ScreenY[i])

View file

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