Move more texture coordinate variables into ProjectedWallTexcoords

This commit is contained in:
Magnus Norddahl 2019-11-09 04:45:39 +01:00
parent 5c21a6c973
commit b40ffb1d64
12 changed files with 110 additions and 104 deletions

View file

@ -422,6 +422,15 @@ namespace swrenderer
double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid); double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid);
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
double lwallscale =
tex ? ((pic ? pic->GetScale().X : 1.0) * sidedef->GetTextureXScale(side_t::mid)) :
mTopPart.Texture ? (mTopPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) :
mBottomPart.Texture ? (mBottomPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) :
1.;
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT);
if (pic && pic->useWorldPanning(sidedef->GetLevel())) if (pic && pic->useWorldPanning(sidedef->GetLevel()))
{ {
xoffset = xs_RoundToInt(xoffset * lwallscale); xoffset = xs_RoundToInt(xoffset * lwallscale);
@ -713,14 +722,6 @@ namespace swrenderer
// calculate light table // calculate light table
if (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector))) if (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector)))
{ {
lwallscale =
ftex ? ((midtex? midtex->GetScale().X : 1.0) * sidedef->GetTextureXScale(side_t::mid)) :
mTopPart.Texture ? (mTopPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) :
mBottomPart.Texture ? (mBottomPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) :
1.;
walltexcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT);
mLight.SetLightLeft(Thread, WallC); mLight.SetLightLeft(Thread, WallC);
} }
} }
@ -1069,27 +1070,28 @@ namespace swrenderer
auto rw_pic = mTopPart.Texture; auto rw_pic = mTopPart.Texture;
double xscale = rw_pic->GetScale().X * mTopPart.TextureScaleU; double xscale = rw_pic->GetScale().X * mTopPart.TextureScaleU;
double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV; double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV;
if (xscale != lwallscale)
{ ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
lwallscale = xscale;
}
fixed_t offset;
if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel())) if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale); walltexcoords.xoffset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale);
} }
else else
{ {
offset = mTopPart.TextureOffsetU; walltexcoords.xoffset = mTopPart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {
offset = -offset; walltexcoords.xoffset = -walltexcoords.xoffset;
} }
walltexcoords.yscale = yscale;
walltexcoords.texturemid = mTopPart.TextureMid;
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, offset, mLight, GetLightList()); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, walltexcoords, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, mLight, GetLightList());
} }
void SWRenderLine::RenderMiddleTexture(int x1, int x2) void SWRenderLine::RenderMiddleTexture(int x1, int x2)
@ -1100,27 +1102,28 @@ namespace swrenderer
auto rw_pic = mMiddlePart.Texture; auto rw_pic = mMiddlePart.Texture;
double xscale = rw_pic->GetScale().X * mMiddlePart.TextureScaleU; double xscale = rw_pic->GetScale().X * mMiddlePart.TextureScaleU;
double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV; double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV;
if (xscale != lwallscale)
{ ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
lwallscale = xscale;
}
fixed_t offset;
if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel())) if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale); walltexcoords.xoffset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale);
} }
else else
{ {
offset = mMiddlePart.TextureOffsetU; walltexcoords.xoffset = mMiddlePart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {
offset = -offset; walltexcoords.xoffset = -walltexcoords.xoffset;
} }
walltexcoords.yscale = yscale;
walltexcoords.texturemid = mMiddlePart.TextureMid;
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, walltexcoords, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
} }
void SWRenderLine::RenderBottomTexture(int x1, int x2) void SWRenderLine::RenderBottomTexture(int x1, int x2)
@ -1132,27 +1135,28 @@ namespace swrenderer
auto rw_pic = mBottomPart.Texture; auto rw_pic = mBottomPart.Texture;
double xscale = rw_pic->GetScale().X * mBottomPart.TextureScaleU; double xscale = rw_pic->GetScale().X * mBottomPart.TextureScaleU;
double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV; double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV;
if (xscale != lwallscale)
{ ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); walltexcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
lwallscale = xscale;
}
fixed_t offset;
if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel())) if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale); walltexcoords.xoffset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale);
} }
else else
{ {
offset = mBottomPart.TextureOffsetU; walltexcoords.xoffset = mBottomPart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {
offset = -offset; walltexcoords.xoffset = -walltexcoords.xoffset;
} }
walltexcoords.yscale = yscale;
walltexcoords.texturemid = mBottomPart.TextureMid;
RenderWallPart renderWallpart(Thread); RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList()); renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, walltexcoords, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
} }
FLightNode *SWRenderLine::GetLightList() FLightNode *SWRenderLine::GetLightList()

View file

@ -125,8 +125,6 @@ namespace swrenderer
ProjectedWallLight mLight; ProjectedWallLight mLight;
double lwallscale;
bool markfloor; // False if the back side is the same plane. bool markfloor; // False if the back side is the same plane.
bool markceiling; bool markceiling;
@ -141,7 +139,6 @@ namespace swrenderer
ProjectedWallLine wallbottom; ProjectedWallLine wallbottom;
ProjectedWallLine wallupper; ProjectedWallLine wallupper;
ProjectedWallLine walllower; ProjectedWallLine walllower;
ProjectedWallTexcoords walltexcoords;
sector_t tempsec; // killough 3/8/98: ceiling/water hack sector_t tempsec; // killough 3/8/98: ceiling/water hack
}; };

View file

@ -299,6 +299,10 @@ namespace swrenderer
auto cameraLight = CameraLight::Instance(); auto cameraLight = CameraLight::Instance();
bool needslight = (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0); 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 // draw the columns one at a time
if (visible) if (visible)
{ {
@ -312,7 +316,7 @@ namespace swrenderer
lightpos += mLight.GetLightStep(); lightpos += mLight.GetLightStep();
} }
columndrawerargs.DrawMaskedColumn(Thread, x, tex, ds->texcoords, texturemid, MaskedScaleY, sprflipvert, mfloorclip, mceilingclip, renderstyle); columndrawerargs.DrawMaskedColumn(Thread, x, tex, ds->texcoords, sprflipvert, mfloorclip, mceilingclip, renderstyle);
} }
} }
} }
@ -369,7 +373,9 @@ namespace swrenderer
mfloorclip = walllower.ScreenY; mfloorclip = walllower.ScreenY;
} }
rw_offset = 0; ProjectedWallTexcoords texcoords = ds->texcoords;
texcoords.texturemid = texturemid;
FSoftwareTexture *rw_pic = tex; FSoftwareTexture *rw_pic = tex;
double top, bot; double top, bot;
@ -379,7 +385,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, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, ds->texcoords, ds->texcoords.yscale, top, bot, true, additive, alpha, rw_offset, mLight, nullptr); renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
} }
return false; return false;
@ -424,7 +430,7 @@ namespace swrenderer
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid); double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid);
double planez = rover->model->GetPlaneTexZ(sector_t::ceiling); double planez = rover->model->GetPlaneTexZ(sector_t::ceiling);
rw_offset = FLOAT2FIXED(curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid)); fixed_t rw_offset = FLOAT2FIXED(curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid));
if (rowoffset < 0) if (rowoffset < 0)
{ {
rowoffset += rw_pic->GetHeight(); rowoffset += rw_pic->GetHeight();
@ -465,12 +471,15 @@ 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, WallT);
walltexcoords.texturemid = texturemid;
walltexcoords.yscale = yscale;
walltexcoords.xoffset = rw_offset;
double top, bot; double top, bot;
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, texturemid, walltexcoords, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, rw_offset, mLight, nullptr); 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);
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);
} }

View file

@ -54,8 +54,6 @@ namespace swrenderer
ProjectedWallLight mLight; ProjectedWallLight mLight;
fixed_t rw_offset = 0;
ProjectedWallLine wallupper; ProjectedWallLine wallupper;
ProjectedWallLine walllower; ProjectedWallLine walllower;
}; };

View file

@ -54,7 +54,7 @@
namespace swrenderer namespace swrenderer
{ {
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords) void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
{ {
if (rw_pic == nullptr) if (rw_pic == nullptr)
return; return;
@ -63,8 +63,6 @@ namespace swrenderer
if (fracbits == 32) if (fracbits == 32)
{ // Hack for one pixel tall textures { // Hack for one pixel tall textures
fracbits = 0; fracbits = 0;
yrepeat = 0;
texturemid = 0;
} }
WallDrawerArgs drawerargs; WallDrawerArgs drawerargs;
@ -116,11 +114,11 @@ namespace swrenderer
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(texcoords.UPos(x + 1)) - FIXED2DBL(texcoords.UPos(x))); if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(texcoords.UPos(x + 1)) - FIXED2DBL(texcoords.UPos(x)));
fixed_t xxoffset = (texcoords.UPos(x) + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale(); fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
// Normalize to 0-1 range: // Normalize to 0-1 range:
double uv_stepd = texcoords.VStep(x) * yrepeat; double uv_stepd = texcoords.VStep(x) * texcoords.yscale;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight(); double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
v = v - floor(v); v = v - floor(v);
double v_step = uv_stepd / rw_pic->GetHeight(); double v_step = uv_stepd / rw_pic->GetHeight();
@ -232,14 +230,14 @@ namespace swrenderer
uint32_t uv_pos; uint32_t uv_pos;
uint32_t uv_step; uint32_t uv_step;
fixed_t xxoffset = (texcoords.UPos(x) + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale(); fixed_t xxoffset = (texcoords.UPos(x) + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
if (uv_fracbits != 32) if (uv_fracbits != 32)
{ {
// Find start uv in [0-base_height[ range. // 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. // 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) * yrepeat; double uv_stepd = texcoords.VStep(x) * texcoords.yscale;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight(); double v = (texcoords.texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
v = v - floor(v); v = v - floor(v);
v *= height; v *= height;
v *= (1 << uv_fracbits); v *= (1 << uv_fracbits);
@ -410,7 +408,7 @@ namespace swrenderer
} }
} }
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords) void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
{ {
ProjectedWallLine most1, most2, most3; ProjectedWallLine most1, most2, most3;
const short *up; const short *up;
@ -434,7 +432,7 @@ namespace swrenderer
{ {
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]); down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
} }
ProcessNormalWall(up, down, texturemid, texcoords); ProcessNormalWall(up, down, texcoords);
up = down; up = down;
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY; down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
} }
@ -442,19 +440,19 @@ namespace swrenderer
mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]); mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]);
} }
ProcessNormalWall(up, dwal, texturemid, texcoords); ProcessNormalWall(up, dwal, texcoords);
} }
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords) void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords)
{ {
CameraLight *cameraLight = CameraLight::Instance(); CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size())) if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
{ {
ProcessNormalWall(uwal, dwal, texturemid, texcoords); ProcessNormalWall(uwal, dwal, texcoords);
} }
else else
{ {
ProcessStripedWall(uwal, dwal, texturemid, texcoords); ProcessStripedWall(uwal, dwal, texcoords);
} }
} }
@ -469,23 +467,23 @@ namespace swrenderer
// //
//============================================================================= //=============================================================================
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords, double top, double bot) void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, ProjectedWallTexcoords texcoords, double top, double bot)
{ {
ProjectedWallLine most1, most2, most3; ProjectedWallLine most1, most2, most3;
double texheight = rw_pic->GetHeight(); double texheight = rw_pic->GetHeight();
double partition; double partition;
double scaledtexheight = texheight / yrepeat; double scaledtexheight = texheight / texcoords.yscale;
if (yrepeat >= 0) if (texcoords.yscale >= 0)
{ // normal orientation: draw strips from top to bottom { // normal orientation: draw strips from top to bottom
partition = top - fmod(top - texturemid / yrepeat - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight); partition = top - fmod(top - texcoords.texturemid / texcoords.yscale - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight);
if (partition == top) if (partition == top)
{ {
partition -= scaledtexheight; partition -= scaledtexheight;
} }
const short *up = uwal; const short *up = uwal;
short *down = most1.ScreenY; short *down = most1.ScreenY;
texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + texheight; texcoords.texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * texcoords.yscale + texheight;
while (partition > bot) while (partition > bot)
{ {
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC); ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC);
@ -495,21 +493,21 @@ namespace swrenderer
{ {
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]); down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
} }
ProcessWall(up, down, texturemid, texcoords); ProcessWall(up, down, texcoords);
up = down; up = down;
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY; down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
} }
partition -= scaledtexheight; partition -= scaledtexheight;
texturemid -= texheight; texcoords.texturemid -= texheight;
} }
ProcessWall(up, dwal, texturemid, texcoords); ProcessWall(up, dwal, texcoords);
} }
else else
{ // upside down: draw strips from bottom to top { // upside down: draw strips from bottom to top
partition = bot - fmod(bot - texturemid / yrepeat - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight); partition = bot - fmod(bot - texcoords.texturemid / texcoords.yscale - Thread->Viewport->viewpoint.Pos.Z, scaledtexheight);
short *up = most1.ScreenY; short *up = most1.ScreenY;
const short *down = dwal; const short *down = dwal;
texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + texheight; texcoords.texturemid = (partition - Thread->Viewport->viewpoint.Pos.Z) * texcoords.yscale + texheight;
while (partition < top) while (partition < top)
{ {
ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC); ProjectedWallCull j = most3.Project(Thread->Viewport.get(), partition - Thread->Viewport->viewpoint.Pos.Z, &WallC);
@ -519,27 +517,25 @@ namespace swrenderer
{ {
up[j] = clamp(most3.ScreenY[j], uwal[j], down[j]); up[j] = clamp(most3.ScreenY[j], uwal[j], down[j]);
} }
ProcessWall(up, down, texturemid, texcoords); ProcessWall(up, down, texcoords);
down = up; down = up;
up = (up == most1.ScreenY) ? most2.ScreenY : most1.ScreenY; up = (up == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
} }
partition -= scaledtexheight; partition -= scaledtexheight;
texturemid -= texheight; texcoords.texturemid -= texheight;
} }
ProcessWall(uwal, down, texturemid, texcoords); 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, double texturemid, const ProjectedWallTexcoords& texcoords, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, fixed_t xoffset, const ProjectedWallLight &light, FLightNode *light_list) 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->x1 = x1;
this->x2 = x2; this->x2 = x2;
this->frontsector = frontsector; this->frontsector = frontsector;
this->curline = curline; this->curline = curline;
this->WallC = WallC; this->WallC = WallC;
this->yrepeat = yscale;
this->mLight = light; this->mLight = light;
this->xoffset = xoffset;
this->light_list = light_list; this->light_list = light_list;
this->rw_pic = pic; this->rw_pic = pic;
this->mask = mask; this->mask = mask;
@ -548,13 +544,13 @@ namespace swrenderer
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here. Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits()) if (rw_pic->GetHeight() != (1 << rw_pic->GetHeightBits()))
{ {
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords, top, bottom); ProcessWallNP2(walltop, wallbottom, texcoords, top, bottom);
} }
else else
{ {
ProcessWall(walltop, wallbottom, texturemid, texcoords); ProcessWall(walltop, wallbottom, texcoords);
} }
} }

View file

@ -54,25 +54,22 @@ namespace swrenderer
int x2, int x2,
const short *walltop, const short *walltop,
const short *wallbottom, const short *wallbottom,
double texturemid,
const ProjectedWallTexcoords &texcoords, const ProjectedWallTexcoords &texcoords,
double yscale,
double top, double top,
double bottom, double bottom,
bool mask, bool mask,
bool additive, bool additive,
fixed_t alpha, fixed_t alpha,
fixed_t xoffset,
const ProjectedWallLight &light, const ProjectedWallLight &light,
FLightNode *light_list); FLightNode *light_list);
RenderThread *Thread = nullptr; RenderThread *Thread = nullptr;
private: private:
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords, double top, double bot); void ProcessWallNP2(const short *uwal, const short *dwal, ProjectedWallTexcoords texcoords, double top, double bot);
void ProcessWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords); void ProcessWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords); void ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords); void ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
void SetLights(WallDrawerArgs &drawerargs, int x, int y1); void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
int x1 = 0; int x1 = 0;
@ -84,8 +81,6 @@ namespace swrenderer
ProjectedWallLight mLight; ProjectedWallLight mLight;
double yrepeat = 0.0;
fixed_t xoffset = 0;
FLightNode *light_list = nullptr; FLightNode *light_list = nullptr;
bool mask = false; bool mask = false;
bool additive = false; bool additive = false;

View file

@ -227,6 +227,7 @@ namespace swrenderer
this->x1 = x1; this->x1 = x1;
this->x2 = x2; this->x2 = x2;
this->WallT = WallT; this->WallT = WallT;
this->flipx = flipx;
CenterX = viewport->CenterX; CenterX = viewport->CenterX;
WallTMapScale2 = viewport->WallTMapScale2; WallTMapScale2 = viewport->WallTMapScale2;
valid = true; valid = true;

