mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Further isolate texture coordinate calculations to r_wallsetup
This commit is contained in:
parent
c64fafc490
commit
62ec165d28
16 changed files with 176 additions and 174 deletions
|
@ -418,10 +418,6 @@ namespace swrenderer
|
||||||
(mFloorClipped != ProjectedWallCull::OutsideAbove || !sidedef->GetTexture(side_t::bottom).isValid()) &&
|
(mFloorClipped != ProjectedWallCull::OutsideAbove || !sidedef->GetTexture(side_t::bottom).isValid()) &&
|
||||||
(WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z))
|
(WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z))
|
||||||
{
|
{
|
||||||
float *swal;
|
|
||||||
fixed_t *lwal;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
maskedtexture = true;
|
maskedtexture = true;
|
||||||
|
|
||||||
// kg3D - backup for mid and fake walls
|
// kg3D - backup for mid and fake walls
|
||||||
|
@ -429,16 +425,12 @@ namespace swrenderer
|
||||||
memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
|
memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
|
||||||
|
|
||||||
draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector);
|
draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector);
|
||||||
if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls())
|
bool is_translucent = sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls();
|
||||||
|
if (is_translucent)
|
||||||
{
|
{
|
||||||
if (sidedef->GetTexture(side_t::mid).isValid())
|
if (sidedef->GetTexture(side_t::mid).isValid())
|
||||||
draw_segment->SetHas3DFloorMidTexture();
|
draw_segment->SetHas3DFloorMidTexture();
|
||||||
|
|
||||||
draw_segment->maskedtexturecol = Thread->FrameMemory->AllocMemory<fixed_t>(stop - start);
|
|
||||||
draw_segment->swall = Thread->FrameMemory->AllocMemory<float>(stop - start);
|
|
||||||
|
|
||||||
lwal = draw_segment->maskedtexturecol;
|
|
||||||
swal = draw_segment->swall;
|
|
||||||
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
|
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
|
||||||
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
|
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
|
||||||
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);
|
||||||
|
@ -449,40 +441,13 @@ namespace swrenderer
|
||||||
xoffset = xs_RoundToInt(xoffset * lwallscale);
|
xoffset = xs_RoundToInt(xoffset * lwallscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = start; i < stop; i++)
|
draw_segment->texcoords.Set(Thread, walltexcoords, start, stop, xoffset, yscale);
|
||||||
{
|
|
||||||
*lwal++ = walltexcoords.UPos[i] + xoffset;
|
|
||||||
*swal++ = walltexcoords.VStep[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
double istart = draw_segment->swall[0] * yscale;
|
|
||||||
double iend = *(swal - 1) * yscale;
|
|
||||||
#if 0
|
|
||||||
///This was for avoiding overflow when using fixed point. It might not be needed anymore.
|
|
||||||
const double mini = 3 / 65536.0;
|
|
||||||
if (istart < mini && istart >= 0) istart = mini;
|
|
||||||
if (istart > -mini && istart < 0) istart = -mini;
|
|
||||||
if (iend < mini && iend >= 0) iend = mini;
|
|
||||||
if (iend > -mini && iend < 0) iend = -mini;
|
|
||||||
#endif
|
|
||||||
istart = 1 / istart;
|
|
||||||
iend = 1 / iend;
|
|
||||||
draw_segment->yscale = (float)yscale;
|
|
||||||
draw_segment->iscale = (float)istart;
|
|
||||||
if (stop - start > 1)
|
|
||||||
{
|
|
||||||
draw_segment->iscalestep = float((iend - istart) / (stop - start - 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
draw_segment->iscalestep = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_segment->light = mLight.GetLightPos(start);
|
draw_segment->light = mLight.GetLightPos(start);
|
||||||
draw_segment->lightstep = mLight.GetLightStep();
|
draw_segment->lightstep = mLight.GetLightStep();
|
||||||
|
|
||||||
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
|
if (draw_segment->bFogBoundary || is_translucent)
|
||||||
{
|
{
|
||||||
Thread->DrawSegments->PushTranslucent(draw_segment);
|
Thread->DrawSegments->PushTranslucent(draw_segment);
|
||||||
}
|
}
|
||||||
|
@ -1118,7 +1083,7 @@ namespace swrenderer
|
||||||
double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV;
|
double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV;
|
||||||
if (xscale != lwallscale)
|
if (xscale != lwallscale)
|
||||||
{
|
{
|
||||||
walltexcoords.ProjectPos(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;
|
lwallscale = xscale;
|
||||||
}
|
}
|
||||||
fixed_t offset;
|
fixed_t offset;
|
||||||
|
@ -1136,7 +1101,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderWallPart renderWallpart(Thread);
|
RenderWallPart renderWallpart(Thread);
|
||||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, 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, mTopPart.TextureMid, walltexcoords, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, offset, mLight, GetLightList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
|
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
|
||||||
|
@ -1149,7 +1114,7 @@ namespace swrenderer
|
||||||
double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV;
|
double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV;
|
||||||
if (xscale != lwallscale)
|
if (xscale != lwallscale)
|
||||||
{
|
{
|
||||||
walltexcoords.ProjectPos(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;
|
lwallscale = xscale;
|
||||||
}
|
}
|
||||||
fixed_t offset;
|
fixed_t offset;
|
||||||
|
@ -1167,7 +1132,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderWallPart renderWallpart(Thread);
|
RenderWallPart renderWallpart(Thread);
|
||||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, 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, mMiddlePart.TextureMid, walltexcoords, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWRenderLine::RenderBottomTexture(int x1, int x2)
|
void SWRenderLine::RenderBottomTexture(int x1, int x2)
|
||||||
|
@ -1181,7 +1146,7 @@ namespace swrenderer
|
||||||
double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV;
|
double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV;
|
||||||
if (xscale != lwallscale)
|
if (xscale != lwallscale)
|
||||||
{
|
{
|
||||||
walltexcoords.ProjectPos(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;
|
lwallscale = xscale;
|
||||||
}
|
}
|
||||||
fixed_t offset;
|
fixed_t offset;
|
||||||
|
@ -1199,7 +1164,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderWallPart renderWallpart(Thread);
|
RenderWallPart renderWallpart(Thread);
|
||||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, 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, mBottomPart.TextureMid, walltexcoords, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, offset, mLight, GetLightList());
|
||||||
}
|
}
|
||||||
|
|
||||||
FLightNode *SWRenderLine::GetLightList()
|
FLightNode *SWRenderLine::GetLightList()
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace swrenderer
|
||||||
RenderFogBoundary renderfog;
|
RenderFogBoundary renderfog;
|
||||||
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight);
|
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight);
|
||||||
|
|
||||||
if (ds->maskedtexturecol == nullptr)
|
if (!ds->texcoords)
|
||||||
renderwall = false;
|
renderwall = false;
|
||||||
}
|
}
|
||||||
else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible)
|
else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible)
|
||||||
|
@ -156,11 +156,7 @@ namespace swrenderer
|
||||||
const short *mfloorclip = ds->sprbottomclip - ds->x1;
|
const short *mfloorclip = ds->sprbottomclip - ds->x1;
|
||||||
const short *mceilingclip = ds->sprtopclip - ds->x1;
|
const short *mceilingclip = ds->sprtopclip - ds->x1;
|
||||||
|
|
||||||
float *MaskedSWall = ds->swall - ds->x1;
|
float MaskedScaleY = ds->texcoords.yscale;
|
||||||
float MaskedScaleY = ds->yscale;
|
|
||||||
fixed_t *maskedtexturecol = ds->maskedtexturecol - ds->x1;
|
|
||||||
double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
|
|
||||||
float rw_scalestep = ds->iscalestep;
|
|
||||||
|
|
||||||
// find positioning
|
// find positioning
|
||||||
double texheight = tex->GetScaledHeightDouble();
|
double texheight = tex->GetScaledHeightDouble();
|
||||||
|
@ -311,19 +307,12 @@ namespace swrenderer
|
||||||
for (int x = x1; x < x2; ++x)
|
for (int x = x1; x < x2; ++x)
|
||||||
{
|
{
|
||||||
if (needslight)
|
if (needslight)
|
||||||
|
{
|
||||||
columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get());
|
columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get());
|
||||||
|
lightpos += mLight.GetLightStep();
|
||||||
|
}
|
||||||
|
|
||||||
fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY);
|
columndrawerargs.DrawMaskedColumn(Thread, x, tex, ds->texcoords, texturemid, MaskedScaleY, sprflipvert, mfloorclip, mceilingclip, renderstyle);
|
||||||
double sprtopscreen;
|
|
||||||
if (sprflipvert)
|
|
||||||
sprtopscreen = viewport->CenterY + texturemid * spryscale;
|
|
||||||
else
|
|
||||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
|
||||||
|
|
||||||
columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, renderstyle);
|
|
||||||
|
|
||||||
lightpos += mLight.GetLightStep();
|
|
||||||
spryscale += rw_scalestep;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +379,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, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, additive, alpha, rw_offset, mLight, nullptr);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -412,9 +401,6 @@ namespace swrenderer
|
||||||
const short *mfloorclip = ds->sprbottomclip - ds->x1;
|
const short *mfloorclip = ds->sprbottomclip - ds->x1;
|
||||||
const short *mceilingclip = ds->sprtopclip - ds->x1;
|
const short *mceilingclip = ds->sprtopclip - ds->x1;
|
||||||
|
|
||||||
//double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
|
|
||||||
float *MaskedSWall = ds->swall - ds->x1;
|
|
||||||
|
|
||||||
// find positioning
|
// find positioning
|
||||||
side_t *scaledside;
|
side_t *scaledside;
|
||||||
side_t::ETexpart scaledpart;
|
side_t::ETexpart scaledpart;
|
||||||
|
@ -478,13 +464,13 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectedWallTexcoords walltexcoords;
|
ProjectedWallTexcoords walltexcoords;
|
||||||
walltexcoords.ProjectPos(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);
|
||||||
|
|
||||||
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, MaskedSWall, walltexcoords.UPos, 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, texturemid, walltexcoords, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, rw_offset, 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
|
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
|
||||||
{
|
{
|
||||||
if (rw_pic == nullptr)
|
if (rw_pic == nullptr)
|
||||||
return;
|
return;
|
||||||
|
@ -410,7 +410,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
|
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
|
||||||
{
|
{
|
||||||
ProjectedWallLine most1, most2, most3;
|
ProjectedWallLine most1, most2, most3;
|
||||||
const short *up;
|
const short *up;
|
||||||
|
@ -445,7 +445,7 @@ namespace swrenderer
|
||||||
ProcessNormalWall(up, dwal, texturemid, swal, lwal);
|
ProcessNormalWall(up, dwal, texturemid, swal, lwal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
|
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
|
||||||
{
|
{
|
||||||
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()))
|
||||||
|
@ -469,7 +469,7 @@ namespace swrenderer
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, double top, double bot)
|
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal, double top, double bot)
|
||||||
{
|
{
|
||||||
ProjectedWallLine most1, most2, most3;
|
ProjectedWallLine most1, most2, most3;
|
||||||
double texheight = rw_pic->GetHeight();
|
double texheight = rw_pic->GetHeight();
|
||||||
|
@ -530,7 +530,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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, float *swall, fixed_t *lwall, 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, 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)
|
||||||
{
|
{
|
||||||
this->x1 = x1;
|
this->x1 = x1;
|
||||||
this->x2 = x2;
|
this->x2 = x2;
|
||||||
|
@ -550,11 +550,39 @@ namespace swrenderer
|
||||||
|
|
||||||
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits())
|
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits())
|
||||||
{
|
{
|
||||||
ProcessWallNP2(walltop, wallbottom, texturemid, swall, lwall, top, bottom);
|
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos, top, bottom);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ProcessWall(walltop, wallbottom, texturemid, swall, lwall);
|
ProcessWall(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 DrawSegmentWallTexcoords& texcoords, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, fixed_t xoffset, const ProjectedWallLight& light, FLightNode* light_list)
|
||||||
|
{
|
||||||
|
this->x1 = x1;
|
||||||
|
this->x2 = x2;
|
||||||
|
this->frontsector = frontsector;
|
||||||
|
this->curline = curline;
|
||||||
|
this->WallC = WallC;
|
||||||
|
this->yrepeat = yscale;
|
||||||
|
this->mLight = light;
|
||||||
|
this->xoffset = xoffset;
|
||||||
|
this->light_list = light_list;
|
||||||
|
this->rw_pic = pic;
|
||||||
|
this->mask = mask;
|
||||||
|
this->additive = additive;
|
||||||
|
this->alpha = alpha;
|
||||||
|
|
||||||
|
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||||
|
|
||||||
|
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits())
|
||||||
|
{
|
||||||
|
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos, top, bottom);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ProcessWall(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,7 @@ namespace swrenderer
|
||||||
const short *walltop,
|
const short *walltop,
|
||||||
const short *wallbottom,
|
const short *wallbottom,
|
||||||
double texturemid,
|
double texturemid,
|
||||||
float *swall,
|
const ProjectedWallTexcoords &texcoords,
|
||||||
fixed_t *lwall,
|
|
||||||
double yscale,
|
double yscale,
|
||||||
double top,
|
double top,
|
||||||
double bottom,
|
double bottom,
|
||||||
|
@ -67,13 +66,34 @@ namespace swrenderer
|
||||||
const ProjectedWallLight &light,
|
const ProjectedWallLight &light,
|
||||||
FLightNode *light_list);
|
FLightNode *light_list);
|
||||||
|
|
||||||
|
void Render(
|
||||||
|
sector_t* frontsector,
|
||||||
|
seg_t* curline,
|
||||||
|
const FWallCoords& WallC,
|
||||||
|
FSoftwareTexture* rw_pic,
|
||||||
|
int x1,
|
||||||
|
int x2,
|
||||||
|
const short* walltop,
|
||||||
|
const short* wallbottom,
|
||||||
|
double texturemid,
|
||||||
|
const DrawSegmentWallTexcoords& texcoords,
|
||||||
|
double yscale,
|
||||||
|
double top,
|
||||||
|
double bottom,
|
||||||
|
bool mask,
|
||||||
|
bool additive,
|
||||||
|
fixed_t alpha,
|
||||||
|
fixed_t xoffset,
|
||||||
|
const ProjectedWallLight& light,
|
||||||
|
FLightNode* light_list);
|
||||||
|
|
||||||
RenderThread *Thread = nullptr;
|
RenderThread *Thread = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, double top, double bot);
|
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal, double top, double bot);
|
||||||
void ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
|
void ProcessWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
|
||||||
void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
|
void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
|
||||||
void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
|
void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
|
||||||
void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
|
void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
|
||||||
|
|
||||||
int x1 = 0;
|
int x1 = 0;
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace swrenderer
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void ProjectedWallTexcoords::Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT)
|
void ProjectedWallTexcoords::Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx)
|
||||||
{
|
{
|
||||||
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
||||||
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
||||||
|
@ -206,39 +206,45 @@ namespace swrenderer
|
||||||
invZ += zGradient;
|
invZ += zGradient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flipx)
|
||||||
|
{
|
||||||
|
int right = (int)walxrepeat - 1;
|
||||||
|
for (int i = x1; i < x2; i++)
|
||||||
|
{
|
||||||
|
UPos[i] = right - UPos[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectedWallTexcoords::ProjectPos(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT)
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DrawSegmentWallTexcoords::Set(RenderThread* thread, const ProjectedWallTexcoords& texcoords, int x1, int x2, fixed_t xoffset, double yscale)
|
||||||
{
|
{
|
||||||
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
UPos = thread->FrameMemory->AllocMemory<fixed_t>(x2 - x1) - x1;
|
||||||
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX);
|
VStep = thread->FrameMemory->AllocMemory<float>(x2 - x1) - x1;
|
||||||
float uGradient = WallT.UoverZstep;
|
|
||||||
float zGradient = WallT.InvZstep;
|
|
||||||
float xrepeat = (float)fabs(walxrepeat);
|
|
||||||
|
|
||||||
if (walxrepeat < 0.0f)
|
for (int i = x1; i < x2; i++)
|
||||||
{
|
{
|
||||||
for (int x = x1; x < x2; x++)
|
UPos[i] = texcoords.UPos[i] + xoffset;
|
||||||
{
|
VStep[i] = texcoords.VStep[i];
|
||||||
float u = uOverZ / invZ * xrepeat - xrepeat;
|
}
|
||||||
|
|
||||||
UPos[x] = (fixed_t)(u * FRACUNIT);
|
double istart = VStep[x1] * yscale;
|
||||||
|
double iend = VStep[x2 - 1] * yscale;
|
||||||
|
|
||||||
uOverZ += uGradient;
|
istart = 1 / istart;
|
||||||
invZ += zGradient;
|
iend = 1 / iend;
|
||||||
}
|
|
||||||
|
this->yscale = (float)yscale;
|
||||||
|
iscale = (float)istart;
|
||||||
|
if (x2 - x1 > 1)
|
||||||
|
{
|
||||||
|
iscalestep = float((iend - istart) / (x2 - x1 - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int x = x1; x < x2; x++)
|
iscalestep = 0;
|
||||||
{
|
|
||||||
float u = uOverZ / invZ * xrepeat;
|
|
||||||
|
|
||||||
UPos[x] = (fixed_t)(u * FRACUNIT);
|
|
||||||
|
|
||||||
uOverZ += uGradient;
|
|
||||||
invZ += zGradient;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,33 @@ namespace swrenderer
|
||||||
class ProjectedWallTexcoords
|
class ProjectedWallTexcoords
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx = false);
|
||||||
|
|
||||||
|
private:
|
||||||
float VStep[MAXWIDTH]; // swall
|
float VStep[MAXWIDTH]; // swall
|
||||||
fixed_t UPos[MAXWIDTH]; // lwall
|
fixed_t UPos[MAXWIDTH]; // lwall
|
||||||
|
|
||||||
void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT);
|
friend class DrawSegmentWallTexcoords;
|
||||||
void ProjectPos(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT);
|
friend class RenderWallPart;
|
||||||
|
friend class SpriteDrawerArgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawSegmentWallTexcoords
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Set(RenderThread *thread, const ProjectedWallTexcoords& texcoords, int x1, int x2, fixed_t xoffset, double yscale);
|
||||||
|
|
||||||
|
float yscale;
|
||||||
|
float iscale, iscalestep;
|
||||||
|
|
||||||
|
explicit operator bool() const { return UPos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
float* VStep = nullptr; // swall
|
||||||
|
fixed_t* UPos = nullptr; // maskedtexturecol
|
||||||
|
|
||||||
|
friend class RenderWallPart;
|
||||||
|
friend class SpriteDrawerArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProjectedWallLight
|
class ProjectedWallLight
|
||||||
|
|
|
@ -214,8 +214,6 @@ namespace swrenderer
|
||||||
draw_segment->silhouette = SIL_BOTH;
|
draw_segment->silhouette = SIL_BOTH;
|
||||||
draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory<short>(pl->right - pl->left);
|
draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory<short>(pl->right - pl->left);
|
||||||
draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory<short>(pl->right - pl->left);
|
draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory<short>(pl->right - pl->left);
|
||||||
draw_segment->maskedtexturecol = nullptr;
|
|
||||||
draw_segment->swall = nullptr;
|
|
||||||
draw_segment->bFogBoundary = false;
|
draw_segment->bFogBoundary = false;
|
||||||
draw_segment->curline = nullptr;
|
draw_segment->curline = nullptr;
|
||||||
memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace swrenderer
|
||||||
// [ZZ] the same as above
|
// [ZZ] the same as above
|
||||||
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||||
continue;
|
continue;
|
||||||
if (ds->maskedtexturecol || ds->bFogBoundary)
|
if (ds->texcoords || ds->bFogBoundary)
|
||||||
{
|
{
|
||||||
RenderDrawSegment renderer(Thread);
|
RenderDrawSegment renderer(Thread);
|
||||||
renderer.Render(ds, ds->x1, ds->x2, clip3DFloor);
|
renderer.Render(ds, ds->x1, ds->x2, clip3DFloor);
|
||||||
|
|
|
@ -29,18 +29,16 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
seg_t *curline;
|
seg_t *curline;
|
||||||
float light, lightstep;
|
float light, lightstep;
|
||||||
float iscale, iscalestep;
|
|
||||||
short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg
|
short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg
|
||||||
FWallCoords WallC;
|
FWallCoords WallC;
|
||||||
float yscale;
|
|
||||||
uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both
|
uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both
|
||||||
bool bFogBoundary = false;
|
bool bFogBoundary = false;
|
||||||
|
|
||||||
|
DrawSegmentWallTexcoords texcoords;
|
||||||
|
|
||||||
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
|
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
|
||||||
short *sprtopclip = nullptr;
|
short *sprtopclip = nullptr;
|
||||||
short *sprbottomclip = nullptr;
|
short *sprbottomclip = nullptr;
|
||||||
fixed_t *maskedtexturecol = nullptr;
|
|
||||||
float *swall = nullptr;
|
|
||||||
short *bkup = nullptr; // sprtopclip backup, for mid and fake textures
|
short *bkup = nullptr; // sprtopclip backup, for mid and fake textures
|
||||||
bool sprclipped = false; // True if draw segment was used for clipping sprites
|
bool sprclipped = false; // True if draw segment was used for clipping sprites
|
||||||
|
|
||||||
|
|
|
@ -242,18 +242,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectedWallTexcoords walltexcoords;
|
ProjectedWallTexcoords walltexcoords;
|
||||||
walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT);
|
walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT, flipx);
|
||||||
|
|
||||||
if (flipx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1;
|
|
||||||
|
|
||||||
for (i = x1; i < x2; i++)
|
|
||||||
{
|
|
||||||
walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare lighting
|
// Prepare lighting
|
||||||
usecolormap = light.GetBaseColormap();
|
usecolormap = light.GetBaseColormap();
|
||||||
|
@ -302,7 +291,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());
|
||||||
}
|
}
|
||||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
|
drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
|
||||||
lightpos += light.GetLightStep();
|
lightpos += light.GetLightStep();
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
@ -315,19 +304,4 @@ namespace swrenderer
|
||||||
mfloorclip = wallbottom;
|
mfloorclip = wallbottom;
|
||||||
} while (needrepeat--);
|
} while (needrepeat--);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style)
|
|
||||||
{
|
|
||||||
auto viewport = thread->Viewport.get();
|
|
||||||
|
|
||||||
float iscale = walltexcoords.VStep[x] * maskedScaleY;
|
|
||||||
double spryscale = 1 / iscale;
|
|
||||||
double sprtopscreen;
|
|
||||||
if (sprflipvert)
|
|
||||||
sprtopscreen = viewport->CenterY + texturemid * spryscale;
|
|
||||||
else
|
|
||||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
|
||||||
|
|
||||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,5 @@ namespace swrenderer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass);
|
static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, seg_t *curline, const ProjectedWallLight &light, const short *walltop, const short *wallbottom, bool drawsegPass);
|
||||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,9 +405,7 @@ namespace swrenderer
|
||||||
DrawSegment *ds = segmentlist->Segment(index);
|
DrawSegment *ds = segmentlist->Segment(index);
|
||||||
|
|
||||||
// determine if the drawseg obscures the sprite
|
// determine if the drawseg obscures the sprite
|
||||||
if (ds->x1 >= x2 || ds->x2 <= x1 ||
|
if (ds->x1 >= x2 || ds->x2 <= x1 || (!(ds->silhouette & SIL_BOTH) && !ds->texcoords && !ds->bFogBoundary))
|
||||||
(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == nullptr &&
|
|
||||||
!ds->bFogBoundary))
|
|
||||||
{
|
{
|
||||||
// does not cover sprite
|
// does not cover sprite
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -175,19 +175,10 @@ namespace swrenderer
|
||||||
WallT.InitFromWallCoords(thread, &spr->wallc);
|
WallT.InitFromWallCoords(thread, &spr->wallc);
|
||||||
|
|
||||||
ProjectedWallTexcoords walltexcoords;
|
ProjectedWallTexcoords walltexcoords;
|
||||||
walltexcoords.Project(thread->Viewport.get(), spr->pic->GetWidth() << FRACBITS, x1, x2, WallT);
|
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;
|
||||||
if (spr->renderflags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
|
|
||||||
|
|
||||||
for (int i = x1; i < x2; i++)
|
|
||||||
{
|
|
||||||
walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare lighting
|
// Prepare lighting
|
||||||
|
|
||||||
|
@ -238,24 +229,9 @@ 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))
|
||||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
|
drawerargs.DrawMaskedColumn(thread, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
|
||||||
light += lightstep;
|
light += lightstep;
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style)
|
|
||||||
{
|
|
||||||
auto viewport = thread->Viewport.get();
|
|
||||||
|
|
||||||
float iscale = walltexcoords.VStep[x] * maskedScaleY;
|
|
||||||
double spryscale = 1 / iscale;
|
|
||||||
double sprtopscreen;
|
|
||||||
if (sprflipvert)
|
|
||||||
sprtopscreen = viewport->CenterY + texturemid * spryscale;
|
|
||||||
else
|
|
||||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
|
||||||
|
|
||||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ namespace swrenderer
|
||||||
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
|
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style);
|
|
||||||
|
|
||||||
FWallCoords wallc;
|
FWallCoords wallc;
|
||||||
uint32_t Translation = 0;
|
uint32_t Translation = 0;
|
||||||
uint32_t FillColor = 0;
|
uint32_t FillColor = 0;
|
||||||
|
|
|
@ -43,6 +43,36 @@ 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)
|
||||||
|
{
|
||||||
|
auto viewport = thread->Viewport.get();
|
||||||
|
|
||||||
|
float iscale = walltexcoords.VStep[x] * maskedScaleY;
|
||||||
|
double spryscale = 1 / iscale;
|
||||||
|
double sprtopscreen;
|
||||||
|
if (sprflipvert)
|
||||||
|
sprtopscreen = viewport->CenterY + texturemid * spryscale;
|
||||||
|
else
|
||||||
|
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
||||||
|
|
||||||
|
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const DrawSegmentWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style)
|
||||||
|
{
|
||||||
|
auto viewport = thread->Viewport.get();
|
||||||
|
|
||||||
|
float iscale = walltexcoords.VStep[x] * maskedScaleY;
|
||||||
|
double spryscale = 1 / iscale;
|
||||||
|
double sprtopscreen;
|
||||||
|
if (sprflipvert)
|
||||||
|
sprtopscreen = viewport->CenterY + texturemid * spryscale;
|
||||||
|
else
|
||||||
|
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
||||||
|
|
||||||
|
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked)
|
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked)
|
||||||
{
|
{
|
||||||
if (x < thread->X1 || x >= thread->X2)
|
if (x < thread->X1 || x >= thread->X2)
|
||||||
|
|
|
@ -9,6 +9,8 @@ struct FLightNode;
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
class RenderThread;
|
class RenderThread;
|
||||||
|
class ProjectedWallTexcoords;
|
||||||
|
class DrawSegmentWallTexcoords;
|
||||||
|
|
||||||
class VoxelBlock
|
class VoxelBlock
|
||||||
{
|
{
|
||||||
|
@ -33,6 +35,8 @@ 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 DrawSegmentWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, 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);
|
||||||
|
|
Loading…
Reference in a new issue