From df0b1e8dae87648050562e506473c19549db7bef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 22:54:04 +0200 Subject: [PATCH] - moved the clipper out of GLSceneDrawer and let it be handled by HWDrawInfo. The precise way the clipper needs to be maintained may differ between APIs, so it is no longer owned by any render structure but instead HWDrawInfo only contains a reference. For OpenGL there is still only one static clipper because without multithreaded BSP traversal there is no need for more. --- src/gl/scene/gl_bsp.cpp | 8 +++++--- src/gl/scene/gl_drawinfo.cpp | 6 ++++++ src/gl/scene/gl_portal.cpp | 30 +++++++++++++++--------------- src/gl/scene/gl_portal.h | 2 +- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_scenedrawer.h | 7 ------- src/hwrenderer/scene/hw_drawinfo.h | 2 ++ 7 files changed, 30 insertions(+), 27 deletions(-) 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;