- GL handling of new portal data organization.

This also fixes some oversights with plane and horizon portals which were included in several checks.
This commit is contained in:
Christoph Oelckers 2016-04-20 20:08:53 +02:00
parent 9c6e7753d8
commit 1c7b512cc0
11 changed files with 147 additions and 138 deletions

View file

@ -356,7 +356,7 @@ static void CollectPortalSectors(FPortalMap &collection)
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
{ {
int ptype = sec->GetPortalType(j); int ptype = sec->GetPortalType(j);
if (ptype== SKYBOX_STACKEDSECTORTHING || ptype == SKYBOX_PORTAL || ptype == SKYBOX_LINKEDPORTAL) // only offset-displacing portal types if (ptype== PORTS_STACKEDSECTORTHING || ptype == PORTS_PORTAL || ptype == PORTS_LINKEDPORTAL) // only offset-displacing portal types
{ {
FPortalID id = { sec->GetPortalDisplacement(j) }; FPortalID id = { sec->GetPortalDisplacement(j) };

View file

@ -69,10 +69,12 @@ bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto
// Mirrors and horizons always block the view // Mirrors and horizons always block the view
//if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true; //if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true;
// Lines with stacked sectors must never block! // Lines with portals must never block.
// Portals which require the sky flat are excluded here, because for them the special sky semantics apply.
if (backsector->portals[sector_t::ceiling] != NULL || backsector->portals[sector_t::floor] != NULL || if (!(frontsector->GetPortal(sector_t::ceiling)->mFlags & PORTSF_SKYFLATONLY) ||
frontsector->portals[sector_t::ceiling] != NULL || frontsector->portals[sector_t::floor] != NULL) !(frontsector->GetPortal(sector_t::floor)->mFlags & PORTSF_SKYFLATONLY) ||
!(backsector->GetPortal(sector_t::ceiling)->mFlags & PORTSF_SKYFLATONLY) ||
!(backsector->GetPortal(sector_t::floor)->mFlags & PORTSF_SKYFLATONLY))
{ {
return false; return false;
} }

View file

@ -491,8 +491,6 @@ void GLFlat::Process(sector_t * model, int whichplane, bool fog)
if (!fog) if (!fog)
{ {
if (plane.texture==skyflatnum) return;
gltexture=FMaterial::ValidateTexture(plane.texture, false, true); gltexture=FMaterial::ValidateTexture(plane.texture, false, true);
if (!gltexture) return; if (!gltexture) return;
if (gltexture->tex->isFullbright()) if (gltexture->tex->isFullbright())
@ -558,6 +556,7 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
void GLFlat::ProcessSector(sector_t * frontsector) void GLFlat::ProcessSector(sector_t * frontsector)
{ {
lightlist_t * light; lightlist_t * light;
FSectorPortal *port;
#ifdef _DEBUG #ifdef _DEBUG
if (frontsector->sectornum == gl_breaksec) if (frontsector->sectornum == gl_breaksec)
@ -589,25 +588,22 @@ void GLFlat::ProcessSector(sector_t * frontsector)
lightlevel = gl_ClampLight(frontsector->GetFloorLight()); lightlevel = gl_ClampLight(frontsector->GetFloorLight());
Colormap = frontsector->ColorMap; Colormap = frontsector->ColorMap;
if ((stack = (frontsector->portals[sector_t::floor] != NULL))) port = frontsector->ValidatePortal(sector_t::floor);
if ((stack = (port != NULL)))
{ {
if (!frontsector->PortalBlocksView(sector_t::floor)) if (port->mType == PORTS_STACKEDSECTORTHING)
{ {
if (sector->SkyBoxes[sector_t::floor]->special1 == SKYBOX_STACKEDSECTORTHING) gl_drawinfo->AddFloorStack(sector); // stacked sector things require visplane merging.
{
gl_drawinfo->AddFloorStack(sector);
} }
alpha = frontsector->GetAlpha(sector_t::floor) / 65536.0f; alpha = frontsector->GetAlpha(sector_t::floor) / 65536.0f;
} }
else else
{
alpha = 1.f;
}
}
else
{ {
alpha = 1.0f - frontsector->GetReflect(sector_t::floor); alpha = 1.0f - frontsector->GetReflect(sector_t::floor);
} }
if (alpha != 0.f && sector->GetTexture(sector_t::floor) != skyflatnum)
{
if (frontsector->VBOHeightcheck(sector_t::floor)) if (frontsector->VBOHeightcheck(sector_t::floor))
{ {
vboindex = frontsector->vboindex[sector_t::floor]; vboindex = frontsector->vboindex[sector_t::floor];
@ -632,7 +628,8 @@ void GLFlat::ProcessSector(sector_t * frontsector)
Colormap.CopyFrom3DLight(light); Colormap.CopyFrom3DLight(light);
} }
renderstyle = STYLE_Translucent; renderstyle = STYLE_Translucent;
if (alpha != 0.0f) Process(frontsector, false, false); Process(frontsector, false, false);
}
} }
// //
@ -650,26 +647,22 @@ void GLFlat::ProcessSector(sector_t * frontsector)
lightlevel = gl_ClampLight(frontsector->GetCeilingLight()); lightlevel = gl_ClampLight(frontsector->GetCeilingLight());
Colormap = frontsector->ColorMap; Colormap = frontsector->ColorMap;
if ((stack = (frontsector->portals[sector_t::ceiling] != NULL))) port = frontsector->ValidatePortal(sector_t::ceiling);
if ((stack = (port != NULL)))
{ {
if (!frontsector->PortalBlocksView(sector_t::ceiling)) if (port->mType == PORTS_STACKEDSECTORTHING)
{
if (sector->SkyBoxes[sector_t::ceiling]->special1 == SKYBOX_STACKEDSECTORTHING)
{ {
gl_drawinfo->AddCeilingStack(sector); gl_drawinfo->AddCeilingStack(sector);
} }
alpha = frontsector->GetAlpha(sector_t::ceiling) / 65536.0f; alpha = frontsector->GetAlpha(sector_t::ceiling) / 65536.0f;
} }
else else
{
alpha = 1.f;
}
}
else
{ {
alpha = 1.0f - frontsector->GetReflect(sector_t::ceiling); alpha = 1.0f - frontsector->GetReflect(sector_t::ceiling);
} }
if (alpha != 0.f && sector->GetTexture(sector_t::ceiling) != skyflatnum)
{
if (frontsector->VBOHeightcheck(sector_t::ceiling)) if (frontsector->VBOHeightcheck(sector_t::ceiling))
{ {
vboindex = frontsector->vboindex[sector_t::ceiling]; vboindex = frontsector->vboindex[sector_t::ceiling];
@ -694,7 +687,8 @@ void GLFlat::ProcessSector(sector_t * frontsector)
Colormap.CopyFrom3DLight(light); Colormap.CopyFrom3DLight(light);
} }
renderstyle = STYLE_Translucent; renderstyle = STYLE_Translucent;
if (alpha != 0.0f) Process(frontsector, true, false); Process(frontsector, true, false);
}
} }
// //

View file

@ -644,7 +644,8 @@ void GLSkyboxPortal::DrawContents()
} }
skyboxrecursion++; skyboxrecursion++;
origin->flags |= MF_JUSTHIT; AActor *origin = portal->mSkybox;
portal->mFlags |= PORTSF_INSKYBOX;
extralight = 0; extralight = 0;
PlaneMirrorMode = 0; PlaneMirrorMode = 0;
@ -672,7 +673,7 @@ void GLSkyboxPortal::DrawContents()
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
GLRenderer->DrawScene(); GLRenderer->DrawScene();
origin->flags &= ~MF_JUSTHIT; portal->mFlags &= ~PORTSF_INSKYBOX;
inskybox = false; inskybox = false;
gl_RenderState.SetDepthClamp(oldclamp); gl_RenderState.SetDepthClamp(oldclamp);
skyboxrecursion--; skyboxrecursion--;
@ -1180,7 +1181,7 @@ void GLHorizonPortal::DrawContents()
void GLEEHorizonPortal::DrawContents() void GLEEHorizonPortal::DrawContents()
{ {
PortalAll.Clock(); PortalAll.Clock();
sector_t *sector = origin->Sector; sector_t *sector = portal->mOrigin;
if (sector->GetTexture(sector_t::floor) == skyflatnum || if (sector->GetTexture(sector_t::floor) == skyflatnum ||
sector->GetTexture(sector_t::ceiling) == skyflatnum) sector->GetTexture(sector_t::ceiling) == skyflatnum)
{ {
@ -1195,7 +1196,7 @@ void GLEEHorizonPortal::DrawContents()
horz.plane.GetFromSector(sector, true); horz.plane.GetFromSector(sector, true);
horz.lightlevel = gl_ClampLight(sector->GetCeilingLight()); horz.lightlevel = gl_ClampLight(sector->GetCeilingLight());
horz.colormap = sector->ColorMap; horz.colormap = sector->ColorMap;
if (origin->special1 == SKYBOX_PLANE) if (portal->mType == PORTS_PLANE)
{ {
horz.plane.Texheight = ViewPos.Z + fabs(horz.plane.Texheight); horz.plane.Texheight = ViewPos.Z + fabs(horz.plane.Texheight);
} }
@ -1208,7 +1209,7 @@ void GLEEHorizonPortal::DrawContents()
horz.plane.GetFromSector(sector, false); horz.plane.GetFromSector(sector, false);
horz.lightlevel = gl_ClampLight(sector->GetFloorLight()); horz.lightlevel = gl_ClampLight(sector->GetFloorLight());
horz.colormap = sector->ColorMap; horz.colormap = sector->ColorMap;
if (origin->special1 == SKYBOX_PLANE) if (portal->mType == PORTS_PLANE)
{ {
horz.plane.Texheight = ViewPos.Z - fabs(horz.plane.Texheight); horz.plane.Texheight = ViewPos.Z - fabs(horz.plane.Texheight);
} }

View file

@ -266,20 +266,20 @@ public:
struct GLSkyboxPortal : public GLPortal struct GLSkyboxPortal : public GLPortal
{ {
AActor * origin; FSectorPortal * portal;
protected: protected:
virtual void DrawContents(); virtual void DrawContents();
virtual void * GetSource() const { return origin; } virtual void * GetSource() const { return portal; }
virtual bool IsSky() { return true; } virtual bool IsSky() { return true; }
virtual const char *GetName(); virtual const char *GetName();
public: public:
GLSkyboxPortal(AActor * pt) GLSkyboxPortal(FSectorPortal * pt)
{ {
origin=pt; portal=pt;
} }
}; };
@ -377,20 +377,20 @@ public:
struct GLEEHorizonPortal : public GLPortal struct GLEEHorizonPortal : public GLPortal
{ {
AActor * origin; FSectorPortal * portal;
protected: protected:
virtual void DrawContents(); virtual void DrawContents();
virtual void * GetSource() const { return origin; } virtual void * GetSource() const { return portal; }
virtual bool NeedDepthBuffer() { return false; } virtual bool NeedDepthBuffer() { return false; }
virtual bool NeedCap() { return false; } virtual bool NeedCap() { return false; }
virtual const char *GetName(); virtual const char *GetName();
public: public:
GLEEHorizonPortal(AActor *pt) GLEEHorizonPortal(FSectorPortal *pt)
{ {
origin=pt; portal=pt;
} }
}; };

View file

@ -134,35 +134,44 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
{ {
int ptype = -1; int ptype = -1;
FPortal *portal = sector->portals[plane];
if (portal != NULL) FSectorPortal *sportal = sector->ValidatePortal(plane);
if (sportal != nullptr && sportal->mFlags & PORTSF_INSKYBOX) sportal = nullptr; // no recursions, delete it here to simplify the following code
// Either a regular sky or a skybox with skyboxes disabled
if ((sportal == nullptr && sector->GetTexture(plane) == skyflatnum) || (gl_noskyboxes && sportal != nullptr && sportal->mType == PORTS_SKYVIEWPOINT))
{
GLSkyInfo skyinfo;
skyinfo.init(sector->sky, Colormap.FadeColor);
ptype = PORTALTYPE_SKY;
sky = UniqueSkies.Get(&skyinfo);
}
else if (sportal != nullptr)
{
switch (sportal->mType)
{
case PORTS_STACKEDSECTORTHING:
case PORTS_PORTAL:
case PORTS_LINKEDPORTAL:
{
FPortal *glport = sector->portals[plane];
if (glport != NULL)
{ {
if (sector->PortalBlocksView(plane)) return; if (sector->PortalBlocksView(plane)) return;
if (GLPortal::instack[1 - plane]) return; if (GLPortal::instack[1 - plane]) return;
ptype = PORTALTYPE_SECTORSTACK; ptype = PORTALTYPE_SECTORSTACK;
this->portal = portal; portal = glport;
}
break;
} }
else
{
ASkyViewpoint * skyboxx = sector->GetSkyBox(plane);
if (sector->GetTexture(plane) == skyflatnum || (skyboxx != NULL && skyboxx->bAlways))
{
GLSkyInfo skyinfo;
// JUSTHIT is used as an indicator that a skybox is in use. case PORTS_SKYVIEWPOINT:
// This is to avoid recursion case PORTS_HORIZON:
case PORTS_PLANE:
if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT))
{
ptype = PORTALTYPE_SKYBOX; ptype = PORTALTYPE_SKYBOX;
skybox = skyboxx; secportal = sportal;
} break;
else
{
skyinfo.init(sector->sky, Colormap.FadeColor);
ptype = PORTALTYPE_SKY;
sky = UniqueSkies.Get(&skyinfo);
} }
} }
else if (allowreflect && sector->GetReflect(plane) > 0) else if (allowreflect && sector->GetReflect(plane) > 0)
@ -172,7 +181,6 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
ptype = PORTALTYPE_PLANEMIRROR; ptype = PORTALTYPE_PLANEMIRROR;
planemirror = plane == sector_t::ceiling ? &sector->ceilingplane : &sector->floorplane; planemirror = plane == sector_t::ceiling ? &sector->ceilingplane : &sector->floorplane;
} }
}
if (ptype != -1) if (ptype != -1)
{ {
PutPortal(ptype); PutPortal(ptype);
@ -188,17 +196,17 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
void GLWall::SkyLine(sector_t *fs, line_t *line) void GLWall::SkyLine(sector_t *fs, line_t *line)
{ {
ASkyViewpoint * skyboxx = line->skybox; FSectorPortal *secport = line->GetTransferredPortal();
GLSkyInfo skyinfo; GLSkyInfo skyinfo;
int ptype; int ptype;
// JUSTHIT is used as an indicator that a skybox is in use. // JUSTHIT is used as an indicator that a skybox is in use.
// This is to avoid recursion // This is to avoid recursion
if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT)) if (!gl_noskyboxes && secport && (secport->mSkybox == nullptr || !(secport->mFlags & PORTSF_INSKYBOX)))
{ {
ptype = PORTALTYPE_SKYBOX; ptype = PORTALTYPE_SKYBOX;
skybox = skyboxx; secportal = secport;
} }
else else
{ {
@ -206,6 +214,10 @@ void GLWall::SkyLine(sector_t *fs, line_t *line)
ptype = PORTALTYPE_SKY; ptype = PORTALTYPE_SKY;
sky = UniqueSkies.Get(&skyinfo); sky = UniqueSkies.Get(&skyinfo);
} }
ztop[0] = zceil[0];
ztop[1] = zceil[1];
zbottom[0] = zfloor[0];
zbottom[1] = zfloor[1];
PutPortal(ptype); PutPortal(ptype);
} }
@ -223,15 +235,6 @@ void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2)
zbottom[1]=zceil[1]; zbottom[1]=zceil[1];
SkyPlane(fs, sector_t::ceiling, true); SkyPlane(fs, sector_t::ceiling, true);
if (seg->linedef->skybox != NULL)
{
ztop[0] = zceil[0];
ztop[1] = zceil[1];
zbottom[0] = zfloor[0];
zbottom[1] = zfloor[1];
SkyLine(fs, seg->linedef);
}
ztop[0]=zfloor[0]; ztop[0]=zfloor[0];
ztop[1]=zfloor[1]; ztop[1]=zfloor[1];
zbottom[0]=zbottom[1]=-32768.0f; zbottom[0]=zbottom[1]=-32768.0f;
@ -312,7 +315,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex
else else
{ {
int type = fs->GetPortalType(sector_t::ceiling); int type = fs->GetPortalType(sector_t::ceiling);
if (type == SKYBOX_STACKEDSECTORTHING || type == SKYBOX_PORTAL || type == SKYBOX_LINKEDPORTAL) if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{ {
FPortal *pfront = fs->GetGLPortal(sector_t::ceiling); FPortal *pfront = fs->GetGLPortal(sector_t::ceiling);
FPortal *pback = bs->GetGLPortal(sector_t::ceiling); FPortal *pback = bs->GetGLPortal(sector_t::ceiling);
@ -391,7 +394,7 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver
else else
{ {
int type = fs->GetPortalType(sector_t::floor); int type = fs->GetPortalType(sector_t::floor);
if (type == SKYBOX_STACKEDSECTORTHING || type == SKYBOX_PORTAL || type == SKYBOX_LINKEDPORTAL) if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{ {
FPortal *pfront = fs->GetGLPortal(sector_t::floor); FPortal *pfront = fs->GetGLPortal(sector_t::floor);
FPortal *pback = bs->GetGLPortal(sector_t::floor); FPortal *pback = bs->GetGLPortal(sector_t::floor);

View file

@ -149,7 +149,7 @@ public:
union union
{ {
// it's either one of them but never more! // it's either one of them but never more!
AActor * skybox; // for skyboxes FSectorPortal *secportal; // sector portal (formerly skybox)
GLSkyInfo * sky; // for normal sky GLSkyInfo * sky; // for normal sky
GLHorizonInfo * horizon; // for horizon information GLHorizonInfo * horizon; // for horizon information
FPortal * portal; // stacked sector portals FPortal * portal; // stacked sector portals

View file

@ -174,12 +174,12 @@ void GLWall::PutPortal(int ptype)
break; break;
case PORTALTYPE_SKYBOX: case PORTALTYPE_SKYBOX:
portal = GLPortal::FindPortal(skybox); portal = GLPortal::FindPortal(secportal);
if (!portal) if (!portal)
{ {
// either a regular skybox or an Eternity-style horizon // either a regular skybox or an Eternity-style horizon
if (skybox->special1 != SKYBOX_SKYVIEWPOINT) portal = new GLEEHorizonPortal(skybox); if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(secportal);
else portal = new GLSkyboxPortal(skybox); else portal = new GLSkyboxPortal(secportal);
} }
portal->AddLine(this); portal->AddLine(this);
break; break;
@ -1479,7 +1479,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
zbottom[1] = zfloor[1]; zbottom[1] = zfloor[1];
PutPortal(PORTALTYPE_LINETOLINE); PutPortal(PORTALTYPE_LINETOLINE);
} }
else if (seg->linedef->skybox == NULL && !seg->linedef->isVisualPortal()) else if (seg->linedef->portaltransferred > 0)
{
SkyLine(frontsector, seg->linedef);
}
else
{ {
// normal texture // normal texture
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true); gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true);

View file

@ -415,7 +415,7 @@ void P_SerializeWorld (FArchive &arc)
arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];
arc << li->portalindex; arc << li->portalindex;
arc << li->skybox; // GZDoom addition. arc << li->portaltransferred; // GZDoom addition.
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{ {

View file

@ -975,14 +975,14 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
{ {
if (lines[j].args[0] == 0) if (lines[j].args[0] == 0)
{ {
lines[j].skybox = origin; lines[j].portaltransferred = pnum;
} }
else else
{ {
FLineIdIterator itr(lines[j].args[0]); FLineIdIterator itr(lines[j].args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
lines[s].skybox = origin; lines[s].portaltransferred = pnum;
} }
} }
} }

View file

@ -975,6 +975,7 @@ public:
void ClearPortal(int plane) void ClearPortal(int plane)
{ {
Portals[plane] = 0; Portals[plane] = 0;
portals[plane] = nullptr;
} }
FSectorPortal *GetPortal(int plane) FSectorPortal *GetPortal(int plane)
@ -1152,7 +1153,6 @@ public:
float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; } float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; }
bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); }
FPortal *GetGLPortal(int plane) { return portals[plane]; } FPortal *GetGLPortal(int plane) { return portals[plane]; }
void ClearPortal(int plane) { portals[plane] = nullptr; SkyBoxes[plane] = nullptr; }
enum enum
{ {
@ -1404,7 +1404,7 @@ public:
int validcount; // if == validcount, already checked int validcount; // if == validcount, already checked
int locknumber; // [Dusk] lock number for special int locknumber; // [Dusk] lock number for special
unsigned portalindex; unsigned portalindex;
TObjPtr<ASkyViewpoint> skybox; unsigned portaltransferred;
DVector2 Delta() const DVector2 Delta() const
{ {
@ -1421,6 +1421,11 @@ public:
Alpha = FLOAT2FIXED(a); Alpha = FLOAT2FIXED(a);
} }
FSectorPortal *GetTransferredPortal()
{
return portaltransferred >= sectorPortals.Size() ? (FSectorPortal*)NULL : &sectorPortals[portaltransferred];
}
FLinePortal *getPortal() const FLinePortal *getPortal() const
{ {
return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex]; return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex];