mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Move all ProjectedWallTexcoords calculations to that class
This commit is contained in:
parent
e388abbb77
commit
fa3e5e34a8
5 changed files with 307 additions and 291 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue