- Calculate drawseg texture coordinates in r_line

This commit is contained in:
Magnus Norddahl 2019-11-11 04:10:08 +01:00
parent 6410bc81cc
commit 3944ee5b67
3 changed files with 57 additions and 53 deletions

View file

@ -301,6 +301,7 @@ namespace swrenderer
SetWallVariables();
}
line_t *linedef = mLineSegment->linedef;
side_t *sidedef = mLineSegment->sidedef;
RenderPortal *renderportal = Thread->Portal.get();
@ -419,23 +420,43 @@ namespace swrenderer
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid);
double lwallscale =
tex ? ((pic ? pic->GetScale().X : 1.0) * sidedef->GetTextureXScale(side_t::mid)) :
mTopTexture ? (mTopTexture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) :
mBottomTexture ? (mBottomTexture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) :
1.;
double yscale = GetYScale(sidedef, pic, side_t::mid);
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
if (pic && pic->useWorldPanning(sidedef->GetLevel()))
{
xoffset = xs_RoundToInt(xoffset * lwallscale);
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();
}
}
draw_segment->texcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT);
draw_segment->texcoords.xoffset = xoffset;
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->light = mLight.GetLightPos(start);

View file

@ -156,33 +156,33 @@ namespace swrenderer
const short *mfloorclip = ds->sprbottomclip - ds->x1;
const short *mceilingclip = ds->sprtopclip - ds->x1;
float MaskedScaleY = ds->texcoords.yscale;
// find positioning
double texheight = tex->GetScaledHeightDouble();
double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid));
if (texheightscale != 1)
{
texheight = texheight / texheightscale;
}
double texturemid;
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
}
else
{
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
}
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
if (!wrap)
{ // Texture does not wrap vertically.
double textop;
float MaskedScaleY = ds->texcoords.yscale;
// find positioning
double texheight = tex->GetScaledHeightDouble();
double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid));
if (texheightscale != 1)
{
texheight = texheight / texheightscale;
}
double texturemid;
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
}
else
{
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
}
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
bool sprflipvert = false;
if (MaskedScaleY < 0)
@ -322,19 +322,6 @@ namespace swrenderer
}
else
{ // Texture does wrap vertically.
if (tex->useWorldPanning(curline->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.
texturemid = (texturemid - Thread->Viewport->viewpoint.Pos.Z + rowoffset) * MaskedScaleY;
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
texturemid = (texturemid - Thread->Viewport->viewpoint.Pos.Z) * MaskedScaleY + rowoffset;
}
WallC.sz1 = ds->WallC.sz1;
WallC.sz2 = ds->WallC.sz2;
WallC.sx1 = ds->WallC.sx1;
@ -373,11 +360,6 @@ namespace swrenderer
mfloorclip = walllower.ScreenY;
}
ProjectedWallTexcoords texcoords = ds->texcoords;
texcoords.texturemid = texturemid;
FSoftwareTexture *rw_pic = tex;
double top, bot;
GetMaskedWallTopBottom(ds, top, bot);
@ -385,7 +367,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, texcoords, top, bot, true, additive, alpha, mLight, nullptr);
renderWallpart.Render(frontsector, curline, WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
}
return false;

View file

@ -38,6 +38,7 @@ namespace swrenderer
private:
bool RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible);
void RenderWrapWall(DrawSegment* ds, int x1, int x2, FSoftwareTexture* tex);
void ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic);
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2);