Move all ProjectedWallTexcoords calculations to that class

This commit is contained in:
Magnus Norddahl 2019-11-12 02:22:30 +01:00
parent e388abbb77
commit fa3e5e34a8
5 changed files with 307 additions and 291 deletions

View file

@ -301,7 +301,6 @@ namespace swrenderer
SetWallVariables();
}
line_t *linedef = mLineSegment->linedef;
side_t *sidedef = mLineSegment->sidedef;
RenderPortal *renderportal = Thread->Portal.get();
@ -419,43 +418,7 @@ namespace swrenderer
if (pic)
{
draw_segment->SetHas3DFloorMidTexture();
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 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
{ // 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);
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.ProjectTranslucent(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, pic);
}
}
@ -959,43 +922,8 @@ namespace swrenderer
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;
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());
@ -1006,43 +934,8 @@ namespace swrenderer
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;
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());
@ -1054,124 +947,13 @@ namespace swrenderer
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;
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());
}
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()
{
CameraLight *cameraLight = CameraLight::Instance();

View file

@ -74,12 +74,6 @@ 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;

View file

@ -149,15 +149,16 @@ namespace swrenderer
{ // Texture does not wrap vertically.
// find positioning
double texheight = tex->GetScaledHeightDouble();
double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid));
if (texheightscale != 1)
{
texheight = texheight / texheightscale;
}
bool sprflipvert = ds->texcoords.yscale < 0;
double textop = ds->texcoords.texturemid / ds->texcoords.yscale;
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(ds->texcoords.yscale);
double textop = texturemid + rowoffset - Thread->Viewport->viewpoint.Pos.Z;
// [RH] Don't bother drawing segs that are completely offscreen
if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop)
@ -290,10 +291,6 @@ namespace swrenderer
void RenderDrawSegment::Render3DFloorWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic)
{
int i;
double xscale;
double yscale;
fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
if (Alpha <= 0)
return;
@ -303,70 +300,23 @@ namespace swrenderer
const short *mfloorclip = ds->sprbottomclip - ds->x1;
const short *mceilingclip = ds->sprtopclip - ds->x1;
// find positioning
side_t *scaledside;
side_t::ETexpart scaledpart;
if (rover->flags & FF_UPPERTEXTURE)
{
scaledside = curline->sidedef;
scaledpart = side_t::top;
}
else if (rover->flags & FF_LOWERTEXTURE)
{
scaledside = curline->sidedef;
scaledpart = side_t::bottom;
}
else
{
scaledside = rover->master->sidedef[0];
scaledpart = side_t::mid;
}
xscale = rw_pic->GetScale().X * scaledside->GetTextureXScale(scaledpart);
yscale = rw_pic->GetScale().Y * scaledside->GetTextureYScale(scaledpart);
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid);
double planez = rover->model->GetPlaneTexZ(sector_t::ceiling);
fixed_t rw_offset = FLOAT2FIXED(curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid));
if (rowoffset < 0)
{
rowoffset += rw_pic->GetHeight();
}
double texturemid = (planez - Thread->Viewport->viewpoint.Pos.Z) * yscale;
if (rw_pic->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 = texturemid + rowoffset * yscale;
rw_offset = xs_RoundToInt(rw_offset * xscale);
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
texturemid += rowoffset;
}
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);
for (i = x1; i < x2; i++)
for (int i = x1; i < x2; i++)
{
if (wallupper.ScreenY[i] < mceilingclip[i])
wallupper.ScreenY[i] = mceilingclip[i];
}
for (i = x1; i < x2; i++)
for (int i = x1; i < x2; i++)
{
if (walllower.ScreenY[i] > mfloorclip[i])
walllower.ScreenY[i] = mfloorclip[i];
}
ProjectedWallTexcoords walltexcoords;
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;
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC.sx1, ds->WallC.sx2, ds->tmapvals, rw_pic);
double top, bot;
GetMaskedWallTopBottom(ds, top, bot);

View file

@ -221,6 +221,217 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////
void ProjectedWallTexcoords::ProjectTop(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic)
{
side_t* sidedef = lineseg->sidedef;
line_t* linedef = lineseg->linedef;
yscale = GetYScale(sidedef, pic, side_t::top);
double cameraZ = viewport->viewpoint.Pos.Z;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGTOP)
{ // top of texture at top
texturemid = (frontsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
else
{ // bottom of texture at bottom
texturemid = (backsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + pic->GetHeight();
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGTOP)
{ // bottom of texture at top
texturemid = (frontsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + pic->GetHeight();
}
else
{ // top of texture at bottom
texturemid = (backsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
}
texturemid += GetRowOffset(lineseg, pic, side_t::top);
Project(viewport, sidedef->TexelLength * GetXScale(sidedef, pic, side_t::top), x1, x2, WallT);
xoffset = GetXOffset(lineseg, pic, side_t::top);
}
void ProjectedWallTexcoords::ProjectMid(RenderViewport* viewport, sector_t* frontsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic)
{
side_t* sidedef = lineseg->sidedef;
line_t* linedef = lineseg->linedef;
yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = viewport->viewpoint.Pos.Z;
if (yscale >= 0)
{ // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom
texturemid = (frontsector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale + pic->GetHeight();
}
else
{ // top of texture at top
texturemid = (frontsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale;
}
}
else
{ // upside down
if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom
texturemid = (frontsector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale;
}
else
{ // bottom of texture at top
texturemid = (frontsector->GetPlaneTexZ(sector_t::ceiling) - cameraZ) * yscale + pic->GetHeight();
}
}
texturemid += GetRowOffset(lineseg, pic, side_t::mid);
Project(viewport, sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), x1, x2, WallT);
xoffset = GetXOffset(lineseg, pic, side_t::mid);
}
void ProjectedWallTexcoords::ProjectBottom(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic)
{
side_t* sidedef = lineseg->sidedef;
line_t* linedef = lineseg->linedef;
double frontlowertop = frontsector->GetPlaneTexZ(sector_t::ceiling);
if (frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum)
{
// Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works.
frontlowertop = backsector->GetPlaneTexZ(sector_t::ceiling);
}
yscale = GetYScale(sidedef, pic, side_t::bottom);
double cameraZ = viewport->viewpoint.Pos.Z;
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 = (backsector->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 = (backsector->GetPlaneTexZ(sector_t::floor) - cameraZ) * yscale + pic->GetHeight();
}
}
texturemid += GetRowOffset(lineseg, pic, side_t::bottom);
Project(viewport, sidedef->TexelLength * GetXScale(sidedef, pic, side_t::bottom), x1, x2, WallT);
xoffset = GetXOffset(lineseg, pic, side_t::bottom);
}
void ProjectedWallTexcoords::ProjectTranslucent(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic)
{
line_t* linedef = lineseg->linedef;
side_t* sidedef = lineseg->sidedef;
yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = viewport->viewpoint.Pos.Z;
double texZFloor = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor));
double texZCeiling = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
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
{ // 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(lineseg, pic, side_t::mid);
Project(viewport, sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), x1, x2, WallT);
xoffset = GetXOffset(lineseg, pic, side_t::mid);
}
void ProjectedWallTexcoords::Project3DFloor(RenderViewport* viewport, F3DFloor* rover, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic)
{
// find positioning
side_t* scaledside;
side_t::ETexpart scaledpart;
if (rover->flags & FF_UPPERTEXTURE)
{
scaledside = lineseg->sidedef;
scaledpart = side_t::top;
}
else if (rover->flags & FF_LOWERTEXTURE)
{
scaledside = lineseg->sidedef;
scaledpart = side_t::bottom;
}
else
{
scaledside = rover->master->sidedef[0];
scaledpart = side_t::mid;
}
double xscale = pic->GetScale().X * scaledside->GetTextureXScale(scaledpart);
yscale = pic->GetScale().Y * scaledside->GetTextureYScale(scaledpart);
double rowoffset = lineseg->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid);
double planez = rover->model->GetPlaneTexZ(sector_t::ceiling);
xoffset = FLOAT2FIXED(lineseg->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid));
if (rowoffset < 0)
{
rowoffset += pic->GetHeight();
}
texturemid = (planez - viewport->viewpoint.Pos.Z) * yscale;
if (pic->useWorldPanning(lineseg->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.
texturemid = texturemid + rowoffset * yscale;
xoffset = xs_RoundToInt(xoffset * xscale);
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
texturemid += rowoffset;
}
Project(viewport, lineseg->sidedef->TexelLength * xscale, x1, x2, WallT);
}
void ProjectedWallTexcoords::Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx)
{
this->walxrepeat = walxrepeat;
@ -273,6 +484,74 @@ namespace swrenderer
return value + xoffset;
}
double ProjectedWallTexcoords::GetRowOffset(seg_t* lineseg, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double yrepeat = GetYScale(lineseg->sidedef, tex, texpart);
double rowoffset = lineseg->sidedef->GetTextureYOffset(texpart);
if (yrepeat >= 0)
{
// check if top of texture at top:
bool top_at_top =
(texpart == side_t::top && (lineseg->linedef->flags & ML_DONTPEGTOP)) ||
(texpart != side_t::top && !(lineseg->linedef->flags & ML_DONTPEGBOTTOM));
if (rowoffset < 0 && top_at_top)
{
rowoffset += tex->GetHeight();
}
}
else
{
rowoffset = -rowoffset;
}
if (tex->useWorldPanning(lineseg->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 ProjectedWallTexcoords::GetXOffset(seg_t* lineseg, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
fixed_t TextureOffsetU = FLOAT2FIXED(lineseg->sidedef->GetTextureXOffset(texpart));
double xscale = GetXScale(lineseg->sidedef, tex, texpart);
fixed_t xoffset;
if (tex->useWorldPanning(lineseg->GetLevel()))
{
xoffset = xs_RoundToInt(TextureOffsetU * xscale);
}
else
{
xoffset = TextureOffsetU;
}
if (xscale < 0)
{
xoffset = -xoffset;
}
return xoffset;
}
double ProjectedWallTexcoords::GetXScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double TextureScaleU = sidedef->GetTextureXScale(texpart);
return tex->GetScale().X * TextureScaleU;
}
double ProjectedWallTexcoords::GetYScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart)
{
double TextureScaleV = sidedef->GetTextureYScale(texpart);
return tex->GetScale().Y * TextureScaleV;
}
/////////////////////////////////////////////////////////////////////////
void ProjectedWallLight::SetLightLeft(RenderThread *thread, const FWallCoords &wallc)

View file

@ -61,6 +61,12 @@ namespace swrenderer
class ProjectedWallTexcoords
{
public:
void ProjectTop(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic);
void ProjectMid(RenderViewport* viewport, sector_t* frontsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic);
void ProjectBottom(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic);
void ProjectTranslucent(RenderViewport* viewport, sector_t* frontsector, sector_t* backsector, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic);
void Project3DFloor(RenderViewport* viewport, F3DFloor* rover, seg_t* lineseg, int x1, int x2, const FWallTmapVals& WallT, FSoftwareTexture* pic);
void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx = false);
float VStep(int x) const;
@ -73,6 +79,11 @@ namespace swrenderer
explicit operator bool() const { return valid; }
private:
static fixed_t GetXOffset(seg_t* lineseg, FSoftwareTexture* tex, side_t::ETexpart texpart);
static double GetRowOffset(seg_t* lineseg, FSoftwareTexture* tex, side_t::ETexpart texpart);
static double GetXScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
static double GetYScale(side_t* sidedef, FSoftwareTexture* tex, side_t::ETexpart texpart);
bool valid = false;
double CenterX;
double WallTMapScale2;