diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index feb261d67..813ff43c3 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -78,7 +78,9 @@ namespace swrenderer if (WallC.Init(pt1, pt2, 32.0 / (1 << 12))) return; - if (WallC.sx1 >= WindowRight || WallC.sx2 <= WindowLeft) + RenderPortal *renderportal = RenderPortal::Instance(); + + if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft) return; if (line->linedef == NULL) @@ -92,7 +94,7 @@ namespace swrenderer // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. - if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, ViewPos)) + if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, ViewPos)) return; vertex_t *v1, *v2; @@ -162,12 +164,12 @@ namespace swrenderer if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) { rw_havehigh = true; - R_CreateWallSegmentYSloped(wallupper, backsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP); + R_CreateWallSegmentYSloped(wallupper, backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); } if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) { rw_havelow = true; - R_CreateWallSegmentYSloped(walllower, backsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP); + R_CreateWallSegmentYSloped(walllower, backsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); } // Portal @@ -268,8 +270,8 @@ namespace swrenderer } else { - rw_ceilstat = R_CreateWallSegmentYSloped(walltop, frontsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP); - rw_floorstat = R_CreateWallSegmentYSloped(wallbottom, frontsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP); + rw_ceilstat = R_CreateWallSegmentYSloped(walltop, frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); + rw_floorstat = R_CreateWallSegmentYSloped(wallbottom, frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); // [RH] treat off-screen walls as solid #if 0 // Maybe later... @@ -339,8 +341,10 @@ namespace swrenderer rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1); + + RenderPortal *renderportal = RenderPortal::Instance(); - draw_segment->CurrentPortalUniq = CurrentPortalUniq; + draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq; draw_segment->sx1 = WallC.sx1; draw_segment->sx2 = WallC.sx2; draw_segment->sz1 = WallC.sz1; @@ -715,7 +719,8 @@ namespace swrenderer // wall but nothing to draw for it. // Recalculate walltop so that the wall is clipped by the back sector's // ceiling instead of the front sector's ceiling. - R_CreateWallSegmentYSloped(walltop, backsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP); + RenderPortal *renderportal = RenderPortal::Instance(); + R_CreateWallSegmentYSloped(walltop, backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); } // Putting sky ceilings on the front and back of a line alters the way unpegged // positioning works. @@ -1166,8 +1171,10 @@ namespace swrenderer tleft.Y = float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin); tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin); + + RenderPortal *renderportal = RenderPortal::Instance(); - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { float t = -tleft.X; tleft.X = -tright.X; @@ -1222,8 +1229,10 @@ namespace swrenderer { const FVector2 *left = &wallc->tleft; const FVector2 *right = &wallc->tright; + + RenderPortal *renderportal = RenderPortal::Instance(); - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { swapvalues(left, right); } @@ -1241,8 +1250,10 @@ namespace swrenderer double fullx2 = right.X * ViewSin - right.Y * ViewCos; double fully1 = left.X * ViewTanCos + left.Y * ViewTanSin; double fully2 = right.X * ViewTanCos + right.Y * ViewTanSin; + + RenderPortal *renderportal = RenderPortal::Instance(); - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { fullx1 = -fullx1; fullx2 = -fullx2; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 981ae2dde..29309f022 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -442,11 +442,13 @@ namespace swrenderer assert(WallC.sx1 <= x1); assert(WallC.sx2 >= x2); + + RenderPortal *renderportal = RenderPortal::Instance(); // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) { - int j = R_CreateWallSegmentYSloped(most3, frontsector->e->XFloor.lightlist[i].plane, &WallC, curline, MirrorFlags & RF_XFLIP); + int j = R_CreateWallSegmentYSloped(most3, frontsector->e->XFloor.lightlist[i].plane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); if (j != 3) { for (int j = x1; j < x2; ++j) diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index df8ecc19a..ba88dd718 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -93,7 +93,8 @@ namespace swrenderer ystep = -sin(planeang) / FocalLengthX; // [RH] flip for mirrors - if (MirrorFlags & RF_XFLIP) + RenderPortal *renderportal = RenderPortal::Instance(); + if (renderportal->MirrorFlags & RF_XFLIP) { xstep = -xstep; ystep = -ystep; diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index 3cf4176c9..727a04e51 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -314,6 +314,8 @@ namespace swrenderer void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat) { using namespace drawerargs; + + RenderPortal *renderportal = RenderPortal::Instance(); uint32_t height = frontskytex->GetHeight(); @@ -327,7 +329,7 @@ namespace swrenderer uint32_t uv_step = (uint32_t)(v_step * 0x01000000); int x = start_x + i; - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) x = (viewwidth - x); uint32_t ang, angle1, angle2; @@ -431,8 +433,10 @@ namespace swrenderer { swall[x] = swal; } + + RenderPortal *renderportal = RenderPortal::Instance(); - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { for (x = pl->left; x < pl->right; ++x) { diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index 7a4a8c8db..e68cee2ab 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -143,7 +143,8 @@ namespace swrenderer plane_su *= 4294967296.f; plane_sv *= 4294967296.f; - if (MirrorFlags & RF_XFLIP) + RenderPortal *renderportal = RenderPortal::Instance(); + if (renderportal->MirrorFlags & RF_XFLIP) { plane_su[0] = -plane_su[0]; plane_sv[0] = -plane_sv[0]; diff --git a/src/swrenderer/plane/r_visibleplane.cpp b/src/swrenderer/plane/r_visibleplane.cpp index 14c830fc9..d1b3084be 100644 --- a/src/swrenderer/plane/r_visibleplane.cpp +++ b/src/swrenderer/plane/r_visibleplane.cpp @@ -250,6 +250,8 @@ namespace swrenderer // New visplane algorithm uses hash table -- killough hash = isskybox ? MAXVISPLANES : visplane_hash(picnum.GetIndex(), lightlevel, height); + + RenderPortal *renderportal = RenderPortal::Instance(); for (check = visplanes[hash]; check; check = check->next) // killough { @@ -260,9 +262,9 @@ namespace swrenderer if (portal->mType != PORTS_SKYVIEWPOINT) { // This skybox is really a stacked sector, so we need to // check even more. - if (check->extralight == stacked_extralight && - check->visibility == stacked_visibility && - check->viewpos == stacked_viewpos && + if (check->extralight == renderportal->stacked_extralight && + check->visibility == renderportal->stacked_visibility && + check->viewpos == renderportal->stacked_viewpos && ( // headache inducing logic... :( (portal->mType != PORTS_STACKEDSECTORTHING) || @@ -277,7 +279,7 @@ namespace swrenderer *xform == check->xform ) ) && - check->viewangle == stacked_angle + check->viewangle == renderportal->stacked_angle ) ) ) @@ -298,8 +300,8 @@ namespace swrenderer basecolormap == check->colormap && // [RH] Add more checks *xform == check->xform && sky == check->sky && - CurrentPortalUniq == check->CurrentPortalUniq && - MirrorFlags == check->MirrorFlags && + renderportal->CurrentPortalUniq == check->CurrentPortalUniq && + renderportal->MirrorFlags == check->MirrorFlags && Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox && ViewPos == check->viewpos ) @@ -319,14 +321,14 @@ namespace swrenderer check->portal = portal; check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98 check->right = 0; - check->extralight = stacked_extralight; - check->visibility = stacked_visibility; - check->viewpos = stacked_viewpos; - check->viewangle = stacked_angle; + check->extralight = renderportal->stacked_extralight; + check->visibility = renderportal->stacked_visibility; + check->viewpos = renderportal->stacked_viewpos; + check->viewangle = renderportal->stacked_angle; check->Alpha = alpha; check->Additive = additive; - check->CurrentPortalUniq = CurrentPortalUniq; - check->MirrorFlags = MirrorFlags; + check->CurrentPortalUniq = renderportal->CurrentPortalUniq; + check->MirrorFlags = renderportal->MirrorFlags; check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox; fillshort(check->top, viewwidth, 0x7fff); @@ -421,13 +423,15 @@ namespace swrenderer int vpcount = 0; drawerargs::ds_color = 3; + + RenderPortal *renderportal = RenderPortal::Instance(); for (i = 0; i < MAXVISPLANES; i++) { for (pl = visplanes[i]; pl; pl = pl->next) { // kg3D - draw only correct planes - if (pl->CurrentPortalUniq != CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox) + if (pl->CurrentPortalUniq != renderportal->CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox) continue; // kg3D - draw only real planes now if (pl->sky >= 0) { @@ -448,19 +452,21 @@ namespace swrenderer DVector3 oViewPos = ViewPos; DAngle oViewAngle = ViewAngle; + + RenderPortal *renderportal = RenderPortal::Instance(); for (i = 0; i < MAXVISPLANES; i++) { for (pl = visplanes[i]; pl; pl = pl->next) { - if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq) + if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; if (pl->sky < 0 && pl->height.Zat0() == height) { ViewPos = pl->viewpos; ViewAngle = pl->viewangle; - MirrorFlags = pl->MirrorFlags; + renderportal->MirrorFlags = pl->MirrorFlags; R_DrawSinglePlane(pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); } diff --git a/src/swrenderer/r_main.cpp b/src/swrenderer/r_main.cpp index a5978b5a8..71031486a 100644 --- a/src/swrenderer/r_main.cpp +++ b/src/swrenderer/r_main.cpp @@ -394,20 +394,6 @@ static void R_ShutdownRenderer() R_FreeDrawSegs(); } -//========================================================================== -// -// R_CopyStackedViewParameters -// -//========================================================================== - -void R_CopyStackedViewParameters() -{ - stacked_viewpos = ViewPos; - stacked_angle = ViewAngle; - stacked_extralight = extralight; - stacked_visibility = R_GetVisibility(); -} - //========================================================================== // // R_SetupColormap @@ -555,11 +541,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) colfunc = basecolfunc; spanfunc = &SWPixelFormatDrawers::DrawSpan; - WindowLeft = 0; - WindowRight = viewwidth; - MirrorFlags = 0; - CurrentPortal = NULL; - CurrentPortalUniq = 0; + RenderPortal::Instance()->SetMainPortal(); r_dontmaplines = dontmaplines; @@ -589,10 +571,10 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) { PlaneCycles.Clock(); R_DrawPlanes(); - R_DrawPortals(); + RenderPortal::Instance()->RenderPlanePortals(); PlaneCycles.Unclock(); - R_DrawWallPortals(); + RenderPortal::Instance()->RenderLinePortals(); NetUpdate (); diff --git a/src/swrenderer/r_main.h b/src/swrenderer/r_main.h index a6e198482..c0a8ac345 100644 --- a/src/swrenderer/r_main.h +++ b/src/swrenderer/r_main.h @@ -134,8 +134,6 @@ void R_MultiresInit (void); -extern void R_CopyStackedViewParameters(); - extern double globaluclip, globaldclip; } diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index c1240bc6b..f08a2e026 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -38,9 +38,10 @@ #include "v_palette.h" #include "v_video.h" #include "m_png.h" -#include "scene/r_bsp.h" #include "r_swrenderer.h" +#include "scene/r_bsp.h" #include "scene/r_3dfloors.h" +#include "scene/r_portal.h" #include "textures/textures.h" #include "r_data/voxels.h" #include "drawers/r_draw_rgba.h" @@ -395,7 +396,7 @@ void FSoftwareRenderer::SetupFrame(player_t *player) void FSoftwareRenderer::CopyStackedViewParameters() { - R_CopyStackedViewParameters(); + RenderPortal::Instance()->CopyStackedViewParameters(); } //========================================================================== diff --git a/src/swrenderer/scene/r_bsp.cpp b/src/swrenderer/scene/r_bsp.cpp index 90866a3a4..1e390b313 100644 --- a/src/swrenderer/scene/r_bsp.cpp +++ b/src/swrenderer/scene/r_bsp.cpp @@ -333,7 +333,7 @@ namespace swrenderer ry1 = x1 * ViewTanCos + y1 * ViewTanSin; ry2 = x2 * ViewTanCos + y2 * ViewTanSin; - if (MirrorFlags & RF_XFLIP) + if (RenderPortal::Instance()->MirrorFlags & RF_XFLIP) { double t = -rx1; rx1 = -rx2; diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index 794c3916b..092eac4c9 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -62,31 +62,12 @@ CVAR(Bool, r_skyboxes, true, 0) namespace swrenderer { - int WindowLeft, WindowRight; - uint16_t MirrorFlags; - - PortalDrawseg *CurrentPortal = nullptr; - int CurrentPortalUniq = 0; - bool CurrentPortalInSkybox = false; - - // These are copies of the main parameters used when drawing stacked sectors. - // When you change the main parameters, you should copy them here too *unless* - // you are changing them to draw a stacked sector. Otherwise, stacked sectors - // won't draw in skyboxes properly. - int stacked_extralight; - double stacked_visibility; - DVector3 stacked_viewpos; - DAngle stacked_angle; - - namespace + RenderPortal *RenderPortal::Instance() { - int numskyboxes; // For ADD_STAT(skyboxes) + static RenderPortal renderportal; + return &renderportal; } - //========================================================================== - // - // R_DrawPortals - // // Draws any recorded sky boxes and then frees them. // // The process: @@ -102,16 +83,8 @@ namespace swrenderer // 8. Repeat for any other sky boxes. // 9. Put the camera back where it was to begin with. // - //========================================================================== - - void R_DrawPortals() + void RenderPortal::RenderPlanePortals() { - static TArray interestingStack; - static TArray drawsegStack; - static TArray visspriteStack; - static TArray viewposStack; - static TArray visplaneStack; - numskyboxes = 0; if (visplanes[MAXVISPLANES] == nullptr) @@ -164,7 +137,7 @@ namespace swrenderer ViewPos = sky->InterpolatedPosition(r_TicFracF); ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF); - R_CopyStackedViewParameters(); + CopyStackedViewParameters(); break; } @@ -311,21 +284,21 @@ namespace swrenderer freehead = &(*freehead)->next; } - void R_DrawWallPortals() + void RenderPortal::RenderLinePortals() { // [RH] Walk through mirrors // [ZZ] Merged with portals size_t lastportal = WallPortals.Size(); for (unsigned int i = 0; i < lastportal; i++) { - R_EnterPortal(&WallPortals[i], 0); + RenderLinePortal(&WallPortals[i], 0); } CurrentPortal = nullptr; CurrentPortalUniq = 0; } - void R_EnterPortal(PortalDrawseg* pds, int depth) + void RenderPortal::RenderLinePortal(PortalDrawseg* pds, int depth) { // [ZZ] check depth. fill portal with black if it's exceeding the visual recursion limit, and continue like nothing happened. if (depth >= r_portal_recursions) @@ -364,7 +337,7 @@ namespace swrenderer } if (r_highlight_portals) - R_HighlightPortal(pds); + RenderLinePortalHighlight(pds); return; } @@ -441,7 +414,7 @@ namespace swrenderer ViewTanSin = FocalTangent * ViewSin; ViewTanCos = FocalTangent * ViewCos; - R_CopyStackedViewParameters(); + CopyStackedViewParameters(); validcount++; PortalDrawseg* prevpds = CurrentPortal; @@ -478,7 +451,7 @@ namespace swrenderer PlaneCycles.Clock(); R_DrawPlanes(); - R_DrawPortals(); + RenderPlanePortals(); PlaneCycles.Unclock(); double vzp = ViewPos.Z; @@ -488,7 +461,7 @@ namespace swrenderer unsigned int portalsAtEnd = WallPortals.Size(); for (; portalsAtStart < portalsAtEnd; portalsAtStart++) { - R_EnterPortal(&WallPortals[portalsAtStart], depth + 1); + RenderLinePortal(&WallPortals[portalsAtStart], depth + 1); } int prevuniq2 = CurrentPortalUniq; CurrentPortalUniq = prevuniq; @@ -506,7 +479,7 @@ namespace swrenderer // draw a red line around a portal if it's being highlighted if (r_highlight_portals) - R_HighlightPortal(pds); + RenderLinePortalHighlight(pds); CurrentPortal = prevpds; MirrorFlags = prevmf; @@ -516,7 +489,7 @@ namespace swrenderer ViewPath[1] = savedpath[1]; } - void R_HighlightPortal(PortalDrawseg* pds) + void RenderPortal::RenderLinePortalHighlight(PortalDrawseg* pds) { // [ZZ] NO OVERFLOW CHECKS HERE // I believe it won't break. if it does, blame me. :( @@ -555,11 +528,28 @@ namespace swrenderer else *(pixels + Ybottom * RenderTarget->GetPitch() + x) = color; } } + + void RenderPortal::CopyStackedViewParameters() + { + stacked_viewpos = ViewPos; + stacked_angle = ViewAngle; + stacked_extralight = extralight; + stacked_visibility = R_GetVisibility(); + } + + void RenderPortal::SetMainPortal() + { + WindowLeft = 0; + WindowRight = viewwidth; + MirrorFlags = 0; + CurrentPortal = nullptr; + CurrentPortalUniq = 0; + } } ADD_STAT(skyboxes) { FString out; - out.Format("%d skybox planes", swrenderer::numskyboxes); + out.Format("%d skybox planes", swrenderer::RenderPortal::Instance()->numskyboxes); return out; } diff --git a/src/swrenderer/scene/r_portal.h b/src/swrenderer/scene/r_portal.h index f7b1fb74c..178102618 100644 --- a/src/swrenderer/scene/r_portal.h +++ b/src/swrenderer/scene/r_portal.h @@ -17,20 +17,46 @@ namespace swrenderer { - extern int WindowLeft, WindowRight; - extern uint16_t MirrorFlags; + struct visplane_t; - extern PortalDrawseg* CurrentPortal; - extern int CurrentPortalUniq; - extern bool CurrentPortalInSkybox; + class RenderPortal + { + public: + static RenderPortal *Instance(); + + void SetMainPortal(); + void CopyStackedViewParameters(); + + void RenderPlanePortals(); + void RenderLinePortals(); + + int WindowLeft = 0; + int WindowRight = 0; + uint16_t MirrorFlags = 0; - extern int stacked_extralight; - extern double stacked_visibility; - extern DVector3 stacked_viewpos; - extern DAngle stacked_angle; + PortalDrawseg* CurrentPortal = nullptr; + int CurrentPortalUniq = 0; + bool CurrentPortalInSkybox = false; - void R_DrawPortals(); - void R_DrawWallPortals(); - void R_EnterPortal(PortalDrawseg* pds, int depth); - void R_HighlightPortal(PortalDrawseg* pds); + // These are copies of the main parameters used when drawing stacked sectors. + // When you change the main parameters, you should copy them here too *unless* + // you are changing them to draw a stacked sector. Otherwise, stacked sectors + // won't draw in skyboxes properly. + int stacked_extralight = 0; + double stacked_visibility = 0.0; + DVector3 stacked_viewpos; + DAngle stacked_angle; + + int numskyboxes = 0; // For ADD_STAT(skyboxes) + + private: + void RenderLinePortal(PortalDrawseg* pds, int depth); + void RenderLinePortalHighlight(PortalDrawseg* pds); + + TArray interestingStack; + TArray drawsegStack; + TArray visspriteStack; + TArray viewposStack; + TArray visplaneStack; + }; } diff --git a/src/swrenderer/scene/r_things.cpp b/src/swrenderer/scene/r_things.cpp index 3b00ccbd4..54b93caee 100644 --- a/src/swrenderer/scene/r_things.cpp +++ b/src/swrenderer/scene/r_things.cpp @@ -427,14 +427,16 @@ static inline void R_CollectPortals() bool R_ClipSpriteColumnWithPortals(vissprite_t* spr) { + RenderPortal *renderportal = RenderPortal::Instance(); + // [ZZ] 10.01.2016: don't clip sprites from the root of a skybox. - if (CurrentPortalInSkybox) + if (renderportal->CurrentPortalInSkybox) return false; for (drawseg_t *seg : portaldrawsegs) { // ignore segs from other portals - if (seg->CurrentPortalUniq != CurrentPortalUniq) + if (seg->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; // (all checks that are already done in R_CollectPortals have been removed for performance reasons.) @@ -636,10 +638,12 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor { return; } + + RenderPortal *renderportal = RenderPortal::Instance(); // [ZZ] Or less definitely not visible (hue) // [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal. - if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), CurrentPortal->dst)) + if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst)) return; // [RH] Interpolate the sprite's position to make it look smooth @@ -776,7 +780,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor tx = tr_x * ViewSin - tr_y * ViewCos; // [RH] Flip for mirrors - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { tx = -tx; } @@ -847,7 +851,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor } // [RH] Flip for mirrors - renderflags ^= MirrorFlags & RF_XFLIP; + renderflags ^= renderportal->MirrorFlags & RF_XFLIP; // calculate edges of the shape const double thingxscalemul = spriteScale.X / tex->Scale.X; @@ -857,14 +861,14 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor x1 = centerx + xs_RoundToInt(dtx1); // off the right side? - if (x1 >= WindowRight) + if (x1 >= renderportal->WindowRight) return; tx += tex->GetWidth() * thingxscalemul; x2 = centerx + xs_RoundToInt(tx * xscale); // off the left side or too small? - if ((x2 < WindowLeft || x2 <= x1)) + if ((x2 < renderportal->WindowLeft || x2 <= x1)) return; xscale = spriteScale.X * xscale / tex->Scale.X; @@ -875,14 +879,14 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor // store information in a vissprite vis = R_NewVisSprite(); - vis->CurrentPortalUniq = CurrentPortalUniq; + vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); vis->yscale = float(InvZtoScale * yscale / tz); vis->idepth = float(1 / tz); vis->floorclip = thing->Floorclip / yscale; vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale; - vis->x1 = x1 < WindowLeft ? WindowLeft : x1; - vis->x2 = x2 > WindowRight ? WindowRight : x2; + vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1; + vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2; vis->Angle = thing->Angles.Yaw; if (renderflags & RF_XFLIP) @@ -902,11 +906,11 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor { vis = R_NewVisSprite(); - vis->CurrentPortalUniq = CurrentPortalUniq; + vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); vis->yscale = (float)yscale; - vis->x1 = WindowLeft; - vis->x2 = WindowRight; + vis->x1 = renderportal->WindowLeft; + vis->x2 = renderportal->WindowRight; vis->idepth = 1 / MINZ; vis->floorclip = thing->Floorclip; @@ -946,7 +950,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor vis->fakefloor = fakefloor; vis->fakeceiling = fakeceiling; vis->Style.ColormapNum = 0; - vis->bInMirror = MirrorFlags & RF_XFLIP; + vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; vis->bSplitSprite = false; if (voxel != NULL) @@ -1604,15 +1608,20 @@ void R_DrawSprite (vissprite_t *spr) neardepth = ds->sz2, fardepth = ds->sz1; } } + + // Check if sprite is in front of draw seg: if ((!spr->bWallSprite && neardepth > spr->depth) || ((spr->bWallSprite || fardepth > spr->depth) && (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)) { + RenderPortal *renderportal = RenderPortal::Instance(); + // seg is behind sprite, so draw the mid texture if it has one - if (ds->CurrentPortalUniq == CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here + if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here (ds->maskedtexturecol != -1 || ds->bFogBoundary)) R_RenderMaskedSegRange (ds, r1, r2); + continue; } @@ -1711,13 +1720,11 @@ void R_DrawMaskedSingle (bool renew) drawseg_t *ds; int i; -#if 0 - R_SplitVisSprites (); -#endif + RenderPortal *renderportal = RenderPortal::Instance(); for (i = vsprcount; i > 0; i--) { - if (spritesorter[i-1]->CurrentPortalUniq != CurrentPortalUniq) + if (spritesorter[i-1]->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; // probably another time R_DrawSprite (spritesorter[i-1]); } @@ -1737,7 +1744,7 @@ void R_DrawMaskedSingle (bool renew) for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough { // [ZZ] the same as above - if (ds->CurrentPortalUniq != CurrentPortalUniq) + if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue; // kg3D - no fake segs if (ds->fake) continue; diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp index 1224dbe91..c8ac27d9f 100644 --- a/src/swrenderer/segments/r_drawsegment.cpp +++ b/src/swrenderer/segments/r_drawsegment.cpp @@ -109,13 +109,15 @@ namespace swrenderer { short most[MAXWIDTH]; - R_CreateWallSegmentYSloped(most, curline->frontsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP); + RenderPortal *renderportal = RenderPortal::Instance(); + + R_CreateWallSegmentYSloped(most, curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); for (int i = x1; i < x2; ++i) { if (wallupper[i] < most[i]) wallupper[i] = most[i]; } - R_CreateWallSegmentYSloped(most, curline->frontsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP); + R_CreateWallSegmentYSloped(most, curline->frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); for (int i = x1; i < x2; ++i) { if (walllower[i] > most[i]) diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 489793790..2dbc6562c 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -66,9 +66,11 @@ namespace swrenderer vissprite_t* vis; sector_t* heightsec = NULL; FSWColormap* map; + + RenderPortal *renderportal = RenderPortal::Instance(); // [ZZ] Particle not visible through the portal plane - if (CurrentPortal && !!P_PointOnLineSide(particle->Pos, CurrentPortal->dst)) + if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos, renderportal->CurrentPortal->dst)) return; // transform the origin point @@ -84,7 +86,7 @@ namespace swrenderer tx = tr_x * ViewSin - tr_y * ViewCos; // Flip for mirrors - if (MirrorFlags & RF_XFLIP) + if (renderportal->MirrorFlags & RF_XFLIP) { tx = viewwidth - tx - 1; } @@ -99,8 +101,8 @@ namespace swrenderer // calculate edges of the shape double psize = particle->size / 8.0; - x1 = MAX(WindowLeft, centerx + xs_RoundToInt((tx - psize) * xscale)); - x2 = MIN(WindowRight, centerx + xs_RoundToInt((tx + psize) * xscale)); + x1 = MAX(renderportal->WindowLeft, centerx + xs_RoundToInt((tx - psize) * xscale)); + x2 = MIN(renderportal->WindowRight, centerx + xs_RoundToInt((tx + psize) * xscale)); if (x1 >= x2) return; @@ -175,7 +177,7 @@ namespace swrenderer // store information in a vissprite vis = R_NewVisSprite(); - vis->CurrentPortalUniq = CurrentPortalUniq; + vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; vis->heightsec = heightsec; vis->xscale = FLOAT2FIXED(xscale); vis->yscale = (float)xscale; diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 34c398c64..7699edf70 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -86,8 +86,10 @@ namespace swrenderer // Is it off-screen? if (wallc.Init(left, right, TOO_CLOSE_Z)) return; + + RenderPortal *renderportal = RenderPortal::Instance(); - if (wallc.sx1 >= WindowRight || wallc.sx2 <= WindowLeft) + if (wallc.sx1 >= renderportal->WindowRight || wallc.sx2 <= renderportal->WindowLeft) return; // Sprite sorting should probably treat these as walls, not sprites, @@ -100,9 +102,9 @@ namespace swrenderer gzb = pos.Z + scale.Y * scaled_bo; vis = R_NewVisSprite(); - vis->CurrentPortalUniq = CurrentPortalUniq; - vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; - vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2; + vis->CurrentPortalUniq = renderportal->CurrentPortalUniq; + vis->x1 = wallc.sx1 < renderportal->WindowLeft ? renderportal->WindowLeft : wallc.sx1; + vis->x2 = wallc.sx2 >= renderportal->WindowRight ? renderportal->WindowRight : wallc.sx2; vis->yscale = (float)scale.Y; vis->idepth = float(1 / tz); vis->depth = (float)tz; @@ -122,7 +124,7 @@ namespace swrenderer vis->Style.Alpha = float(thing->Alpha); vis->fakefloor = NULL; vis->fakeceiling = NULL; - vis->bInMirror = MirrorFlags & RF_XFLIP; + vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP; vis->pic = pic; vis->bIsVoxel = false; vis->bWallSprite = true;