diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index 413c85dc6a..0262f964b7 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -356,7 +356,7 @@ static void CollectPortalSectors(FPortalMap &collection) for (int j = 0; j < 2; 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) }; diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index 70ac86ec7e..04a19a7ed9 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -69,10 +69,12 @@ bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto // Mirrors and horizons always block the view //if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true; - // Lines with stacked sectors must never block! - - if (backsector->portals[sector_t::ceiling] != NULL || backsector->portals[sector_t::floor] != NULL || - frontsector->portals[sector_t::ceiling] != NULL || frontsector->portals[sector_t::floor] != NULL) + // Lines with portals must never block. + // Portals which require the sky flat are excluded here, because for them the special sky semantics apply. + if (!(frontsector->GetPortal(sector_t::ceiling)->mFlags & PORTSF_SKYFLATONLY) || + !(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; } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index bdb57813a6..3621973c93 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -491,8 +491,6 @@ void GLFlat::Process(sector_t * model, int whichplane, bool fog) if (!fog) { - if (plane.texture==skyflatnum) return; - gltexture=FMaterial::ValidateTexture(plane.texture, false, true); if (!gltexture) return; if (gltexture->tex->isFullbright()) @@ -558,6 +556,7 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside) void GLFlat::ProcessSector(sector_t * frontsector) { lightlist_t * light; + FSectorPortal *port; #ifdef _DEBUG if (frontsector->sectornum == gl_breaksec) @@ -589,50 +588,48 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = gl_ClampLight(frontsector->GetFloorLight()); 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); - } - alpha = frontsector->GetAlpha(sector_t::floor) / 65536.0f; - } - else - { - alpha = 1.f; + gl_drawinfo->AddFloorStack(sector); // stacked sector things require visplane merging. } + alpha = frontsector->GetAlpha(sector_t::floor) / 65536.0f; } else { alpha = 1.0f - frontsector->GetReflect(sector_t::floor); } - if (frontsector->VBOHeightcheck(sector_t::floor)) - { - vboindex = frontsector->vboindex[sector_t::floor]; - } - else - { - vboindex = -1; - } - ceiling = false; - renderflags = SSRF_RENDERFLOOR; - - if (x.ffloors.Size()) + if (alpha != 0.f && sector->GetTexture(sector_t::floor) != skyflatnum) { - light = P_GetPlaneLight(sector, &frontsector->floorplane, false); - if ((!(sector->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING) || light->lightsource == NULL) - && (light->p_lightlevel != &frontsector->lightlevel)) + if (frontsector->VBOHeightcheck(sector_t::floor)) { - lightlevel = gl_ClampLight(*light->p_lightlevel); + vboindex = frontsector->vboindex[sector_t::floor]; + } + else + { + vboindex = -1; } - Colormap.CopyFrom3DLight(light); + ceiling = false; + renderflags = SSRF_RENDERFLOOR; + + if (x.ffloors.Size()) + { + light = P_GetPlaneLight(sector, &frontsector->floorplane, false); + if ((!(sector->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING) || light->lightsource == NULL) + && (light->p_lightlevel != &frontsector->lightlevel)) + { + lightlevel = gl_ClampLight(*light->p_lightlevel); + } + + Colormap.CopyFrom3DLight(light); + } + renderstyle = STYLE_Translucent; + Process(frontsector, false, false); } - renderstyle = STYLE_Translucent; - if (alpha != 0.0f) Process(frontsector, false, false); } // @@ -650,51 +647,48 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = gl_ClampLight(frontsector->GetCeilingLight()); 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); - } - alpha = frontsector->GetAlpha(sector_t::ceiling) / 65536.0f; - } - else - { - alpha = 1.f; + gl_drawinfo->AddCeilingStack(sector); } + alpha = frontsector->GetAlpha(sector_t::ceiling) / 65536.0f; } else { alpha = 1.0f - frontsector->GetReflect(sector_t::ceiling); } - if (frontsector->VBOHeightcheck(sector_t::ceiling)) + if (alpha != 0.f && sector->GetTexture(sector_t::ceiling) != skyflatnum) { - vboindex = frontsector->vboindex[sector_t::ceiling]; - } - else - { - vboindex = -1; - } - - ceiling = true; - renderflags = SSRF_RENDERCEILING; - - if (x.ffloors.Size()) - { - light = P_GetPlaneLight(sector, §or->ceilingplane, true); - - if ((!(sector->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) - && (light->p_lightlevel != &frontsector->lightlevel)) + if (frontsector->VBOHeightcheck(sector_t::ceiling)) { - lightlevel = gl_ClampLight(*light->p_lightlevel); + vboindex = frontsector->vboindex[sector_t::ceiling]; } - Colormap.CopyFrom3DLight(light); + else + { + vboindex = -1; + } + + ceiling = true; + renderflags = SSRF_RENDERCEILING; + + if (x.ffloors.Size()) + { + light = P_GetPlaneLight(sector, §or->ceilingplane, true); + + if ((!(sector->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) + && (light->p_lightlevel != &frontsector->lightlevel)) + { + lightlevel = gl_ClampLight(*light->p_lightlevel); + } + Colormap.CopyFrom3DLight(light); + } + renderstyle = STYLE_Translucent; + Process(frontsector, true, false); } - renderstyle = STYLE_Translucent; - if (alpha != 0.0f) Process(frontsector, true, false); } // diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 3c2c661be6..6c2a055925 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -644,7 +644,8 @@ void GLSkyboxPortal::DrawContents() } skyboxrecursion++; - origin->flags |= MF_JUSTHIT; + AActor *origin = portal->mSkybox; + portal->mFlags |= PORTSF_INSKYBOX; extralight = 0; PlaneMirrorMode = 0; @@ -672,7 +673,7 @@ void GLSkyboxPortal::DrawContents() currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); GLRenderer->DrawScene(); - origin->flags &= ~MF_JUSTHIT; + portal->mFlags &= ~PORTSF_INSKYBOX; inskybox = false; gl_RenderState.SetDepthClamp(oldclamp); skyboxrecursion--; @@ -1180,7 +1181,7 @@ void GLHorizonPortal::DrawContents() void GLEEHorizonPortal::DrawContents() { PortalAll.Clock(); - sector_t *sector = origin->Sector; + sector_t *sector = portal->mOrigin; if (sector->GetTexture(sector_t::floor) == skyflatnum || sector->GetTexture(sector_t::ceiling) == skyflatnum) { @@ -1195,7 +1196,7 @@ void GLEEHorizonPortal::DrawContents() horz.plane.GetFromSector(sector, true); horz.lightlevel = gl_ClampLight(sector->GetCeilingLight()); horz.colormap = sector->ColorMap; - if (origin->special1 == SKYBOX_PLANE) + if (portal->mType == PORTS_PLANE) { horz.plane.Texheight = ViewPos.Z + fabs(horz.plane.Texheight); } @@ -1208,7 +1209,7 @@ void GLEEHorizonPortal::DrawContents() horz.plane.GetFromSector(sector, false); horz.lightlevel = gl_ClampLight(sector->GetFloorLight()); horz.colormap = sector->ColorMap; - if (origin->special1 == SKYBOX_PLANE) + if (portal->mType == PORTS_PLANE) { horz.plane.Texheight = ViewPos.Z - fabs(horz.plane.Texheight); } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index f62db377d5..8fe54c5b10 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -266,20 +266,20 @@ public: struct GLSkyboxPortal : public GLPortal { - AActor * origin; + FSectorPortal * portal; protected: virtual void DrawContents(); - virtual void * GetSource() const { return origin; } + virtual void * GetSource() const { return portal; } virtual bool IsSky() { return true; } virtual const char *GetName(); public: - GLSkyboxPortal(AActor * pt) + GLSkyboxPortal(FSectorPortal * pt) { - origin=pt; + portal=pt; } }; @@ -377,20 +377,20 @@ public: struct GLEEHorizonPortal : public GLPortal { - AActor * origin; + FSectorPortal * portal; protected: virtual void DrawContents(); - virtual void * GetSource() const { return origin; } + virtual void * GetSource() const { return portal; } virtual bool NeedDepthBuffer() { return false; } virtual bool NeedCap() { return false; } virtual const char *GetName(); public: - GLEEHorizonPortal(AActor *pt) + GLEEHorizonPortal(FSectorPortal *pt) { - origin=pt; + portal=pt; } }; diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index ab16f57abf..67ac94103a 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -134,44 +134,52 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor) void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) { int ptype = -1; - FPortal *portal = sector->portals[plane]; - if (portal != NULL) - { - if (sector->PortalBlocksView(plane)) return; - if (GLPortal::instack[1 - plane]) return; - ptype = PORTALTYPE_SECTORSTACK; - this->portal = portal; + 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 + else if (sportal != nullptr) { - ASkyViewpoint * skyboxx = sector->GetSkyBox(plane); - if (sector->GetTexture(plane) == skyflatnum || (skyboxx != NULL && skyboxx->bAlways)) + switch (sportal->mType) { - GLSkyInfo skyinfo; - - // JUSTHIT is used as an indicator that a skybox is in use. - // This is to avoid recursion - - if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT)) - { - ptype = PORTALTYPE_SKYBOX; - skybox = skyboxx; - } - else - { - skyinfo.init(sector->sky, Colormap.FadeColor); - ptype = PORTALTYPE_SKY; - sky = UniqueSkies.Get(&skyinfo); - } - } - else if (allowreflect && sector->GetReflect(plane) > 0) + case PORTS_STACKEDSECTORTHING: + case PORTS_PORTAL: + case PORTS_LINKEDPORTAL: { - if ((plane == sector_t::ceiling && ViewPos.Z > sector->ceilingplane.fD()) || - (plane == sector_t::floor && ViewPos.Z < -sector->floorplane.fD())) return; - ptype = PORTALTYPE_PLANEMIRROR; - planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane; + FPortal *glport = sector->portals[plane]; + if (glport != NULL) + { + if (sector->PortalBlocksView(plane)) return; + + if (GLPortal::instack[1 - plane]) return; + ptype = PORTALTYPE_SECTORSTACK; + portal = glport; + } + break; } + + case PORTS_SKYVIEWPOINT: + case PORTS_HORIZON: + case PORTS_PLANE: + ptype = PORTALTYPE_SKYBOX; + secportal = sportal; + break; + } + } + else if (allowreflect && sector->GetReflect(plane) > 0) + { + if ((plane == sector_t::ceiling && ViewPos.Z > sector->ceilingplane.fD()) || + (plane == sector_t::floor && ViewPos.Z < -sector->floorplane.fD())) return; + ptype = PORTALTYPE_PLANEMIRROR; + planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane; } if (ptype != -1) { @@ -188,17 +196,17 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) void GLWall::SkyLine(sector_t *fs, line_t *line) { - ASkyViewpoint * skyboxx = line->skybox; + FSectorPortal *secport = line->GetTransferredPortal(); GLSkyInfo skyinfo; int ptype; // JUSTHIT is used as an indicator that a skybox is in use. // 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; - skybox = skyboxx; + secportal = secport; } else { @@ -206,6 +214,10 @@ void GLWall::SkyLine(sector_t *fs, line_t *line) ptype = PORTALTYPE_SKY; sky = UniqueSkies.Get(&skyinfo); } + ztop[0] = zceil[0]; + ztop[1] = zceil[1]; + zbottom[0] = zfloor[0]; + zbottom[1] = zfloor[1]; PutPortal(ptype); } @@ -223,15 +235,6 @@ void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2) zbottom[1]=zceil[1]; 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[1]=zfloor[1]; 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 { 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 *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 { 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 *pback = bs->GetGLPortal(sector_t::floor); diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 637737971d..5d998342a5 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -149,7 +149,7 @@ public: union { // it's either one of them but never more! - AActor * skybox; // for skyboxes + FSectorPortal *secportal; // sector portal (formerly skybox) GLSkyInfo * sky; // for normal sky GLHorizonInfo * horizon; // for horizon information FPortal * portal; // stacked sector portals diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index b9dfc9ef45..aec87c8af9 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -174,12 +174,12 @@ void GLWall::PutPortal(int ptype) break; case PORTALTYPE_SKYBOX: - portal = GLPortal::FindPortal(skybox); + portal = GLPortal::FindPortal(secportal); if (!portal) { // either a regular skybox or an Eternity-style horizon - if (skybox->special1 != SKYBOX_SKYVIEWPOINT) portal = new GLEEHorizonPortal(skybox); - else portal = new GLSkyboxPortal(skybox); + if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(secportal); + else portal = new GLSkyboxPortal(secportal); } portal->AddLine(this); break; @@ -1479,7 +1479,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) zbottom[1] = zfloor[1]; 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 gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true); diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index dda47ef666..663ba6a677 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -415,7 +415,7 @@ void P_SerializeWorld (FArchive &arc) arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; arc << li->portalindex; - arc << li->skybox; // GZDoom addition. + arc << li->portaltransferred; // GZDoom addition. for (j = 0; j < 2; j++) { diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c4a121507c..9dad0253a1 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -975,14 +975,14 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo { if (lines[j].args[0] == 0) { - lines[j].skybox = origin; + lines[j].portaltransferred = pnum; } else { FLineIdIterator itr(lines[j].args[0]); while ((s = itr.Next()) >= 0) { - lines[s].skybox = origin; + lines[s].portaltransferred = pnum; } } } diff --git a/src/r_defs.h b/src/r_defs.h index ab42114659..6a69ee1d42 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -975,6 +975,7 @@ public: void ClearPortal(int plane) { Portals[plane] = 0; + portals[plane] = nullptr; } FSectorPortal *GetPortal(int plane) @@ -1152,7 +1153,6 @@ 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]; } - void ClearPortal(int plane) { portals[plane] = nullptr; SkyBoxes[plane] = nullptr; } enum { @@ -1404,7 +1404,7 @@ public: int validcount; // if == validcount, already checked int locknumber; // [Dusk] lock number for special unsigned portalindex; - TObjPtr skybox; + unsigned portaltransferred; DVector2 Delta() const { @@ -1421,6 +1421,11 @@ public: Alpha = FLOAT2FIXED(a); } + FSectorPortal *GetTransferredPortal() + { + return portaltransferred >= sectorPortals.Size() ? (FSectorPortal*)NULL : §orPortals[portaltransferred]; + } + FLinePortal *getPortal() const { return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex];