- merge top/mid/bottom texture coordinate calculations

This commit is contained in:
Magnus Norddahl 2019-11-11 03:19:00 +01:00
parent 81753e5ffb
commit 6410bc81cc
3 changed files with 244 additions and 249 deletions

View file

@ -423,8 +423,8 @@ namespace swrenderer
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)) :
mTopTexture ? (mTopTexture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) :
mBottomTexture ? (mBottomTexture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) :
1.;
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
@ -679,9 +679,7 @@ namespace swrenderer
markfloor = ShouldMarkFloor();
markceiling = ShouldMarkCeiling();
SetTopTexture();
SetMiddleTexture();
SetBottomTexture();
SetTextures();
if (mBackSector && !(sidedef == linedef->sidedef[0] && (linedef->special == Line_Mirror && r_drawmirrors)))
{
@ -709,7 +707,7 @@ namespace swrenderer
FTexture *ftex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
FSoftwareTexture *midtex = ftex && ftex->isValid() ? ftex->GetSoftwareTexture() : nullptr;
bool segtextured = ftex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL;
bool segtextured = ftex != NULL || mTopTexture != NULL || mBottomTexture != NULL;
if (m3DFloor.type == Fake3DOpaque::Normal)
{
@ -723,259 +721,65 @@ namespace swrenderer
}
}
void SWRenderLine::SetTextures()
{
mTopTexture = nullptr;
mMiddleTexture = nullptr;
mBottomTexture = nullptr;
side_t* sidedef = mLineSegment->sidedef;
line_t* linedef = mLineSegment->linedef;
if (sidedef == linedef->sidedef[0] && (linedef->special == Line_Mirror && r_drawmirrors)) return;
if (!mBackSector)
{
SetMiddleTexture();
}
else
{
if (mFrontCeilingZ1 > mBackCeilingZ1 || mFrontCeilingZ2 > mBackCeilingZ2) SetTopTexture();
if (mFrontFloorZ1 < mBackFloorZ1 || mFrontFloorZ2 < mBackFloorZ2) SetBottomTexture();
}
}
void SWRenderLine::SetTopTexture()
{
mTopPart.Texture = nullptr;
if (!(mFrontCeilingZ1 > mBackCeilingZ1 || mFrontCeilingZ2 > mBackCeilingZ2)) return;
side_t *sidedef = mLineSegment->sidedef;
line_t *linedef = mLineSegment->linedef;
if (sidedef == linedef->sidedef[0] && (linedef->special == Line_Mirror && r_drawmirrors)) return;
if (!mBackSector) return;
// No top texture for skyhack lines
if (mFrontSector->GetTexture(sector_t::ceiling) == skyflatnum && mBackSector->GetTexture(sector_t::ceiling) == skyflatnum) return;
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::top), true);
mTopPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
if (mTopPart.Texture == nullptr) return;
if (!tex || !tex->isValid()) return;
fixed_t TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::top));
double rowoffset = sidedef->GetTextureYOffset(side_t::top);
double TextureScaleU = sidedef->GetTextureXScale(side_t::top);
double TextureScaleV = sidedef->GetTextureYScale(side_t::top);
double yrepeat = mTopPart.Texture->GetScale().Y * TextureScaleV;
double TextureMid;
if (yrepeat >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGTOP)
{ // top of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
if (rowoffset < 0 && mTopPart.Texture != NULL)
{
rowoffset += mTopPart.Texture->GetHeight();
}
}
else
{ // bottom of texture at bottom
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mTopPart.Texture->GetHeight();
}
}
else
{ // upside down
rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGTOP)
{ // bottom of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mTopPart.Texture->GetHeight();
}
else
{ // top of texture at bottom
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
}
}
if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
TextureMid += rowoffset * yrepeat;
}
else
{
TextureMid += rowoffset;
}
auto rw_pic = mTopPart.Texture;
double xscale = rw_pic->GetScale().X * TextureScaleU;
double yscale = rw_pic->GetScale().Y * TextureScaleV;
mTopPart.texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * xscale, WallC.sx1, WallC.sx2, WallT);
if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mTopPart.texcoords.xoffset = xs_RoundToInt(TextureOffsetU * xscale);
}
else
{
mTopPart.texcoords.xoffset = TextureOffsetU;
}
if (xscale < 0)
{
mTopPart.texcoords.xoffset = -mTopPart.texcoords.xoffset;
}
mTopPart.texcoords.yscale = yscale;
mTopPart.texcoords.texturemid = TextureMid;
mTopTexture = tex->GetSoftwareTexture();
}
void SWRenderLine::SetMiddleTexture()
{
mMiddlePart.Texture = nullptr;
side_t *sidedef = mLineSegment->sidedef;
line_t *linedef = mLineSegment->linedef;
if (sidedef == linedef->sidedef[0] && (linedef->special == Line_Mirror && r_drawmirrors)) return;
if (mBackSector) return;
// [RH] Horizon lines do not need to be textured
if (linedef->isVisualPortal()) return;
if (linedef->special == Line_Horizon) return;
auto tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
mMiddlePart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
if (mMiddlePart.Texture == nullptr) return;
fixed_t TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
double rowoffset = sidedef->GetTextureYOffset(side_t::mid);
double TextureScaleU = sidedef->GetTextureXScale(side_t::mid);
double TextureScaleV = sidedef->GetTextureYScale(side_t::mid);
double yrepeat = mMiddlePart.Texture->GetScale().Y * TextureScaleV;
double TextureMid;
if (yrepeat >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mMiddlePart.Texture->GetHeight();
}
else
{ // top of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
if (rowoffset < 0 && mMiddlePart.Texture != NULL)
{
rowoffset += mMiddlePart.Texture->GetHeight();
}
}
}
else
{ // upside down
rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
}
else
{ // bottom of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mMiddlePart.Texture->GetHeight();
}
}
if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
TextureMid += rowoffset * yrepeat;
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
TextureMid += rowoffset;
}
if (!tex || !tex->isValid()) return;
auto rw_pic = mMiddlePart.Texture;
double xscale = rw_pic->GetScale().X * TextureScaleU;
double yscale = rw_pic->GetScale().Y * TextureScaleV;
mMiddlePart.texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * xscale, WallC.sx1, WallC.sx2, WallT);
if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mMiddlePart.texcoords.xoffset = xs_RoundToInt(TextureOffsetU * xscale);
}
else
{
mMiddlePart.texcoords.xoffset = TextureOffsetU;
}
if (xscale < 0)
{
mMiddlePart.texcoords.xoffset = -mMiddlePart.texcoords.xoffset;
}
mMiddlePart.texcoords.yscale = yscale;
mMiddlePart.texcoords.texturemid = TextureMid;
mMiddleTexture = tex->GetSoftwareTexture();
}
void SWRenderLine::SetBottomTexture()
{
mBottomPart.Texture = nullptr;
if (!(mFrontFloorZ1 < mBackFloorZ1 || mFrontFloorZ2 < mBackFloorZ2)) return;
side_t *sidedef = mLineSegment->sidedef;
line_t *linedef = mLineSegment->linedef;
if (sidedef == linedef->sidedef[0] && (linedef->special == Line_Mirror && r_drawmirrors)) return;
if (!mBackSector) return;
double frontlowertop = mFrontSector->GetPlaneTexZ(sector_t::ceiling);
if (mFrontSector->GetTexture(sector_t::ceiling) == skyflatnum && mBackSector->GetTexture(sector_t::ceiling) == skyflatnum)
{
// Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works.
frontlowertop = mBackSector->GetPlaneTexZ(sector_t::ceiling);
}
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::bottom), true);
mBottomPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
if (!mBottomPart.Texture) return;
if (!tex || !tex->isValid()) return;
fixed_t TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::bottom));
double rowoffset = sidedef->GetTextureYOffset(side_t::bottom);
double TextureScaleU = sidedef->GetTextureXScale(side_t::bottom);
double TextureScaleV = sidedef->GetTextureYScale(side_t::bottom);
double yrepeat = mBottomPart.Texture->GetScale().Y * TextureScaleV;
double TextureMid;
if (yrepeat >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (frontlowertop - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
}
else
{ // top of texture at top
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
if (rowoffset < 0 && mBottomPart.Texture != NULL)
{
rowoffset += mBottomPart.Texture->GetHeight();
}
}
}
else
{ // upside down
rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (frontlowertop - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
}
else
{ // bottom of texture at top
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mBottomPart.Texture->GetHeight();
}
}
if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
TextureMid += rowoffset * yrepeat;
}
else
{
TextureMid += rowoffset;
}
auto rw_pic = mBottomPart.Texture;
double xscale = rw_pic->GetScale().X * TextureScaleU;
double yscale = rw_pic->GetScale().Y * TextureScaleV;
mBottomPart.texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * xscale, WallC.sx1, WallC.sx2, WallT);
if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mBottomPart.texcoords.xoffset = xs_RoundToInt(TextureOffsetU * xscale);
}
else
{
mBottomPart.texcoords.xoffset = TextureOffsetU;
}
if (xscale < 0)
{
mBottomPart.texcoords.xoffset = -mBottomPart.texcoords.xoffset;
}
mBottomPart.texcoords.yscale = yscale;
mBottomPart.texcoords.texturemid = TextureMid;
mBottomTexture = tex->GetSoftwareTexture();
}
bool SWRenderLine::IsFogBoundary(sector_t *front, sector_t *back) const
@ -1093,14 +897,14 @@ namespace swrenderer
auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = Thread->OpaquePass->floorclip;
if (mMiddlePart.Texture) // one sided line
if (mMiddleTexture) // one sided line
{
fillshort(ceilingclip + x1, x2 - x1, viewheight);
fillshort(floorclip + x1, x2 - x1, 0xffff);
}
else
{ // two sided line
if (mTopPart.Texture != nullptr)
if (mTopTexture != nullptr)
{ // top wall
for (int x = x1; x < x2; ++x)
{
@ -1113,7 +917,7 @@ namespace swrenderer
memcpy(ceilingclip + x1, walltop.ScreenY + x1, (x2 - x1) * sizeof(short));
}
if (mBottomPart.Texture != nullptr)
if (mBottomTexture != nullptr)
{ // bottom wall
for (int x = x1; x < x2; ++x)
{
@ -1130,31 +934,221 @@ namespace swrenderer
void SWRenderLine::RenderTopTexture(int x1, int x2)
{
if (mMiddlePart.Texture) return;
if (!mTopPart.Texture) return;
if (mMiddleTexture) return;
if (!mTopTexture) return;
if (!viewactive) return;
side_t* sidedef = mLineSegment->sidedef;
line_t* linedef = mLineSegment->linedef;
double yscale = GetYScale(sidedef, mTopTexture, side_t::top);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
double TextureMid;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGTOP)
{ // top of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
else
{ // bottom of texture at bottom
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + mTopTexture->GetHeight();
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGTOP)
{ // bottom of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + mTopTexture->GetHeight();
}
else
{ // top of texture at bottom
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
}
TextureMid += GetRowOffset(linedef, sidedef, mTopTexture, side_t::top);
ProjectedWallTexcoords texcoords;
texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * GetXScale(sidedef, mTopTexture, side_t::top), WallC.sx1, WallC.sx2, WallT);
texcoords.xoffset = GetXOffset(sidedef, mTopTexture, side_t::top);
texcoords.yscale = yscale;
texcoords.texturemid = TextureMid;
RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mTopPart.Texture, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.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, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, mLight, GetLightList());
}
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
{
if (!mMiddlePart.Texture) return;
if (!mMiddleTexture) return;
if (!viewactive) return;
side_t* sidedef = mLineSegment->sidedef;
line_t* linedef = mLineSegment->linedef;
double yscale = GetYScale(sidedef, mMiddleTexture, side_t::mid);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
double TextureMid;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale + mMiddleTexture->GetHeight();
}
else
{ // top of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale;
}
else
{ // bottom of texture at top
TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + mMiddleTexture->GetHeight();
}
}
TextureMid += GetRowOffset(linedef, sidedef, mMiddleTexture, side_t::mid);
ProjectedWallTexcoords texcoords;
texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * GetXScale(sidedef, mMiddleTexture, side_t::mid), WallC.sx1, WallC.sx2, WallT);
texcoords.xoffset = GetXOffset(sidedef, mMiddleTexture, side_t::mid);
texcoords.yscale = yscale;
texcoords.texturemid = TextureMid;
RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mMiddlePart.Texture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.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, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
}
void SWRenderLine::RenderBottomTexture(int x1, int x2)
{
if (mMiddlePart.Texture) return;
if (!mBottomPart.Texture) return;
if (mMiddleTexture) return;
if (!mBottomTexture) return;
if (!viewactive) return;
side_t* sidedef = mLineSegment->sidedef;
line_t* linedef = mLineSegment->linedef;
double frontlowertop = mFrontSector->GetPlaneTexZ(sector_t::ceiling);
if (mFrontSector->GetTexture(sector_t::ceiling) == skyflatnum && mBackSector->GetTexture(sector_t::ceiling) == skyflatnum)
{
// Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works.
frontlowertop = mBackSector->GetPlaneTexZ(sector_t::ceiling);
}
double yscale = GetYScale(sidedef, mBottomTexture, side_t::bottom);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
double TextureMid;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
TextureMid = (frontlowertop - cameraZ) * yscale;
}
else
{ // top of texture at top
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale;
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
TextureMid = (frontlowertop - cameraZ) * yscale;
}
else
{ // bottom of texture at top
TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale + mBottomTexture->GetHeight();
}
}
TextureMid += GetRowOffset(linedef, sidedef, mBottomTexture, side_t::bottom);
ProjectedWallTexcoords texcoords;
texcoords.Project(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength * GetXScale(sidedef, mBottomTexture, side_t::bottom), WallC.sx1, WallC.sx2, WallT);
texcoords.xoffset = GetXOffset(sidedef, mBottomTexture, side_t::bottom);
texcoords.yscale = yscale;
texcoords.texturemid = TextureMid;
RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomPart.Texture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.texcoords, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, mLight, GetLightList());
}
double SWRenderLine::GetRowOffset(line_t* linedef, side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double yrepeat = GetYScale(sidedef, tex, texpart);
double rowoffset = sidedef->GetTextureYOffset(texpart);
if (yrepeat >= 0)
{
// check if top of texture at top:
bool top_at_top =
(texpart == side_t::top && (linedef->flags & ML_DONTPEGTOP)) ||
(texpart != side_t::top && !(linedef->flags & ML_DONTPEGBOTTOM));
if (rowoffset < 0 && top_at_top)
{
rowoffset += tex->GetHeight();
}
}
else
{
rowoffset = -rowoffset;
}
if (tex->useWorldPanning(mLineSegment->GetLevel()))
{
return rowoffset * yrepeat;
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
return rowoffset;
}
}
fixed_t SWRenderLine::GetXOffset(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
fixed_t TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(texpart));
double xscale = GetXScale(sidedef, tex, texpart);
fixed_t xoffset;
if (tex->useWorldPanning(mLineSegment->GetLevel()))
{
xoffset = xs_RoundToInt(TextureOffsetU * xscale);
}
else
{
xoffset = TextureOffsetU;
}
if (xscale < 0)
{
xoffset = -xoffset;
}
return xoffset;
}
double SWRenderLine::GetXScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double TextureScaleU = sidedef->GetTextureXScale(texpart);
return tex->GetScale().X * TextureScaleU;
}
double SWRenderLine::GetYScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double TextureScaleV = sidedef->GetTextureYScale(texpart);
return tex->GetScale().Y * TextureScaleV;
}
FLightNode *SWRenderLine::GetLightList()

View file

@ -50,12 +50,6 @@ namespace swrenderer
bool Init(RenderThread *thread, const DVector2 &pt1, const DVector2 &pt2, double too_close);
};
struct WallPartTexture
{
FSoftwareTexture *Texture;
ProjectedWallTexcoords texcoords;
};
class SWRenderLine : VisibleSegmentRenderer
{
public:
@ -67,6 +61,7 @@ namespace swrenderer
private:
bool RenderWallSegment(int x1, int x2) override;
void SetWallVariables();
void SetTextures();
void SetTopTexture();
void SetMiddleTexture();
void SetBottomTexture();
@ -79,6 +74,12 @@ namespace swrenderer
void RenderMiddleTexture(int x1, int x2);
void RenderBottomTexture(int x1, int x2);
fixed_t GetXOffset(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
double GetXScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
double GetYScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
double GetRowOffset(line_t* linedef, side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
FLightNode *GetLightList();
bool IsFogBoundary(sector_t *front, sector_t *back) const;
@ -125,9 +126,9 @@ namespace swrenderer
bool markfloor; // False if the back side is the same plane.
bool markceiling;
WallPartTexture mTopPart;
WallPartTexture mMiddlePart;
WallPartTexture mBottomPart;
FSoftwareTexture* mTopTexture;
FSoftwareTexture* mMiddleTexture;
FSoftwareTexture* mBottomTexture;
ProjectedWallCull mCeilingClipped;
ProjectedWallCull mFloorClipped;

View file

@ -316,7 +316,7 @@ namespace swrenderer
lightpos += mLight.GetLightStep();
}
columndrawerargs.DrawMaskedColumn(Thread, x, tex, ds->texcoords, sprflipvert, mfloorclip, mceilingclip, renderstyle);
columndrawerargs.DrawMaskedColumn(Thread, x, tex, texcoords, sprflipvert, mfloorclip, mceilingclip, renderstyle);
}
}
}
@ -385,7 +385,7 @@ namespace swrenderer
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
RenderWallPart renderWallpart(Thread);
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texcoords, top, bot, true, additive, alpha, mLight, nullptr);
}
return false;