- resorted portal render data.

Compiles but does not work...
This commit is contained in:
Christoph Oelckers 2018-04-01 22:26:57 +02:00
parent 8be788a9b3
commit 248a29bf06
40 changed files with 204 additions and 195 deletions

View file

@ -89,6 +89,8 @@ struct FLevelLocals
FDisplacementTable Displacements;
FPortalBlockmap PortalBlockmap;
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
TArray<FSectorPortalGroup *> portalGroups;
TArray<FLinePortalSpan> linePortalSpans;
TArray<zone_t> Zones;

View file

@ -20,29 +20,6 @@ inline int getExtraLight()
struct GLSectorStackPortal;
struct FPortal
{
DVector2 mDisplacement;
int plane;
GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal!
GLSectorStackPortal *GetRenderState();
};
struct FGLLinePortal
{
// defines the complete span of this portal, if this is of type PORTT_LINKED.
vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2
TArray<FLinePortal *> lines;
int validcount = 0;
};
extern TArray<FPortal *> glSectorPortals;
extern TArray<FGLLinePortal*> linePortalToGL;
extern TArray<uint8_t> currentmapsection;
void gl_InitPortals();
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement);
#endif

View file

@ -48,7 +48,12 @@
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/utility/gl_clock.h"
#include "gl/gl_functions.h"
//==========================================================================
//
// Helper types for portal grouping
//
//==========================================================================
struct FPortalID
{
@ -69,25 +74,8 @@ struct FPortalSector
};
typedef TArray<FPortalSector> FPortalSectors;
typedef TMap<FPortalID, FPortalSectors> FPortalMap;
TArray<FPortal *> glSectorPortals;
TArray<FGLLinePortal*> linePortalToGL;
TArray<FGLLinePortal> glLinePortals;
//==========================================================================
//
//
//
//==========================================================================
GLSectorStackPortal *FPortal::GetRenderState()
{
if (glportal == NULL) glportal = new GLSectorStackPortal(this);
return glportal;
}
//==========================================================================
//
// this is left as fixed_t because the nodes also are, it makes no sense
@ -119,7 +107,6 @@ struct FCoverageBuilder
//==========================================================================
//
//
//
//==========================================================================
FCoverageBuilder(subsector_t *sub)
@ -305,10 +292,16 @@ struct FCoverageBuilder
//==========================================================================
//
// Calculate portal coverage for a single subsector
// This data is used by the clipper to free up the ranges covered by a portal.
//
// This also gets called by the render hack code because ZDoom was really lax
// with its stacked sector things and allowed partial tagging of affected sectors
// Any such sector will only be found during rendering and must create its
// coverage info then.
//
//==========================================================================
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement)
void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement)
{
TArray<FCoverageVertex> shape;
double centerx=0, centery=0;
@ -332,7 +325,7 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, c
//==========================================================================
//
// portal initialization
//
//
//==========================================================================
@ -355,15 +348,20 @@ static void CollectPortalSectors(FPortalMap &collection)
}
}
void gl_InitPortals()
//==========================================================================
//
// group sector portals by displacement
// The renderer can handle such a group in one go to avoid multiple
// BSP traversals
//
//==========================================================================
static void GroupSectorPortals()
{
FPortalMap collection;
if (level.nodes.Size() == 0) return;
CollectPortalSectors(collection);
glSectorPortals.Clear();
level.portalGroups.Clear();
FPortalMap::Iterator it(collection);
FPortalMap::Pair *pair;
@ -378,14 +376,14 @@ void gl_InitPortals()
}
for (int i = 1; i <= 2; i <<= 1)
{
// add separate glSectorPortals for floor and ceiling.
// add separate portals for floor and ceiling.
if (planeflags & i)
{
FPortal *portal = new FPortal;
FSectorPortalGroup *portal = new FSectorPortalGroup;
portal->mDisplacement = pair->Key.mDisplacement;
portal->plane = (i == 1 ? sector_t::floor : sector_t::ceiling); /**/
portal->glportal = NULL;
glSectorPortals.Push(portal);
level.portalGroups.Push(portal);
for (unsigned j = 0; j < pair->Value.Size(); j++)
{
sector_t *sec = pair->Value[j].mSub;
@ -395,7 +393,7 @@ void gl_InitPortals()
for (int k = 0; k < sec->subsectorcount; k++)
{
subsector_t *sub = sec->subsectors[k];
gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement);
BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement);
}
sec->portals[plane] = portal;
}
@ -403,10 +401,18 @@ void gl_InitPortals()
}
}
}
}
// Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps)
glLinePortals.Clear();
linePortalToGL.Clear();
//==========================================================================
//
// Group the line portals
// Each group must be a continuous set of colinear linedefs with no gaps
//
//==========================================================================
static void GroupLinePortals()
{
level.linePortalSpans.Clear();
TArray<int> tempindex;
tempindex.Reserve(level.linePortals.Size());
@ -419,13 +425,13 @@ void gl_InitPortals()
if (tempindex[i] == -1)
{
tempindex[i] = glLinePortals.Size();
tempindex[i] = level.linePortalSpans.Size();
line_t *pSrcLine = level.linePortals[i].mOrigin;
line_t *pLine = level.linePortals[i].mDestination;
FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)];
FLinePortalSpan &glport = level.linePortalSpans[level.linePortalSpans.Reserve(1)];
glport.lines.Push(&level.linePortals[i]);
// We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time.
// We cannot do this grouping for non-linked portals because they can be changed at run time.
if (level.linePortals[i].mType == PORTT_LINKED && pLine != nullptr)
{
glport.v1 = pLine->v1;
@ -440,7 +446,7 @@ void gl_InitPortals()
{
line_t *pSrcLine2 = level.linePortals[j].mOrigin;
line_t *pLine2 = level.linePortals[j].mDestination;
// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.)
// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical portals aren't found here.)
unsigned srcang = pSrcLine->Delta().Angle().BAMs();
unsigned dstang = pLine->Delta().Angle().BAMs();
if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) ||
@ -465,30 +471,37 @@ void gl_InitPortals()
}
}
}
linePortalToGL.Resize(level.linePortals.Size());
// Final assignment can only be done when all allocations are finished. Otherwise the array may be moved.
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
linePortalToGL[i] = &glLinePortals[tempindex[i]];
/*
Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
int(level.linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.);
*/
level.linePortals[i].mGroup = &level.linePortalSpans[tempindex[i]];
}
}
void InitPortalGroups()
{
if (level.nodes.Size() == 0) return;
GroupSectorPortals();
GroupLinePortals();
}
CCMD(dumpportals)
{
for(unsigned i=0;i<glSectorPortals.Size(); i++)
for(unsigned i=0;i<level.portalGroups.Size(); i++)
{
double xdisp = glSectorPortals[i]->mDisplacement.X;
double ydisp = glSectorPortals[i]->mDisplacement.Y;
Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, glSectorPortals[i]->plane==0? "floor":"ceiling",
auto p = level.portalGroups[i];
double xdisp = p->mDisplacement.X;
double ydisp = p->mDisplacement.Y;
Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, p->plane==0? "floor":"ceiling",
xdisp, ydisp);
Printf(PRINT_LOG, "Coverage:\n");
for(auto &sub : level.subsectors)
{
FPortal *port = sub.render_sector->GetGLPortal(glSectorPortals[i]->plane);
if (port == glSectorPortals[i])
auto port = sub.render_sector->GetPortalGroup(p->plane);
if (port == p)
{
Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", sub.Index(), sub.render_sector->sectornum);
for(unsigned k = 0;k< sub.numlines; k++)
@ -496,7 +509,7 @@ CCMD(dumpportals)
Printf(PRINT_LOG, "(%.3f,%.3f), ", sub.firstline[k].v1->fX() + xdisp, sub.firstline[k].v1->fY() + ydisp);
}
Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n");
FPortalCoverage *cov = &sub.portalcoverage[glSectorPortals[i]->plane];
FPortalCoverage *cov = &sub.portalcoverage[p->plane];
for(int l = 0;l< cov->sscount; l++)
{
subsector_t *csub = &level.subsectors[cov->subsectors[l]];

View file

@ -48,7 +48,6 @@
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/utility/gl_clock.h"
#include "gl/gl_functions.h"
//==========================================================================
//
@ -568,8 +567,6 @@ void gl_PreprocessLevel()
}
delete[] checkmap;
gl_InitPortals();
if (GLRenderer != NULL)
{
GLRenderer->SetupLevel();
@ -582,53 +579,6 @@ void gl_PreprocessLevel()
//==========================================================================
//
// Cleans up all the GL data for the last level
//
//==========================================================================
void gl_CleanLevelData()
{
// Dynamic lights must be destroyed before the sector information here is deleted.
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
AActor * mo=it.Next();
while (mo)
{
AActor * next = it.Next();
mo->Destroy();
mo=next;
}
if (level.sides.Size() > 0 && level.sides[0].segs)
{
delete [] level.sides[0].segs;
level.sides[0].segs = NULL;
}
if (level.sectors.Size() > 0 && level.sectors[0].subsectors)
{
delete [] level.sectors[0].subsectors;
level.sectors[0].subsectors = nullptr;
}
for (auto &sub : level.subsectors)
{
for(int j=0;j<2;j++)
{
if (sub.portalcoverage[j].subsectors != NULL)
{
delete [] sub.portalcoverage[j].subsectors;
sub.portalcoverage[j].subsectors = NULL;
}
}
}
for(unsigned i=0;i<glSectorPortals.Size(); i++)
{
delete glSectorPortals[i];
}
glSectorPortals.Clear();
}
//==========================================================================
//
//

View file

@ -29,7 +29,6 @@
#include "c_dispatch.h"
#include "p_local.h"
#include "vectors.h"
#include "gl/gl_functions.h"
#include "g_level.h"
#include "actorinlines.h"
#include "a_dynlight.h"

View file

@ -5,7 +5,5 @@
class AActor;
void gl_PreprocessLevel();
void gl_CleanLevelData();
#endif

View file

@ -42,7 +42,6 @@
#include "r_utility.h"
#include "p_local.h"
#include "colormatcher.h"
#include "gl/gl_functions.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/system/gl_cvars.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -33,8 +33,6 @@
#include "m_png.h"
#include "m_crc32.h"
#include "w_wad.h"
//#include "gl/gl_intern.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "doomstat.h"

View file

@ -520,16 +520,16 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
(sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED;
if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub);
FPortal *portal;
FSectorPortalGroup *portal;
portal = fakesector->GetGLPortal(sector_t::ceiling);
portal = fakesector->GetPortalGroup(sector_t::ceiling);
if (portal != NULL)
{
GLSectorStackPortal *glportal = portal->GetRenderState();
glportal->AddSubsector(sub);
}
portal = fakesector->GetGLPortal(sector_t::floor);
portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != NULL)
{
GLSectorStackPortal *glportal = portal->GetRenderState();

View file

@ -87,7 +87,7 @@ bool GLPortal::inskybox;
UniqueList<GLSkyInfo> UniqueSkies;
UniqueList<GLHorizonInfo> UniqueHorizons;
UniqueList<secplane_t> UniquePlaneMirrors;
UniqueList<FGLLinePortal> UniqueLineToLines;
UniqueList<FLinePortalSpan> UniqueLineToLines;
//==========================================================================
//
@ -673,6 +673,22 @@ void GLSkyboxPortal::DrawContents()
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//==========================================================================
//
// Fixme: This needs abstraction.
//
//==========================================================================
GLSectorStackPortal *FSectorPortalGroup::GetRenderState()
{
if (glportal == NULL) glportal = new GLSectorStackPortal(this);
return glportal;
}
GLSectorStackPortal::~GLSectorStackPortal()
{
if (origin != NULL && origin->glportal == this)
@ -730,7 +746,7 @@ void GLSectorStackPortal::SetupCoverage()
//-----------------------------------------------------------------------------
void GLSectorStackPortal::DrawContents()
{
FPortal *portal = origin;
FSectorPortalGroup *portal = origin;
r_viewpoint.Pos += origin->mDisplacement;
r_viewpoint.ActorPos += origin->mDisplacement;

View file

@ -74,7 +74,7 @@ struct GLSkyInfo
extern UniqueList<GLSkyInfo> UniqueSkies;
extern UniqueList<GLHorizonInfo> UniqueHorizons;
extern UniqueList<secplane_t> UniquePlaneMirrors;
extern UniqueList<FGLLinePortal> UniqueLineToLines;
extern UniqueList<FLinePortalSpan> UniqueLineToLines;
struct GLEEHorizonPortal;
class GLSceneDrawer;
@ -198,7 +198,7 @@ struct GLLinePortal : public GLPortal
CalcDelta();
}
GLLinePortal(FGLLinePortal *line)
GLLinePortal(FLinePortalSpan *line)
{
if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr)
{
@ -258,7 +258,7 @@ public:
struct GLLineToLinePortal : public GLLinePortal
{
FGLLinePortal *glport;
FLinePortalSpan *glport;
protected:
virtual void DrawContents();
virtual void * GetSource() const { return glport; }
@ -268,7 +268,7 @@ protected:
public:
GLLineToLinePortal(FGLLinePortal *ll)
GLLineToLinePortal(FLinePortalSpan *ll)
: GLLinePortal(ll)
{
glport = ll;
@ -331,11 +331,11 @@ protected:
virtual void * GetSource() const { return origin; }
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.
virtual const char *GetName();
FPortal *origin;
FSectorPortalGroup *origin;
public:
GLSectorStackPortal(FPortal *pt)
GLSectorStackPortal(FSectorPortalGroup *pt)
{
origin=pt;
}

View file

@ -1034,7 +1034,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor)
sub->validcount=validcount;
// Has a sector stack or skybox itself!
if (sub->render_sector->GetGLPortal(sector_t::ceiling) != nullptr) return;
if (sub->render_sector->GetPortalGroup(sector_t::ceiling) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
@ -1078,7 +1078,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor)
sub->validcount=validcount;
// Has a sector stack or skybox itself!
if (sub->render_sector->GetGLPortal(sector_t::floor) != nullptr) return;
if (sub->render_sector->GetPortalGroup(sector_t::floor) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
@ -1125,7 +1125,7 @@ void FDrawInfo::ProcessSectorStacks()
for (i=0;i<CeilingStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(CeilingStacks[i], &fake, mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::ceiling);
auto portal = sec->GetPortalGroup(sector_t::ceiling);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
@ -1149,7 +1149,7 @@ void FDrawInfo::ProcessSectorStacks()
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
{
gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement);
BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement);
}
portal->GetRenderState()->AddSubsector(sub);
@ -1169,7 +1169,7 @@ void FDrawInfo::ProcessSectorStacks()
for (i=0;i<FloorStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(FloorStacks[i], &fake, mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::floor);
auto portal = sec->GetPortalGroup(sector_t::floor);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
@ -1194,7 +1194,7 @@ void FDrawInfo::ProcessSectorStacks()
if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
{
gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement);
BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement);
}
GLSectorStackPortal *glportal = portal->GetRenderState();

View file

@ -42,7 +42,6 @@
#include "po_man.h"
#include "r_utility.h"
#include "p_local.h"
#include "gl/gl_functions.h"
#include "serializer.h"
#include "g_levellocals.h"
#include "events.h"
@ -266,7 +265,7 @@ void GLSceneDrawer::CreateScene()
ProcessAll.Clock();
// clip the scene and fill the drawlists
for(unsigned i=0;i<glSectorPortals.Size(); i++) glSectorPortals[i]->glportal = NULL;
for(auto p : level.portalGroups) p->glportal = nullptr;
GLRenderer->gl_spriteindex=0;
Bsp.Clock();
GLRenderer->mVBO->Map();
@ -462,7 +461,7 @@ void GLSceneDrawer::RenderTranslucent()
//-----------------------------------------------------------------------------
//
// gl_drawscene - this function renders the scene from the current
// viewpoint, including mirrors and skyboxes and other glSectorPortals
// viewpoint, including mirrors and skyboxes and other portals
// It is assumed that the GLPortal::EndFrame returns with the
// stencil, z-buffer and the projection matrix intact!
//
@ -513,7 +512,7 @@ void GLSceneDrawer::DrawScene(int drawmode)
gl_RenderState.ApplyMatrices();
}
// Handle all glSectorPortals after rendering the opaque objects but before
// Handle all portals after rendering the opaque objects but before
// doing all translucent stuff
recursion++;
GLPortal::EndFrame();
@ -1041,7 +1040,6 @@ void FGLInterface::EndSerialize(FSerializer &arc)
if (arc.isReading())
{
// The portal data needs to be recreated after reading a savegame.
gl_InitPortals();
}
}
@ -1152,6 +1150,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, do
//
//
//===========================================================================
void gl_PreprocessLevel();
void FGLInterface::PreprocessLevel()
{
@ -1160,7 +1159,6 @@ void FGLInterface::PreprocessLevel()
void FGLInterface::CleanLevelData()
{
gl_CleanLevelData();
}
uint32_t FGLInterface::GetCaps()

View file

@ -60,7 +60,7 @@ public:
void DrawBlend(sector_t * viewsector);
void EndDrawScene(sector_t * viewsector);
void DrawEndScene2D(sector_t * viewsector);
void RenderActorsInPortal(FGLLinePortal *glport);
void RenderActorsInPortal(FLinePortalSpan *glport);
void CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector);

View file

@ -29,7 +29,6 @@
#include "doomdata.h"
#include "portal.h"
#include "g_levellocals.h"
#include "gl/gl_functions.h"
#include "gl/data/gl_data.h"
#include "gl/renderer/gl_lightdata.h"
@ -135,7 +134,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
case PORTS_PORTAL:
case PORTS_LINKEDPORTAL:
{
FPortal *glport = sector->GetGLPortal(plane);
FSectorPortalGroup *glport = sector->GetPortalGroup(plane);
if (glport != NULL)
{
if (sector->PortalBlocksView(plane)) return;
@ -298,8 +297,8 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex
int type = fs->GetPortalType(sector_t::ceiling);
if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{
FPortal *pfront = fs->GetGLPortal(sector_t::ceiling);
FPortal *pback = bs->GetGLPortal(sector_t::ceiling);
auto pfront = fs->GetPortalGroup(sector_t::ceiling);
auto pback = bs->GetPortalGroup(sector_t::ceiling);
if (pfront == NULL || fs->PortalBlocksView(sector_t::ceiling)) return;
if (pfront == pback && !bs->PortalBlocksView(sector_t::ceiling)) return;
}
@ -377,8 +376,8 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver
int type = fs->GetPortalType(sector_t::floor);
if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{
FPortal *pfront = fs->GetGLPortal(sector_t::floor);
FPortal *pback = bs->GetGLPortal(sector_t::floor);
auto pfront = fs->GetPortalGroup(sector_t::floor);
auto pback = bs->GetPortalGroup(sector_t::floor);
if (pfront == NULL || fs->PortalBlocksView(sector_t::floor)) return;
if (pfront == pback && !bs->PortalBlocksView(sector_t::floor)) return;
}

View file

@ -30,7 +30,6 @@
#include "p_effect.h"
#include "g_level.h"
#include "doomstat.h"
#include "gl/gl_functions.h"
#include "r_defs.h"
#include "r_sky.h"
#include "r_utility.h"
@ -1284,7 +1283,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
//
//==========================================================================
void GLSceneDrawer::RenderActorsInPortal(FGLLinePortal *glport)
void GLSceneDrawer::RenderActorsInPortal(FLinePortalSpan *glport)
{
TMap<AActor*, bool> processcheck;
if (glport->validcount == validcount) return; // only process once per frame

View file

@ -30,7 +30,6 @@
#include "p_local.h"
#include "p_effect.h"
#include "vectors.h"
#include "gl/gl_functions.h"
#include "g_level.h"
#include "g_levellocals.h"
#include "actorinlines.h"

View file

@ -23,7 +23,6 @@
#include "gl/system/gl_system.h"
#include "gl/gl_functions.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"

View file

@ -20,9 +20,9 @@ class FMaterial;
struct GLDrawList;
struct GLSkyInfo;
struct FTexCoordInfo;
struct FPortal;
struct FSectorPortalGroup;
struct FFlatVertex;
struct FGLLinePortal;
struct FLinePortalSpan;
class GLSceneDrawer;
enum
@ -171,9 +171,9 @@ public:
FSectorPortal *secportal; // sector portal (formerly skybox)
GLSkyInfo * sky; // for normal sky
GLHorizonInfo * horizon; // for horizon information
FPortal * portal; // stacked sector portals
FSectorPortalGroup * portal; // stacked sector portals
secplane_t * planemirror; // for plane mirrors
FGLLinePortal *lineportal; // line-to-line portals
FLinePortalSpan *lineportal; // line-to-line portals
};

View file

@ -179,7 +179,7 @@ void GLWall::PutPortal(int ptype)
line_t *otherside = lineportal->lines[0]->mDestination;
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
{
mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]);
mDrawer->RenderActorsInPortal(otherside->getPortal()->mGroup);
}
portal = new GLLineToLinePortal(lineportal);
}
@ -1562,7 +1562,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (seg->linedef->isVisualPortal())
{
lineportal = linePortalToGL[seg->linedef->portalindex];
lineportal = seg->linedef->getPortal()->mGroup;
ztop[0] = zceil[0];
ztop[1] = zceil[1];
zbottom[0] = zfloor[0];
@ -1669,7 +1669,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (isportal)
{
lineportal = linePortalToGL[seg->linedef->portalindex];
lineportal = seg->linedef->getPortal()->mGroup;
ztop[0] = bch1;
ztop[1] = bch2;
zbottom[0] = bfh1;

View file

@ -27,7 +27,6 @@
#include "g_levellocals.h"
#include "actor.h"
#include "actorinlines.h"
#include "gl/gl_functions.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"

View file

@ -23,7 +23,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -23,7 +23,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "w_wad.h"
#include "gl/system/gl_interface.h"

View file

@ -30,7 +30,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"

View file

@ -24,7 +24,6 @@
#include "files.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -45,7 +45,6 @@
#include "gl/data/gl_data.h"
#include "gl/textures/gl_hwtexture.h"
#include "gl/utility/gl_clock.h"
#include "gl/gl_functions.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl_debug.h"
#include "r_videoscale.h"

View file

@ -1024,6 +1024,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
}
}
AActor::RecreateAllAttachedLights();
InitPortalGroups();
Renderer->EndSerialize(arc);
}

View file

@ -111,6 +111,7 @@
#include "p_saveg.h"
#include "g_levellocals.h"
#include "c_dispatch.h"
#include "a_dynlight.h"
#ifndef NO_EDATA
#include "edata.h"
#endif
@ -3499,14 +3500,24 @@ static void P_PrecacheLevel()
extern polyblock_t **PolyBlockMap;
//===========================================================================
//==========================================================================
//
//
//
//===========================================================================
//==========================================================================
void P_FreeLevelData ()
{
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
auto mo = it.Next();
while (mo)
{
auto next = it.Next();
mo->Destroy();
mo = next;
}
// [ZZ] delete per-map event handlers
E_Shutdown(true);
MapThingsConverted.Clear();
@ -3531,14 +3542,26 @@ void P_FreeLevelData ()
level.killed_monsters = level.found_items = level.found_secrets =
wminfo.maxfrags = 0;
// delete allocated data in the level arrays.
if (level.sectors.Size() > 0)
{
delete[] level.sectors[0].e;
if (level.sectors[0].subsectors)
{
delete[] level.sectors[0].subsectors;
level.sectors[0].subsectors = nullptr;
}
}
for (auto &sub : level.subsectors)
{
if (sub.BSP != nullptr) delete sub.BSP;
}
if (level.sides.Size() > 0 && level.sides[0].segs)
{
delete[] level.sides[0].segs;
level.sides[0].segs = nullptr;
}
FBehavior::StaticUnloadModules ();
level.segs.Clear();

View file

@ -507,6 +507,8 @@ void P_ClearPortals()
level.linePortals.Clear();
level.linkedPortals.Clear();
level.sectorPortals.Resize(2);
level.PortalBlockmap.Clear();
// The first entry must always be the default skybox. This is what every sector gets by default.
memset(&level.sectorPortals[0], 0, sizeof(level.sectorPortals[0]));
level.sectorPortals[0].mType = PORTS_SKYVIEWPOINT;
@ -515,6 +517,25 @@ void P_ClearPortals()
memset(&level.sectorPortals[1], 0, sizeof(level.sectorPortals[0]));
level.sectorPortals[1].mType = PORTS_SKYVIEWPOINT;
level.sectorPortals[1].mFlags = PORTSF_SKYFLATONLY;
// also clear the render data
for (auto &sub : level.subsectors)
{
for (int j = 0; j<2; j++)
{
if (sub.portalcoverage[j].subsectors != nullptr)
{
delete[] sub.portalcoverage[j].subsectors;
sub.portalcoverage[j].subsectors = nullptr;
}
}
}
for (unsigned i = 0; i<level.portalGroups.Size(); i++)
{
delete level.portalGroups[i];
}
level.portalGroups.Clear();
level.linePortalSpans.Clear();
}
//============================================================================

View file

@ -173,6 +173,8 @@ enum
// All information about a line-to-line portal (all types)
//
//============================================================================
struct FLinePortalSpan;
struct vertex_t;
struct FLinePortal
{
@ -187,8 +189,18 @@ struct FLinePortal
double mSinRot;
double mCosRot;
portnode_t *lineportal_thinglist;
FLinePortalSpan *mGroup;
};
struct FLinePortalSpan
{
// defines the complete span of connected colinear line portals, if they are of type PORTT_LINKED.
vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2
TArray<FLinePortal *> lines;
int validcount = 0;
};
//============================================================================
//
// All information about a sector plane portal
@ -230,6 +242,24 @@ struct FSectorPortal
}
};
//============================================================================
//
// This groups all sector portals with identical offset.
//
//============================================================================
struct GLSectorStackPortal;
struct FSectorPortalGroup
{
DVector2 mDisplacement;
int plane;
GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal!
GLSectorStackPortal *GetRenderState();
};
//============================================================================
//
// Functions
@ -255,6 +285,7 @@ void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely);
void P_TranslatePortalAngle(line_t* src, DAngle& angle);
void P_TranslatePortalZ(line_t* src, double& vz);
DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy);
void InitPortalGroups();
#endif

View file

@ -49,7 +49,6 @@
#include "sdlglvideo.h"
#include "gl/system/gl_system.h"
#include "r_defs.h"
#include "gl/gl_functions.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -45,7 +45,7 @@
struct FLightNode;
struct FGLSection;
class FSerializer;
struct FPortal;
struct FSectorPortalGroup;
struct FSectorPortal;
struct FLinePortal;
struct seg_t;
@ -1075,7 +1075,7 @@ public:
int subsectorcount; // list of subsectors
double transdoorheight; // for transparent door hacks
subsector_t ** subsectors;
FPortal * portals[2]; // floor and ceiling portals
FSectorPortalGroup * portals[2]; // floor and ceiling portals
enum
{
@ -1089,7 +1089,7 @@ public:
float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; }
bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); }
FPortal *GetGLPortal(int plane) { return portals[plane]; }
FSectorPortalGroup *GetPortalGroup(int plane) { return portals[plane]; }
enum
{
@ -1418,6 +1418,8 @@ struct FPortalCoverage
int sscount;
};
void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement);
struct subsector_t
{
sector_t *sector;