View file

@ -68,6 +68,7 @@ namespace swrenderer
float yscale = 1.0f; float yscale = 1.0f;
fixed_t xoffset = 0; fixed_t xoffset = 0;
double texturemid = 0.0f;
explicit operator bool() const { return valid; } explicit operator bool() const { return valid; }

View file

@ -241,9 +241,6 @@ namespace swrenderer
return; return;
} }
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT, flipx);
// Prepare lighting // Prepare lighting
usecolormap = light.GetBaseColormap(); usecolormap = light.GetBaseColormap();
@ -271,6 +268,12 @@ namespace swrenderer
} }
maskedScaleY = float(1 / yscale); maskedScaleY = float(1 / yscale);
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT, flipx);
walltexcoords.yscale = maskedScaleY;
walltexcoords.texturemid = texturemid;
do do
{ {
int x = x1; int x = x1;
@ -291,7 +294,7 @@ namespace swrenderer
{ // calculate lighting { // calculate lighting
drawerargs.SetLight(lightpos, light.GetLightLevel(), light.GetFoggy(), thread->Viewport.get()); drawerargs.SetLight(lightpos, light.GetLightLevel(), light.GetFoggy(), thread->Viewport.get());
} }
drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
lightpos += light.GetLightStep(); lightpos += light.GetLightStep();
x++; x++;
} }

View file

@ -174,9 +174,6 @@ namespace swrenderer
FWallTmapVals WallT; FWallTmapVals WallT;
WallT.InitFromWallCoords(thread, &spr->wallc); WallT.InitFromWallCoords(thread, &spr->wallc);
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(thread->Viewport.get(), spr->pic->GetWidth(), x1, x2, WallT, spr->renderflags & RF_XFLIP);
iyscale = 1 / spr->yscale; iyscale = 1 / spr->yscale;
double texturemid = (spr->gzt - thread->Viewport->viewpoint.Pos.Z) * iyscale; double texturemid = (spr->gzt - thread->Viewport->viewpoint.Pos.Z) * iyscale;
@ -218,6 +215,11 @@ namespace swrenderer
int x = x1; int x = x1;
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(thread->Viewport.get(), spr->pic->GetWidth(), x1, x2, WallT, spr->renderflags & RF_XFLIP);
walltexcoords.yscale = maskedScaleY;
walltexcoords.texturemid = texturemid;
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
thread->PrepareTexture(WallSpriteTile, spr->RenderStyle); thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
@ -229,7 +231,7 @@ namespace swrenderer
drawerargs.SetLight(light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get()); drawerargs.SetLight(light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get());
} }
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle); drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
light += lightstep; light += lightstep;
x++; x++;
} }

View file

@ -43,17 +43,17 @@ namespace swrenderer
colfunc = &SWPixelFormatDrawers::DrawColumn; colfunc = &SWPixelFormatDrawers::DrawColumn;
} }
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const ProjectedWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style) void SpriteDrawerArgs::DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const ProjectedWallTexcoords& walltexcoords, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style)
{ {
auto viewport = thread->Viewport.get(); auto viewport = thread->Viewport.get();
float iscale = walltexcoords.VStep(x) * maskedScaleY; float iscale = walltexcoords.VStep(x) * walltexcoords.yscale;
double spryscale = 1 / iscale; double spryscale = 1 / iscale;
double sprtopscreen; double sprtopscreen;
if (sprflipvert) if (sprflipvert)
sprtopscreen = viewport->CenterY + texturemid * spryscale; sprtopscreen = viewport->CenterY + walltexcoords.texturemid * spryscale;
else else
sprtopscreen = viewport->CenterY - texturemid * spryscale; sprtopscreen = viewport->CenterY - walltexcoords.texturemid * spryscale;
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos(x), spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style); DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos(x), spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
} }

View file

@ -34,7 +34,7 @@ namespace swrenderer
void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; } void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; }
void SetDynamicLight(uint32_t color) { dynlightcolor = color; } void SetDynamicLight(uint32_t color) { dynlightcolor = color; }
void DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const ProjectedWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style); void DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const ProjectedWallTexcoords& walltexcoords, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style);
void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false); void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false);
void FillColumn(RenderThread *thread); void FillColumn(RenderThread *thread);
void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount); void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount);