diff --git a/src/rendering/swrenderer/line/r_line.cpp b/src/rendering/swrenderer/line/r_line.cpp index 04d43b3bd..4a9e0b48e 100644 --- a/src/rendering/swrenderer/line/r_line.cpp +++ b/src/rendering/swrenderer/line/r_line.cpp @@ -418,10 +418,6 @@ namespace swrenderer (mFloorClipped != ProjectedWallCull::OutsideAbove || !sidedef->GetTexture(side_t::bottom).isValid()) && (WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z)) { - float *swal; - fixed_t *lwal; - int i; - maskedtexture = true; // 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)); 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()) draw_segment->SetHas3DFloorMidTexture(); - draw_segment->maskedtexturecol = Thread->FrameMemory->AllocMemory(stop - start); - draw_segment->swall = Thread->FrameMemory->AllocMemory(stop - start); - - lwal = draw_segment->maskedtexturecol; - swal = draw_segment->swall; 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); @@ -449,40 +441,13 @@ namespace swrenderer xoffset = xs_RoundToInt(xoffset * lwallscale); } - for (i = start; i < stop; i++) - { - *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->texcoords.Set(Thread, walltexcoords, start, stop, xoffset, yscale); } draw_segment->light = mLight.GetLightPos(start); draw_segment->lightstep = mLight.GetLightStep(); - if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) + if (draw_segment->bFogBoundary || is_translucent) { Thread->DrawSegments->PushTranslucent(draw_segment); } @@ -1118,7 +1083,7 @@ namespace swrenderer double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV; 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; } fixed_t offset; @@ -1136,7 +1101,7 @@ namespace swrenderer } 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) @@ -1149,7 +1114,7 @@ namespace swrenderer double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV; 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; } fixed_t offset; @@ -1167,7 +1132,7 @@ namespace swrenderer } 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) @@ -1181,7 +1146,7 @@ namespace swrenderer double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV; 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; } fixed_t offset; @@ -1199,7 +1164,7 @@ namespace swrenderer } 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() diff --git a/src/rendering/swrenderer/line/r_renderdrawsegment.cpp b/src/rendering/swrenderer/line/r_renderdrawsegment.cpp index 17d48427a..0f6932845 100644 --- a/src/rendering/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/rendering/swrenderer/line/r_renderdrawsegment.cpp @@ -115,7 +115,7 @@ namespace swrenderer RenderFogBoundary renderfog; renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight); - if (ds->maskedtexturecol == nullptr) + if (!ds->texcoords) renderwall = false; } else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible) @@ -156,11 +156,7 @@ namespace swrenderer const short *mfloorclip = ds->sprbottomclip - ds->x1; const short *mceilingclip = ds->sprtopclip - ds->x1; - float *MaskedSWall = ds->swall - ds->x1; - 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; + float MaskedScaleY = ds->texcoords.yscale; // find positioning double texheight = tex->GetScaledHeightDouble(); @@ -311,19 +307,12 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { if (needslight) + { columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get()); + lightpos += mLight.GetLightStep(); + } - fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY); - 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; + columndrawerargs.DrawMaskedColumn(Thread, x, tex, ds->texcoords, texturemid, MaskedScaleY, sprflipvert, mfloorclip, mceilingclip, renderstyle); } } } @@ -390,7 +379,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, 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; @@ -412,9 +401,6 @@ namespace swrenderer const short *mfloorclip = ds->sprbottomclip - 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 side_t *scaledside; side_t::ETexpart scaledpart; @@ -478,13 +464,13 @@ namespace swrenderer } 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; GetMaskedWallTopBottom(ds, top, bot); 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); } diff --git a/src/rendering/swrenderer/line/r_walldraw.cpp b/src/rendering/swrenderer/line/r_walldraw.cpp index 7ca3b6ac4..6dcc56b8f 100644 --- a/src/rendering/swrenderer/line/r_walldraw.cpp +++ b/src/rendering/swrenderer/line/r_walldraw.cpp @@ -54,7 +54,7 @@ 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) 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; const short *up; @@ -445,7 +445,7 @@ namespace swrenderer 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(); 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; 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->x2 = x2; @@ -550,11 +550,39 @@ namespace swrenderer 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 { - 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); } } diff --git a/src/rendering/swrenderer/line/r_walldraw.h b/src/rendering/swrenderer/line/r_walldraw.h index bff80f8f4..d68741233 100644 --- a/src/rendering/swrenderer/line/r_walldraw.h +++ b/src/rendering/swrenderer/line/r_walldraw.h @@ -55,8 +55,7 @@ namespace swrenderer const short *walltop, const short *wallbottom, double texturemid, - float *swall, - fixed_t *lwall, + const ProjectedWallTexcoords &texcoords, double yscale, double top, double bottom, @@ -67,13 +66,34 @@ namespace swrenderer const ProjectedWallLight &light, 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; private: - void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, double top, double bot); - void ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); - void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); - void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); + 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, const float *swal, const 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, const float *swal, const fixed_t *lwal); void SetLights(WallDrawerArgs &drawerargs, int x, int y1); int x1 = 0; diff --git a/src/rendering/swrenderer/line/r_wallsetup.cpp b/src/rendering/swrenderer/line/r_wallsetup.cpp index f1b2f2518..0a053f466 100644 --- a/src/rendering/swrenderer/line/r_wallsetup.cpp +++ b/src/rendering/swrenderer/line/r_wallsetup.cpp @@ -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 invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX); @@ -206,39 +206,45 @@ namespace swrenderer 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); - float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX); - float uGradient = WallT.UoverZstep; - float zGradient = WallT.InvZstep; - float xrepeat = (float)fabs(walxrepeat); + UPos = thread->FrameMemory->AllocMemory(x2 - x1) - x1; + VStep = thread->FrameMemory->AllocMemory(x2 - x1) - x1; - if (walxrepeat < 0.0f) + for (int i = x1; i < x2; i++) { - for (int x = x1; x < x2; x++) - { - float u = uOverZ / invZ * xrepeat - xrepeat; + UPos[i] = texcoords.UPos[i] + xoffset; + VStep[i] = texcoords.VStep[i]; + } - UPos[x] = (fixed_t)(u * FRACUNIT); + double istart = VStep[x1] * yscale; + double iend = VStep[x2 - 1] * yscale; - uOverZ += uGradient; - invZ += zGradient; - } + istart = 1 / istart; + iend = 1 / iend; + + this->yscale = (float)yscale; + iscale = (float)istart; + if (x2 - x1 > 1) + { + iscalestep = float((iend - istart) / (x2 - x1 - 1)); } else { - for (int x = x1; x < x2; x++) - { - float u = uOverZ / invZ * xrepeat; - - UPos[x] = (fixed_t)(u * FRACUNIT); - - uOverZ += uGradient; - invZ += zGradient; - } + iscalestep = 0; } } diff --git a/src/rendering/swrenderer/line/r_wallsetup.h b/src/rendering/swrenderer/line/r_wallsetup.h index 46bee0def..d956fc081 100644 --- a/src/rendering/swrenderer/line/r_wallsetup.h +++ b/src/rendering/swrenderer/line/r_wallsetup.h @@ -50,11 +50,33 @@ namespace swrenderer class ProjectedWallTexcoords { public: + void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx = false); + + private: float VStep[MAXWIDTH]; // swall fixed_t UPos[MAXWIDTH]; // lwall - void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); - void ProjectPos(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT); + friend class DrawSegmentWallTexcoords; + 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 diff --git a/src/rendering/swrenderer/scene/r_portal.cpp b/src/rendering/swrenderer/scene/r_portal.cpp index c7fd72c9d..279e261f8 100644 --- a/src/rendering/swrenderer/scene/r_portal.cpp +++ b/src/rendering/swrenderer/scene/r_portal.cpp @@ -214,8 +214,6 @@ namespace swrenderer draw_segment->silhouette = SIL_BOTH; draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory(pl->right - pl->left); draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory(pl->right - pl->left); - draw_segment->maskedtexturecol = nullptr; - draw_segment->swall = nullptr; draw_segment->bFogBoundary = false; draw_segment->curline = nullptr; memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short)); diff --git a/src/rendering/swrenderer/scene/r_translucent_pass.cpp b/src/rendering/swrenderer/scene/r_translucent_pass.cpp index 4738af57b..16338c0d4 100644 --- a/src/rendering/swrenderer/scene/r_translucent_pass.cpp +++ b/src/rendering/swrenderer/scene/r_translucent_pass.cpp @@ -156,7 +156,7 @@ namespace swrenderer // [ZZ] the same as above if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; - if (ds->maskedtexturecol || ds->bFogBoundary) + if (ds->texcoords || ds->bFogBoundary) { RenderDrawSegment renderer(Thread); renderer.Render(ds, ds->x1, ds->x2, clip3DFloor); diff --git a/src/rendering/swrenderer/segments/r_drawsegment.h b/src/rendering/swrenderer/segments/r_drawsegment.h index 85e34768c..938c56c6c 100644 --- a/src/rendering/swrenderer/segments/r_drawsegment.h +++ b/src/rendering/swrenderer/segments/r_drawsegment.h @@ -29,18 +29,16 @@ namespace swrenderer { seg_t *curline; float light, lightstep; - float iscale, iscalestep; short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg FWallCoords WallC; - float yscale; uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both bool bFogBoundary = false; + DrawSegmentWallTexcoords texcoords; + // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. short *sprtopclip = nullptr; short *sprbottomclip = nullptr; - fixed_t *maskedtexturecol = nullptr; - float *swall = nullptr; short *bkup = nullptr; // sprtopclip backup, for mid and fake textures bool sprclipped = false; // True if draw segment was used for clipping sprites diff --git a/src/rendering/swrenderer/things/r_decal.cpp b/src/rendering/swrenderer/things/r_decal.cpp index af026276b..4074ff1b5 100644 --- a/src/rendering/swrenderer/things/r_decal.cpp +++ b/src/rendering/swrenderer/things/r_decal.cpp @@ -242,18 +242,7 @@ namespace swrenderer } ProjectedWallTexcoords walltexcoords; - walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT); - - if (flipx) - { - int i; - int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1; - - for (i = x1; i < x2; i++) - { - walltexcoords.UPos[i] = right - walltexcoords.UPos[i]; - } - } + walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT, flipx); // Prepare lighting usecolormap = light.GetBaseColormap(); @@ -302,7 +291,7 @@ namespace swrenderer { // calculate lighting 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(); x++; } @@ -315,19 +304,4 @@ namespace swrenderer mfloorclip = wallbottom; } 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); - } } diff --git a/src/rendering/swrenderer/things/r_decal.h b/src/rendering/swrenderer/things/r_decal.h index 69a97f6d0..e6f647501 100644 --- a/src/rendering/swrenderer/things/r_decal.h +++ b/src/rendering/swrenderer/things/r_decal.h @@ -16,6 +16,5 @@ namespace swrenderer 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 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); }; } diff --git a/src/rendering/swrenderer/things/r_visiblesprite.cpp b/src/rendering/swrenderer/things/r_visiblesprite.cpp index a2dd22b13..e2a328b58 100644 --- a/src/rendering/swrenderer/things/r_visiblesprite.cpp +++ b/src/rendering/swrenderer/things/r_visiblesprite.cpp @@ -405,9 +405,7 @@ namespace swrenderer DrawSegment *ds = segmentlist->Segment(index); // determine if the drawseg obscures the sprite - if (ds->x1 >= x2 || ds->x2 <= x1 || - (!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == nullptr && - !ds->bFogBoundary)) + if (ds->x1 >= x2 || ds->x2 <= x1 || (!(ds->silhouette & SIL_BOTH) && !ds->texcoords && !ds->bFogBoundary)) { // does not cover sprite continue; diff --git a/src/rendering/swrenderer/things/r_wallsprite.cpp b/src/rendering/swrenderer/things/r_wallsprite.cpp index 2a9eb7311..6383bf1ee 100644 --- a/src/rendering/swrenderer/things/r_wallsprite.cpp +++ b/src/rendering/swrenderer/things/r_wallsprite.cpp @@ -175,19 +175,10 @@ namespace swrenderer WallT.InitFromWallCoords(thread, &spr->wallc); 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; 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 @@ -238,24 +229,9 @@ namespace swrenderer drawerargs.SetLight(light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get()); } 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; 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); - } } diff --git a/src/rendering/swrenderer/things/r_wallsprite.h b/src/rendering/swrenderer/things/r_wallsprite.h index bcd0a1389..2851ec2b5 100644 --- a/src/rendering/swrenderer/things/r_wallsprite.h +++ b/src/rendering/swrenderer/things/r_wallsprite.h @@ -17,8 +17,6 @@ namespace swrenderer void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; 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; uint32_t Translation = 0; uint32_t FillColor = 0; diff --git a/src/rendering/swrenderer/viewport/r_spritedrawer.cpp b/src/rendering/swrenderer/viewport/r_spritedrawer.cpp index dd0c7b1b4..519296ce2 100644 --- a/src/rendering/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/rendering/swrenderer/viewport/r_spritedrawer.cpp @@ -43,6 +43,36 @@ namespace swrenderer 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) { if (x < thread->X1 || x >= thread->X2) diff --git a/src/rendering/swrenderer/viewport/r_spritedrawer.h b/src/rendering/swrenderer/viewport/r_spritedrawer.h index 186618991..7f5733b4f 100644 --- a/src/rendering/swrenderer/viewport/r_spritedrawer.h +++ b/src/rendering/swrenderer/viewport/r_spritedrawer.h @@ -9,6 +9,8 @@ struct FLightNode; namespace swrenderer { class RenderThread; + class ProjectedWallTexcoords; + class DrawSegmentWallTexcoords; class VoxelBlock { @@ -33,6 +35,8 @@ namespace swrenderer void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[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 FillColumn(RenderThread *thread); void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount);