From 5f87e81b6aad426fc5de65741411c186de56e73c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 22:04:29 +0200 Subject: [PATCH] - moved CurrentMapSections and in_area from GLSceneDrawer to HWDrawInfo. Not only are they better placed in the common code, but they are also both per-viewpoint and not per-scene, so this is a far more suitable place and avoids saving and restoring them in the portal code. --- src/gl/scene/gl_bsp.cpp | 18 +++++------ src/gl/scene/gl_drawinfo.cpp | 16 +++------- src/gl/scene/gl_portal.cpp | 42 ++++--------------------- src/gl/scene/gl_portal.h | 4 --- src/gl/scene/gl_scene.cpp | 39 +++++------------------ src/gl/scene/gl_scenedrawer.h | 2 -- src/gl/scene/gl_walls_draw.cpp | 2 +- src/hwrenderer/scene/hw_drawinfo.h | 4 +++ src/hwrenderer/scene/hw_fakeflat.cpp | 24 ++++++++++++++ src/hwrenderer/scene/hw_renderhacks.cpp | 11 +++++++ 10 files changed, 67 insertions(+), 95 deletions(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 2449fce9e..d0a21dfb1 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -140,9 +140,9 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) else { // clipping checks are only needed when the backsector is not the same as the front sector - if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); + if (gl_drawinfo->in_area == area_default) gl_drawinfo->in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); - backsector = hw_FakeFlat(seg->backsector, &bs, in_area, true); + backsector = hw_FakeFlat(seg->backsector, &bs, gl_drawinfo->in_area, true); if (hw_CheckClip(seg->sidedef, currentsector, backsector)) { @@ -364,10 +364,10 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } } // If this thing is in a map section that's not in view it can't possibly be visible - if (CurrentMapSections[thing->subsector->mapsection]) + if (gl_drawinfo->CurrentMapSections[thing->subsector->mapsection]) { GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, in_area, false); + sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, false); } } @@ -386,7 +386,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->mDrawer->in_area, true); + sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, true); } SetupSprite.Unclock(); } @@ -419,7 +419,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) if (!sector) return; // If the mapsections differ this subsector can't possibly be visible from the current view point - if (!CurrentMapSections[sub->mapsection]) return; + if (!gl_drawinfo->CurrentMapSections[sub->mapsection]) return; if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect. if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN) @@ -431,7 +431,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) } if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. - fakesector=hw_FakeFlat(sector, &fake, in_area, false); + fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); if (GLRenderer->mClipPortal) { @@ -497,14 +497,14 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // but undetermined heightsec state. This can only happen if the // subsector is obstructed but not excluded due to a large bounding box. // Due to the way a BSP works such a subsector can never be visible - if (!sector->GetHeightSec() || in_area!=area_default) + if (!sector->GetHeightSec() || gl_drawinfo->in_area!=area_default) { if (sector != sub->render_sector) { sector = sub->render_sector; // the planes of this subsector are faked to belong to another sector // This means we need the heightsec parts and light info of the render sector, not the actual one. - fakesector = hw_FakeFlat(sector, &fake, in_area, false); + fakesector = hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); } uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum]; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index dc39e3ecb..cc697114c 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -204,14 +204,6 @@ void FDrawInfo::StartScene() { ClearBuffers(); - sectorrenderflags.Resize(level.sectors.Size()); - ss_renderflags.Resize(level.subsectors.Size()); - no_renderflags.Resize(level.subsectors.Size()); - - memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); - memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0])); - memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0])); - next = gl_drawinfo; gl_drawinfo = this; for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset(); @@ -393,8 +385,8 @@ void FDrawInfo::FloodUpperGap(seg_t * seg) { wallseg ws; sector_t ffake, bfake; - sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true); - sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false); + sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true); + sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false); vertex_t * v1, * v2; @@ -445,8 +437,8 @@ void FDrawInfo::FloodLowerGap(seg_t * seg) { wallseg ws; sector_t ffake, bfake; - sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true); - sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false); + sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true); + sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false); vertex_t * v1, * v2; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e6fdc54b7..25209848d 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -271,7 +271,6 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) savedshowviewer = r_viewpoint.showviewer; savedAngles = r_viewpoint.Angles; savedviewactor=GLRenderer->mViewActor; - savedviewarea=drawer->in_area; savedviewpath[0] = r_viewpoint.Path[0]; savedviewpath[1] = r_viewpoint.Path[1]; savedvisibility = r_viewpoint.camera ? r_viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0); @@ -340,7 +339,6 @@ void GLPortal::End(bool usestencil) r_viewpoint.ActorPos = savedViewActorPos; r_viewpoint.Angles = savedAngles; GLRenderer->mViewActor=savedviewactor; - drawer->in_area=savedviewarea; if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags = (r_viewpoint.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); @@ -399,7 +397,6 @@ void GLPortal::End(bool usestencil) r_viewpoint.Pos = savedViewPos; r_viewpoint.Angles = savedAngles; GLRenderer->mViewActor=savedviewactor; - drawer->in_area=savedviewarea; if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags |= savedvisibility; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); @@ -560,26 +557,6 @@ GLPortal * GLPortal::FindPortal(const void * src) } -//----------------------------------------------------------------------------- -// -// Save/RestoreMapSection -// -// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene -// -//----------------------------------------------------------------------------- - -void GLPortal::SaveMapSection() -{ - SavedMapSection = std::move(drawer->CurrentMapSections); - drawer->CurrentMapSections.Resize(SavedMapSection.Size()); - drawer->CurrentMapSections.Zero(); -} - -void GLPortal::RestoreMapSection() -{ - drawer->CurrentMapSections = std::move(SavedMapSection); -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // @@ -629,13 +606,13 @@ 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)); - drawer->SetViewArea(); + di->SetViewArea(); ClearClipper(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - SaveMapSection(); - drawer->CurrentMapSections.Set(mapsection); + di->CurrentMapSections.Zero(); + di->CurrentMapSections.Set(mapsection); drawer->DrawScene(di, DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; @@ -645,8 +622,6 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) PlaneMirrorMode = old_pm; r_viewpoint.extralight = saved_extralight; - - RestoreMapSection(); } //----------------------------------------------------------------------------- @@ -717,7 +692,7 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di) for(int j=0;jportalcoverage[plane].sscount; j++) { subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]]; - drawer->CurrentMapSections.Set(dsub->mapsection); + di->CurrentMapSections.Set(dsub->mapsection); di->ss_renderflags[dsub->Index()] |= SSRF_SEEN; } } @@ -741,7 +716,6 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) if (origin->plane != -1) screen->instack[origin->plane]++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - SaveMapSection(); SetupCoverage(di); ClearClipper(); @@ -755,7 +729,6 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) } drawer->DrawScene(di, DM_PORTAL); - RestoreMapSection(); if (origin->plane != -1) screen->instack[origin->plane]--; } @@ -1031,8 +1004,6 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) } - SaveMapSection(); - for (unsigned i = 0; i < lines.Size(); i++) { line_t *line = lines[i].seg->linedef->getPortalDestination(); @@ -1040,7 +1011,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) if (line->sidedef[0]->Flags & WALLF_POLYOBJ) sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY()); else sub = line->frontsector->subsectors[0]; - drawer->CurrentMapSections.Set(sub->mapsection); + di->CurrentMapSections.Set(sub->mapsection); } GLRenderer->mViewActor = nullptr; @@ -1051,12 +1022,11 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) gl_RenderState.EnableClipLine(true); drawer->DrawScene(di, DM_PORTAL); gl_RenderState.EnableClipLine(false); - RestoreMapSection(); } void GLLineToLinePortal::RenderAttached(FDrawInfo *di) { - di->ProcessActorsInPortal(glport, di->mDrawer->in_area); + di->ProcessActorsInPortal(glport, di->in_area); } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 707c3d2a4..ecab4db22 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -75,11 +75,9 @@ private: DRotator savedAngles; bool savedshowviewer; AActor * savedviewactor; - area_t savedviewarea; ActorRenderFlags savedvisibility; GLPortal *PrevPortal; GLPortal *PrevClipPortal; - BitArray SavedMapSection; TArray mPrimIndices; protected: @@ -99,8 +97,6 @@ protected: virtual bool NeedDepthBuffer() { return true; } void ClearScreen(); virtual const char *GetName() = 0; - void SaveMapSection(); - void RestoreMapSection(); virtual void PushState() {} virtual void PopState() {} diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c3108a51b..c10ba669a 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -92,29 +92,6 @@ angle_t GLSceneDrawer::FrustumAngle() return a1; } -//----------------------------------------------------------------------------- -// -// Sets the area the camera is in -// -//----------------------------------------------------------------------------- -void GLSceneDrawer::SetViewArea() -{ - // The render_sector is better suited to represent the current position in GL - r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector; - - // Get the heightsec state from the render sector, not the current one! - if (r_viewpoint.sector->GetHeightSec()) - { - in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below : - (r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) && - !(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal; - } - else - { - in_area = level.HasHeightSecs? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs. - } -} - //----------------------------------------------------------------------------- // // resets the 3D viewport @@ -261,7 +238,7 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) di->mShadowMap = &GLRenderer->mShadowMap; RenderBSPNode (level.HeadNode()); - di->PreparePlayerSprites(r_viewpoint.sector, in_area); + di->PreparePlayerSprites(r_viewpoint.sector, di->in_area); // Process all the sprites on the current portal's back side which touch the portal. if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di); @@ -271,9 +248,9 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) // These cannot be multithreaded when the time comes because all these depend // on the global 'validcount' variable. - di->HandleMissingTextures(in_area); // Missing upper/lower textures + di->HandleMissingTextures(di->in_area); // Missing upper/lower textures di->HandleHackedSubsectors(); // open sector hacks for deep water - di->ProcessSectorStacks(in_area); // merge visplanes of sector stacks + di->ProcessSectorStacks(di->in_area); // merge visplanes of sector stacks GLRenderer->mLights->Finish(); GLRenderer->mVBO->Unmap(); @@ -578,9 +555,7 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen) GLPortal::BeginScene(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - CurrentMapSections.Resize(level.NumMapSections); - CurrentMapSections.Zero(); - CurrentMapSections.Set(mapsection); + di->CurrentMapSections.Set(mapsection); DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN); } @@ -644,7 +619,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl GLRenderer->mSceneClearColor[1] = 0.0f; GLRenderer->mSceneClearColor[2] = 0.0f; R_SetupFrame (r_viewpoint, r_viewwindow, camera); - SetViewArea(); GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility); @@ -684,6 +658,10 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl Set3DViewport(mainview); GLRenderer->mDrawingScene2D = true; GLRenderer->mCurrentFoV = fov; + + FDrawInfo *di = FDrawInfo::StartDrawInfo(this); + di->SetViewArea(); + // Stereo mode specific perspective projection SetProjection( eye->GetProjection(fov, ratio, fovratio) ); // SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper @@ -694,7 +672,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false); gl_RenderState.ApplyMatrices(); - FDrawInfo *di = FDrawInfo::StartDrawInfo(this); ProcessScene(di, toscreen); if (mainview && toscreen) EndDrawScene(di, lviewsector); // do not call this for camera textures. diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index dfca8f4fa..169cfbc7f 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -46,8 +46,6 @@ public: Clipper clipper; int FixedColormap; - area_t in_area; - BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. angle_t FrustumAngle(); void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index b8a2155c0..2dbe156dd 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -426,7 +426,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype) line_t *otherside = wall->lineportal->lines[0]->mDestination; if (otherside != NULL && otherside->portalindex < level.linePortals.Size()) { - ProcessActorsInPortal(otherside->getPortal()->mGroup, mDrawer->in_area); + ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area); } portal = new GLLineToLinePortal(wall->lineportal); } diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 429981c89..3e57fa21d 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -104,6 +104,9 @@ struct HWDrawInfo TArray ss_renderflags; TArray no_renderflags; + BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. + area_t in_area; + private: // For ProcessLowerMiniseg bool inview; @@ -114,6 +117,7 @@ private: public: void ClearBuffers(); + void SetViewArea(); bool DoOneSectorUpper(subsector_t * subsec, float planez, area_t in_area); bool DoOneSectorLower(subsector_t * subsec, float planez, area_t in_area); diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index 0e22e276f..761379851 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -31,6 +31,8 @@ #include "a_sharedglobal.h" #include "r_sky.h" #include "hw_fakeflat.h" +#include "hw_drawinfo.h" +#include "r_utility.h" //========================================================================== @@ -383,4 +385,26 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac return dest; } +//----------------------------------------------------------------------------- +// +// Sets the area the camera is in +// +//----------------------------------------------------------------------------- +void HWDrawInfo::SetViewArea() +{ + // The render_sector is better suited to represent the current position in GL + r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector; + + // Get the heightsec state from the render sector, not the current one! + if (r_viewpoint.sector->GetHeightSec()) + { + in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below : + (r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) && + !(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal; + } + else + { + in_area = level.HasHeightSecs ? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs. + } +} diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 5eacd9dfc..89352007c 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -72,7 +72,18 @@ void HWDrawInfo::ClearBuffers() HandledSubsectors.Clear(); spriteindex = 0; + CurrentMapSections.Resize(level.NumMapSections); + CurrentMapSections.Zero(); + + sectorrenderflags.Resize(level.sectors.Size()); + ss_renderflags.Resize(level.subsectors.Size()); + no_renderflags.Resize(level.subsectors.Size()); + + memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); + memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0])); + memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0])); } + //========================================================================== // // Adds a subsector plane to a sector's render list