diff --git a/src/rendering/swrenderer/line/r_line.cpp b/src/rendering/swrenderer/line/r_line.cpp index aa4f9a509..f0714c751 100644 --- a/src/rendering/swrenderer/line/r_line.cpp +++ b/src/rendering/swrenderer/line/r_line.cpp @@ -313,27 +313,27 @@ namespace swrenderer if (m3DFloor.type == Fake3DOpaque::Normal) Thread->DrawSegments->Push(draw_segment); - draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq; + draw_segment->drawsegclip.CurrentPortalUniq = renderportal->CurrentPortalUniq; draw_segment->WallC = WallC; draw_segment->tmapvals = WallT; draw_segment->x1 = start; draw_segment->x2 = stop; draw_segment->curline = mLineSegment; - draw_segment->SubsectorDepth = Thread->OpaquePass->GetSubsectorDepth(mSubsector->Index()); + draw_segment->drawsegclip.SubsectorDepth = Thread->OpaquePass->GetSubsectorDepth(mSubsector->Index()); bool markportal = ShouldMarkPortal(); if (markportal) { - draw_segment->silhouette = SIL_BOTH; + draw_segment->drawsegclip.silhouette = SIL_BOTH; } else if (mBackSector == NULL) { - draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); - draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); - fillshort(draw_segment->sprtopclip, stop - start, viewheight); - memset(draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short)); - draw_segment->silhouette = SIL_BOTH; + draw_segment->drawsegclip.sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); + draw_segment->drawsegclip.sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); + fillshort(draw_segment->drawsegclip.sprtopclip, stop - start, viewheight); + memset(draw_segment->drawsegclip.sprbottomclip, -1, (stop - start) * sizeof(short)); + draw_segment->drawsegclip.silhouette = SIL_BOTH; } else { @@ -341,13 +341,13 @@ namespace swrenderer if (mFrontFloorZ1 > mBackFloorZ1 || mFrontFloorZ2 > mBackFloorZ2 || mBackSector->floorplane.PointOnSide(Thread->Viewport->viewpoint.Pos) < 0) { - draw_segment->silhouette = SIL_BOTTOM; + draw_segment->drawsegclip.silhouette = SIL_BOTTOM; } if (mFrontCeilingZ1 < mBackCeilingZ1 || mFrontCeilingZ2 < mBackCeilingZ2 || mBackSector->ceilingplane.PointOnSide(Thread->Viewport->viewpoint.Pos) < 0) { - draw_segment->silhouette |= SIL_TOP; + draw_segment->drawsegclip.silhouette |= SIL_TOP; } // killough 1/17/98: this test is required if the fix @@ -361,15 +361,15 @@ namespace swrenderer { if (mDoorClosed || (mBackCeilingZ1 <= mFrontFloorZ1 && mBackCeilingZ2 <= mFrontFloorZ2)) { - draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); - memset(draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short)); - draw_segment->silhouette |= SIL_BOTTOM; + draw_segment->drawsegclip.sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); + memset(draw_segment->drawsegclip.sprbottomclip, -1, (stop - start) * sizeof(short)); + draw_segment->drawsegclip.silhouette |= SIL_BOTTOM; } if (mDoorClosed || (mBackFloorZ1 >= mFrontCeilingZ1 && mBackFloorZ2 >= mFrontCeilingZ2)) { // killough 1/17/98, 2/8/98 - draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); - fillshort(draw_segment->sprtopclip, stop - start, viewheight); - draw_segment->silhouette |= SIL_TOP; + draw_segment->drawsegclip.sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); + fillshort(draw_segment->drawsegclip.sprtopclip, stop - start, viewheight); + draw_segment->drawsegclip.silhouette |= SIL_TOP; } } @@ -407,10 +407,10 @@ namespace swrenderer maskedtexture = true; // kg3D - backup for mid and fake walls - draw_segment->bkup = Thread->FrameMemory->AllocMemory(stop - start); - memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start)); + draw_segment->drawsegclip.bkup = Thread->FrameMemory->AllocMemory(stop - start); + memcpy(draw_segment->drawsegclip.bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start)); - draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector); + draw_segment->drawsegclip.bFogBoundary = IsFogBoundary(mFrontSector, mBackSector); if (sidedef->GetTexture(side_t::mid).isValid()) { FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); @@ -425,7 +425,7 @@ namespace swrenderer draw_segment->light = mLight.GetLightPos(start); draw_segment->lightstep = mLight.GetLightStep(); - if (draw_segment->bFogBoundary || draw_segment->texcoords || draw_segment->Has3DFloorWalls()) + if (draw_segment->drawsegclip.bFogBoundary || draw_segment->texcoords || draw_segment->Has3DFloorWalls()) { Thread->DrawSegments->PushTranslucent(draw_segment); } @@ -447,21 +447,21 @@ namespace swrenderer MarkOpaquePassClip(start, stop); // save sprite clipping info - if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr) + if (((draw_segment->drawsegclip.silhouette & SIL_TOP) || maskedtexture) && draw_segment->drawsegclip.sprtopclip == nullptr) { - draw_segment->sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); - memcpy(draw_segment->sprtopclip, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start)); + draw_segment->drawsegclip.sprtopclip = Thread->FrameMemory->AllocMemory(stop - start); + memcpy(draw_segment->drawsegclip.sprtopclip, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start)); } - if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == nullptr) + if (((draw_segment->drawsegclip.silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->drawsegclip.sprbottomclip == nullptr) { - draw_segment->sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); - memcpy(draw_segment->sprbottomclip, &Thread->OpaquePass->floorclip[start], sizeof(short)*(stop - start)); + draw_segment->drawsegclip.sprbottomclip = Thread->FrameMemory->AllocMemory(stop - start); + memcpy(draw_segment->drawsegclip.sprbottomclip, &Thread->OpaquePass->floorclip[start], sizeof(short)*(stop - start)); } if (maskedtexture && mLineSegment->sidedef->GetTexture(side_t::mid).isValid()) { - draw_segment->silhouette |= SIL_TOP | SIL_BOTTOM; + draw_segment->drawsegclip.silhouette |= SIL_TOP | SIL_BOTTOM; } RenderMiddleTexture(start, stop); @@ -477,7 +477,7 @@ namespace swrenderer if (markportal) { - Thread->Portal->AddLinePortal(mLineSegment->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip); + Thread->Portal->AddLinePortal(mLineSegment->linedef, draw_segment->x1, draw_segment->x2, draw_segment->drawsegclip.sprtopclip, draw_segment->drawsegclip.sprbottomclip); } return true; diff --git a/src/rendering/swrenderer/line/r_renderdrawsegment.cpp b/src/rendering/swrenderer/line/r_renderdrawsegment.cpp index 3d7e19a18..7258167af 100644 --- a/src/rendering/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/rendering/swrenderer/line/r_renderdrawsegment.cpp @@ -94,16 +94,16 @@ namespace swrenderer bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0; bool visible = alpha > 0.0f; - if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls()) + if (!visible && !ds->drawsegclip.bFogBoundary && !ds->Has3DFloorWalls()) { return; } // [RH] Draw fog partition - if (ds->bFogBoundary) + if (ds->drawsegclip.bFogBoundary) { - const short *mfloorclip = ds->sprbottomclip - ds->x1; - const short *mceilingclip = ds->sprtopclip - ds->x1; + const short *mfloorclip = ds->drawsegclip.sprbottomclip - ds->x1; + const short *mceilingclip = ds->drawsegclip.sprtopclip - ds->x1; RenderFogBoundary renderfog; renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight); @@ -120,8 +120,8 @@ namespace swrenderer if (!notrelevant) { - ds->sprclipped = true; - fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight); + ds->drawsegclip.sprclipped = true; + fillshort(ds->drawsegclip.sprtopclip - ds->x1 + x1, x2 - x1, viewheight); } } @@ -141,8 +141,8 @@ namespace swrenderer } FSoftwareTexture *tex = ttex->GetSoftwareTexture(); - const short *mfloorclip = ds->sprbottomclip - ds->x1; - const short *mceilingclip = ds->sprtopclip - ds->x1; + const short *mfloorclip = ds->drawsegclip.sprbottomclip - ds->x1; + const short *mceilingclip = ds->drawsegclip.sprtopclip - ds->x1; bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); if (!wrap) @@ -297,8 +297,8 @@ namespace swrenderer mLight.SetLightLeft(ds->light, ds->lightstep, ds->x1); - const short *mfloorclip = ds->sprbottomclip - ds->x1; - const short *mceilingclip = ds->sprtopclip - ds->x1; + const short *mfloorclip = ds->drawsegclip.sprbottomclip - ds->x1; + const short *mceilingclip = ds->drawsegclip.sprtopclip - ds->x1; Clip3DFloors *clip3d = Thread->Clip3D.get(); wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC); diff --git a/src/rendering/swrenderer/scene/r_portal.cpp b/src/rendering/swrenderer/scene/r_portal.cpp index 279e261f8..40528777b 100644 --- a/src/rendering/swrenderer/scene/r_portal.cpp +++ b/src/rendering/swrenderer/scene/r_portal.cpp @@ -206,18 +206,18 @@ namespace swrenderer // Create a drawseg to clip sprites to the sky plane DrawSegment *draw_segment = Thread->FrameMemory->NewObject(); - draw_segment->CurrentPortalUniq = CurrentPortalUniq; + draw_segment->drawsegclip.CurrentPortalUniq = CurrentPortalUniq; draw_segment->WallC.sz1 = 0; draw_segment->WallC.sz2 = 0; draw_segment->x1 = pl->left; draw_segment->x2 = pl->right; - 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->bFogBoundary = false; + draw_segment->drawsegclip.silhouette = SIL_BOTH; + draw_segment->drawsegclip.sprbottomclip = Thread->FrameMemory->AllocMemory(pl->right - pl->left); + draw_segment->drawsegclip.sprtopclip = Thread->FrameMemory->AllocMemory(pl->right - pl->left); + draw_segment->drawsegclip.bFogBoundary = false; draw_segment->curline = nullptr; - memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short)); - memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short)); + memcpy(draw_segment->drawsegclip.sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short)); + memcpy(draw_segment->drawsegclip.sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short)); drawseglist->Push(draw_segment); Thread->OpaquePass->RenderScene(Thread->Viewport->Level()); diff --git a/src/rendering/swrenderer/scene/r_translucent_pass.cpp b/src/rendering/swrenderer/scene/r_translucent_pass.cpp index 16338c0d4..02e1afe63 100644 --- a/src/rendering/swrenderer/scene/r_translucent_pass.cpp +++ b/src/rendering/swrenderer/scene/r_translucent_pass.cpp @@ -114,7 +114,7 @@ namespace swrenderer for (DrawSegment *seg : portaldrawsegs) { // ignore segs from other portals - if (seg->CurrentPortalUniq != renderportal->CurrentPortalUniq) + if (seg->drawsegclip.CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; // (all checks that are already done in R_CollectPortals have been removed for performance reasons.) @@ -154,19 +154,19 @@ namespace swrenderer DrawSegment *ds = drawseglist->Segment(index); // [ZZ] the same as above - if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq) + if (ds->drawsegclip.CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; - if (ds->texcoords || ds->bFogBoundary) + if (ds->texcoords || ds->drawsegclip.bFogBoundary) { RenderDrawSegment renderer(Thread); renderer.Render(ds, ds->x1, ds->x2, clip3DFloor); - if (renew && ds->bFogBoundary) // don't draw fogboundary again - ds->bFogBoundary = false; + if (renew && ds->drawsegclip.bFogBoundary) // don't draw fogboundary again + ds->drawsegclip.bFogBoundary = false; - if (renew && ds->sprclipped) + if (renew && ds->drawsegclip.sprclipped) { - memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * sizeof(short)); - ds->sprclipped = false; + memcpy(ds->drawsegclip.sprtopclip, ds->drawsegclip.bkup, (ds->x2 - ds->x1) * sizeof(short)); + ds->drawsegclip.sprclipped = false; } } } diff --git a/src/rendering/swrenderer/segments/r_drawsegment.cpp b/src/rendering/swrenderer/segments/r_drawsegment.cpp index 798ee7a3c..f5d2cc6a6 100644 --- a/src/rendering/swrenderer/segments/r_drawsegment.cpp +++ b/src/rendering/swrenderer/segments/r_drawsegment.cpp @@ -131,10 +131,10 @@ namespace swrenderer { ds = Segment(groupIndex); - if (ds->silhouette & SIL_BOTTOM) + if (ds->drawsegclip.silhouette & SIL_BOTTOM) { short *clip1 = clipbottom + ds->x1; - const short *clip2 = ds->sprbottomclip; + const short *clip2 = ds->drawsegclip.sprbottomclip; int i = ds->x2 - ds->x1; do { @@ -145,10 +145,10 @@ namespace swrenderer } while (--i); } - if (ds->silhouette & SIL_TOP) + if (ds->drawsegclip.silhouette & SIL_TOP) { short *clip1 = cliptop + ds->x1; - const short *clip2 = ds->sprtopclip; + const short *clip2 = ds->drawsegclip.sprtopclip; int i = ds->x2 - ds->x1; do { diff --git a/src/rendering/swrenderer/segments/r_drawsegment.h b/src/rendering/swrenderer/segments/r_drawsegment.h index 7051e4e30..b814c57f6 100644 --- a/src/rendering/swrenderer/segments/r_drawsegment.h +++ b/src/rendering/swrenderer/segments/r_drawsegment.h @@ -25,28 +25,31 @@ namespace swrenderer { + struct DrawSegmentClipInfo + { + // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. + short* sprtopclip = nullptr; + short* sprbottomclip = nullptr; + short* bkup = nullptr; // sprtopclip backup, for translucent and 3d floor walls + + bool sprclipped = false; // True if draw segment was used for clipping sprites + uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both + bool bFogBoundary = false; + int CurrentPortalUniq = 0; // [ZZ] to identify the portal that this drawseg is in. used for sprite clipping. + int SubsectorDepth; + }; + struct DrawSegment { seg_t *curline; float light, lightstep; short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg - FWallCoords WallC; - uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both - bool bFogBoundary = false; + FWallCoords WallC; + FWallTmapVals tmapvals; ProjectedWallTexcoords texcoords; - // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. - short *sprtopclip = nullptr; - short *sprbottomclip = nullptr; - short *bkup = nullptr; // sprtopclip backup, for mid and fake textures - bool sprclipped = false; // True if draw segment was used for clipping sprites - - FWallTmapVals tmapvals; - - int CurrentPortalUniq = 0; // [ZZ] to identify the portal that this drawseg is in. used for sprite clipping. - - int SubsectorDepth; + DrawSegmentClipInfo drawsegclip; bool Has3DFloorWalls() const { return b3DFloorBoundary != 0; } bool Has3DFloorFrontSectorWalls() const { return (b3DFloorBoundary & 2) == 2; } diff --git a/src/rendering/swrenderer/things/r_particle.cpp b/src/rendering/swrenderer/things/r_particle.cpp index 231ee9b4c..0d9755a65 100644 --- a/src/rendering/swrenderer/things/r_particle.cpp +++ b/src/rendering/swrenderer/things/r_particle.cpp @@ -298,7 +298,7 @@ namespace swrenderer if ((siz2 - siz1) * ((x2 + x1) / 2 - ds->WallC.sx1) / (ds->WallC.sx2 - ds->WallC.sx1) + siz1 < idepth) { // [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves - if (ds->CurrentPortalUniq == CurrentPortalUniq) + if (ds->drawsegclip.CurrentPortalUniq == CurrentPortalUniq) { RenderDrawSegment renderer(thread); renderer.Render(ds, MAX(ds->x1, x1), MIN(ds->x2, x2), clip3DFloor); diff --git a/src/rendering/swrenderer/things/r_visiblesprite.cpp b/src/rendering/swrenderer/things/r_visiblesprite.cpp index e2a328b58..f2f9a843c 100644 --- a/src/rendering/swrenderer/things/r_visiblesprite.cpp +++ b/src/rendering/swrenderer/things/r_visiblesprite.cpp @@ -59,7 +59,7 @@ namespace swrenderer for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++) { DrawSegment *ds = segmentlist->TranslucentSegment(index); - if (ds->SubsectorDepth >= SubsectorDepth && ds->CurrentPortalUniq == renderportal->CurrentPortalUniq) + if (ds->drawsegclip.SubsectorDepth >= SubsectorDepth && ds->drawsegclip.CurrentPortalUniq == renderportal->CurrentPortalUniq) { int r1 = MAX(ds->x1, 0); int r2 = MIN(ds->x2, viewwidth - 1); @@ -321,7 +321,7 @@ namespace swrenderer for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++) { DrawSegment *ds = segmentlist->TranslucentSegment(index); - if (ds->SubsectorDepth >= subsectordepth && ds->CurrentPortalUniq == renderportal->CurrentPortalUniq) + if (ds->drawsegclip.SubsectorDepth >= subsectordepth && ds->drawsegclip.CurrentPortalUniq == renderportal->CurrentPortalUniq) { int r1 = MAX(ds->x1, 0); int r2 = MIN(ds->x2, viewwidth - 1); @@ -350,7 +350,7 @@ namespace swrenderer (spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) - (spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0)) { - if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq) + if (ds->drawsegclip.CurrentPortalUniq == renderportal->CurrentPortalUniq) { int r1 = MAX(ds->x1, x1); int r2 = MIN(ds->x2, x2); @@ -405,7 +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->texcoords && !ds->bFogBoundary)) + if (ds->x1 >= x2 || ds->x2 <= x1 || (!(ds->drawsegclip.silhouette & SIL_BOTH) && !ds->texcoords && !ds->drawsegclip.bFogBoundary)) { // does not cover sprite continue; @@ -431,10 +431,10 @@ namespace swrenderer // [RH] Optimized further (at least for VC++; // other compilers should be at least as good as before) - if (ds->silhouette & SIL_BOTTOM) //bottom sil + if (ds->drawsegclip.silhouette & SIL_BOTTOM) //bottom sil { short *clip1 = clipbot + r1; - const short *clip2 = ds->sprbottomclip + r1 - ds->x1; + const short *clip2 = ds->drawsegclip.sprbottomclip + r1 - ds->x1; int i = r2 - r1; do { @@ -445,10 +445,10 @@ namespace swrenderer } while (--i); } - if (ds->silhouette & SIL_TOP) // top sil + if (ds->drawsegclip.silhouette & SIL_TOP) // top sil { short *clip1 = cliptop + r1; - const short *clip2 = ds->sprtopclip + r1 - ds->x1; + const short *clip2 = ds->drawsegclip.sprtopclip + r1 - ds->x1; int i = r2 - r1; do {