- 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.
This commit is contained in:
Christoph Oelckers 2018-05-21 22:04:29 +02:00
parent e6a447eb6f
commit 5f87e81b6a
10 changed files with 67 additions and 95 deletions

View File

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

View File

@ -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(&sectorrenderflags[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;

View File

@ -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;j<sub->portalcoverage[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);
}
//-----------------------------------------------------------------------------

View File

@ -75,11 +75,9 @@ private:
DRotator savedAngles;
bool savedshowviewer;
AActor * savedviewactor;
area_t savedviewarea;
ActorRenderFlags savedvisibility;
GLPortal *PrevPortal;
GLPortal *PrevClipPortal;
BitArray SavedMapSection;
TArray<unsigned int> 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() {}

View File

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

View File

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

View File

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

View File

@ -104,6 +104,9 @@ struct HWDrawInfo
TArray<uint8_t> ss_renderflags;
TArray<uint8_t> 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);

View File

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

View File

@ -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(&sectorrenderflags[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