- 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.
This commit is contained in:
Christoph Oelckers 2018-05-21 22:54:04 +02:00
parent 5f87e81b6a
commit df0b1e8dae
7 changed files with 30 additions and 27 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 (af<ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af);
if (af<ANGLE_180) di->mClipper->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);

View File

@ -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; }

View File

@ -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();

View File

@ -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);

View File

@ -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<MissingTextureInfo> MissingUpperTextures;
TArray<MissingTextureInfo> MissingLowerTextures;