diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index d0a21dfb1..5e87acc62 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -46,6 +46,7 @@ void GLSceneDrawer::UnclipSubsector(subsector_t *sub) { int count = sub->numlines; seg_t * seg = sub->firstline; + auto &clipper = *gl_drawinfo->mClipper; while (count--) { @@ -88,6 +89,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) if (clipres == PClip_InFront) return; } + auto &clipper = *gl_drawinfo->mClipper; angle_t startAngle = clipper.GetClipAngle(seg->v2); angle_t endAngle = clipper.GetClipAngle(seg->v1); @@ -225,7 +227,7 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!clipper.CheckBox(bsp->bbox[side])) + if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) { return; } @@ -429,7 +431,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // range this subsector spans before going on. UnclipSubsector(sub); } - if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. + if (gl_drawinfo->mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); @@ -575,7 +577,7 @@ void GLSceneDrawer::RenderBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!clipper.CheckBox(bsp->bbox[side])) + if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) { if (!(gl_drawinfo->no_renderflags[bsp->Index()] & SSRF_SEEN)) return; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index cc697114c..93ce4f624 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -191,10 +191,16 @@ FDrawInfo::~FDrawInfo() // Sets up a new drawinfo struct // //========================================================================== + +// OpenGL has no use for multiple clippers so use the same one for all DrawInfos. +static Clipper staticClipper; + FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) { FDrawInfo *di=di_list.GetNew(); di->mDrawer = drawer; + di->mClipper = &staticClipper; + staticClipper.Clear(); di->FixedColormap = drawer->FixedColormap; di->StartScene(); return di; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 25209848d..b90cd3dcd 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -286,14 +286,14 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) } -inline void GLPortal::ClearClipper() +inline void GLPortal::ClearClipper(FDrawInfo *di) { DAngle angleOffset = deltaangle(savedAngles.Yaw, r_viewpoint.Angles.Yaw); - drawer->clipper.Clear(); + di->mClipper->Clear(); // Set the clipper to the minimal visible area - drawer->clipper.SafeAddClipRange(0,0xffffffff); + di->mClipper->SafeAddClipRange(0,0xffffffff); for (unsigned int i = 0; i < lines.Size(); i++) { DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - savedViewPos).Angle() + angleOffset; @@ -301,16 +301,16 @@ inline void GLPortal::ClearClipper() if (deltaangle(endAngle, startAngle) < 0) { - drawer->clipper.SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs()); + di->mClipper->SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs()); } } // and finally clip it to the visible area angle_t a1 = drawer->FrustumAngle(); - if (a1 < ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); + if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); // lock the parts that have just been clipped out. - drawer->clipper.SetSilhouette(); + di->mClipper->SetSilhouette(); } //----------------------------------------------------------------------------- @@ -607,7 +607,7 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) inskybox = true; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); di->SetViewArea(); - ClearClipper(); + ClearClipper(di); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; @@ -717,15 +717,15 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(di); - ClearClipper(); + ClearClipper(di); // If the viewpoint is not within the portal, we need to invalidate the entire clip area. // The portal will re-validate the necessary parts when its subsectors get traversed. subsector_t *sub = R_PointInSubsector(r_viewpoint.Pos); if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN)) { - drawer->clipper.SafeAddClipRange(0, ANGLE_MAX); - drawer->clipper.SetBlocked(true); + di->mClipper->SafeAddClipRange(0, ANGLE_MAX); + di->mClipper->SetBlocked(true); } drawer->DrawScene(di, DM_PORTAL); @@ -771,7 +771,7 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di) PlaneMirrorFlag++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); - ClearClipper(); + ClearClipper(di); gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f); drawer->DrawScene(di, DM_PORTAL); @@ -938,14 +938,14 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di) MirrorFlag++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - drawer->clipper.Clear(); + di->mClipper->Clear(); angle_t af = drawer->FrustumAngle(); - if (afclipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af); + if (afmClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af); angle_t a2 = linedef->v1->GetClipAngle(); angle_t a1 = linedef->v2->GetClipAngle(); - drawer->clipper.SafeAddClipRange(a1,a2); + di->mClipper->SafeAddClipRange(a1,a2); gl_RenderState.SetClipLine(linedef); gl_RenderState.EnableClipLine(true); @@ -1017,7 +1017,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) GLRenderer->mViewActor = nullptr; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - ClearClipper(); + ClearClipper(di); gl_RenderState.SetClipLine(glport->lines[0]->mDestination); gl_RenderState.EnableClipLine(true); drawer->DrawScene(di, DM_PORTAL); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index ecab4db22..8b4a87f15 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -91,7 +91,7 @@ protected: void End(bool usestencil); virtual void DrawContents(FDrawInfo *di)=0; virtual void * GetSource() const =0; // GetSource MUST be implemented! - void ClearClipper(); + void ClearClipper(FDrawInfo *di); virtual bool IsSky() { return false; } virtual bool NeedCap() { return true; } virtual bool NeedDepthBuffer() { return true; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c10ba669a..78da1e5aa 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -214,7 +214,7 @@ void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirr void GLSceneDrawer::CreateScene(FDrawInfo *di) { angle_t a1 = FrustumAngle(); - InitClipper(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); + di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); // reset the portal manager GLPortal::StartFrame(); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 169cfbc7f..e6c30239b 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -44,7 +44,6 @@ public: GLPortal::drawer = this; } - Clipper clipper; int FixedColormap; angle_t FrustumAngle(); @@ -65,12 +64,6 @@ public: sector_t *RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void InitClipper(angle_t a1, angle_t a2) - { - clipper.Clear(); - clipper.SafeAddClipRangeRealAngles(a1, a2); - } - void SetView() { viewx = FLOAT2FIXED(r_viewpoint.Pos.X); diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 3e57fa21d..369bfe399 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -14,6 +14,7 @@ class IShadowMap; struct particle_t; struct FDynLightData; struct HUDSprite; +class Clipper; //========================================================================== // @@ -83,6 +84,7 @@ struct HWDrawInfo FVector2 mViewVector; AActor *mViewActor; IShadowMap *mShadowMap; + Clipper *mClipper; TArray MissingUpperTextures; TArray MissingLowerTextures;