diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index f8d2ead8fc..883e5ffe58 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -85,7 +85,6 @@ extern bool NoInterpolateView; FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) { framebuffer = fb; - mClipPortal = nullptr; mCurrentPortal = nullptr; mMirrorCount = 0; mPlaneMirrorCount = 0; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index d3ac026716..7cdf3b01d2 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -87,7 +87,7 @@ class FGLRenderer public: OpenGLFrameBuffer *framebuffer; - GLPortal *mClipPortal; + //GLPortal *mClipPortal; GLPortal *mCurrentPortal; int mMirrorCount; int mPlaneMirrorCount; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 5e87acc62f..b5bc58e46d 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -31,10 +31,13 @@ #include "g_levellocals.h" #include "p_effect.h" #include "po_man.h" +#include "hwrenderer/scene/hw_fakeflat.h" +#include "hwrenderer/scene/hw_clipper.h" +#include "hwrenderer/scene/hw_drawstructs.h" +#include "hwrenderer/scene/hw_drawinfo.h" +#include "hwrenderer/scene/hw_portal.h" +#include "hwrenderer/utility/hw_clock.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_vertexbuffer.h" -#include "gl/scene/gl_scenedrawer.h" EXTERN_CVAR(Bool, gl_render_segs) @@ -42,11 +45,11 @@ CVAR(Bool, gl_render_things, true, 0) CVAR(Bool, gl_render_walls, true, 0) CVAR(Bool, gl_render_flats, true, 0) -void GLSceneDrawer::UnclipSubsector(subsector_t *sub) +void HWDrawInfo::UnclipSubsector(subsector_t *sub) { int count = sub->numlines; seg_t * seg = sub->firstline; - auto &clipper = *gl_drawinfo->mClipper; + auto &clipper = *mClipper; while (count--) { @@ -71,7 +74,7 @@ void GLSceneDrawer::UnclipSubsector(subsector_t *sub) // //========================================================================== -void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) +void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) { #ifdef _DEBUG if (seg->linedef->Index() == 38) @@ -80,16 +83,16 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) } #endif - sector_t * backsector = NULL; + sector_t * backsector = nullptr; sector_t bs; if (portalclip) { - int clipres = GLRenderer->mClipPortal->ClipSeg(seg); + int clipres = mClipPortal->ClipSeg(seg); if (clipres == PClip_InFront) return; } - auto &clipper = *gl_drawinfo->mClipper; + auto &clipper = *mClipper; angle_t startAngle = clipper.GetClipAngle(seg->v2); angle_t endAngle = clipper.GetClipAngle(seg->v1); @@ -99,7 +102,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) return; } - if (seg->sidedef == NULL) + if (seg->sidedef == nullptr) { if (!(currentsubsector->flags & SSECMF_DRAWN)) { @@ -142,9 +145,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 (gl_drawinfo->in_area == area_default) gl_drawinfo->in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); + if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); - backsector = hw_FakeFlat(seg->backsector, &bs, gl_drawinfo->in_area, true); + backsector = hw_FakeFlat(seg->backsector, &bs, in_area, true); if (hw_CheckClip(seg->sidedef, currentsector, backsector)) { @@ -170,7 +173,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) GLWall wall; wall.sub = currentsubsector; - wall.Process(gl_drawinfo, seg, currentsector, backsector); + wall.Process(this, seg, currentsector, backsector); rendered_lines++; SetupWall.Unclock(); @@ -187,7 +190,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) // //========================================================================== -void GLSceneDrawer::PolySubsector(subsector_t * sub) +void HWDrawInfo::PolySubsector(subsector_t * sub) { int count = sub->numlines; seg_t * line = sub->firstline; @@ -196,7 +199,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub) { if (line->linedef) { - AddLine (line, GLRenderer->mClipPortal != NULL); + AddLine (line, mClipPortal != nullptr); } line++; } @@ -211,7 +214,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub) // //========================================================================== -void GLSceneDrawer::RenderPolyBSPNode (void *node) +void HWDrawInfo::RenderPolyBSPNode (void *node) { while (!((size_t)node & 1)) // Keep going until found a subsector { @@ -227,7 +230,7 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) + if (!mClipper->CheckBox(bsp->bbox[side])) { return; } @@ -244,15 +247,15 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) // //========================================================================== -void GLSceneDrawer::AddPolyobjs(subsector_t *sub) +void HWDrawInfo::AddPolyobjs(subsector_t *sub) { - if (sub->BSP == NULL || sub->BSP->bDirty) + if (sub->BSP == nullptr || sub->BSP->bDirty) { sub->BuildPolyBSP(); for (unsigned i = 0; i < sub->BSP->Segs.Size(); i++) { sub->BSP->Segs[i].Subsector = sub; - sub->BSP->Segs[i].PartnerSeg = NULL; + sub->BSP->Segs[i].PartnerSeg = nullptr; } } if (sub->BSP->Nodes.Size() == 0) @@ -272,13 +275,13 @@ void GLSceneDrawer::AddPolyobjs(subsector_t *sub) // //========================================================================== -void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector) +void HWDrawInfo::AddLines(subsector_t * sub, sector_t * sector) { currentsector = sector; currentsubsector = sub; ClipWall.Clock(); - if (sub->polys != NULL) + if (sub->polys != nullptr) { AddPolyobjs(sub); } @@ -289,13 +292,13 @@ void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector) while (count--) { - if (seg->linedef == NULL) + if (seg->linedef == nullptr) { - if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, GLRenderer->mClipPortal != NULL); + if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, mClipPortal != nullptr); } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { - AddLine (seg, GLRenderer->mClipPortal != NULL); + AddLine (seg, mClipPortal != nullptr); } seg++; } @@ -316,7 +319,7 @@ inline bool PointOnLine(const DVector2 &pos, const line_t *line) return fabs(v) <= EQUAL_EPSILON; } -void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line) +void HWDrawInfo::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line) { currentsector = sector; currentsubsector = sub; @@ -327,7 +330,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, while (count--) { - if (seg->linedef != NULL && seg->PartnerSeg != NULL) + if (seg->linedef != nullptr && seg->PartnerSeg != nullptr) { if (PointOnLine(seg->v1->fPos(), line) && PointOnLine(seg->v2->fPos(), line)) AddLine(seg, false); @@ -344,7 +347,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, // //========================================================================== -void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) +void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector) { SetupSprite.Clock(); sector_t * sec=sub->sector; @@ -356,7 +359,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) thing->validcount = validcount; FIntCVar *cvar = thing->GetInfo()->distancecheck; - if (cvar != NULL && *cvar >= 0) + if (cvar != nullptr && *cvar >= 0) { double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared(); double check = (double)**cvar; @@ -366,10 +369,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 (gl_drawinfo->CurrentMapSections[thing->subsector->mapsection]) + if (CurrentMapSections[thing->subsector->mapsection]) { GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, false); + sprite.Process(this, thing, sector, in_area, false); } } @@ -377,7 +380,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) { AActor *thing = node->m_thing; FIntCVar *cvar = thing->GetInfo()->distancecheck; - if (cvar != NULL && *cvar >= 0) + if (cvar != nullptr && *cvar >= 0) { double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared(); double check = (double)**cvar; @@ -388,7 +391,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, true); + sprite.Process(this, thing, sector, in_area, true); } SetupSprite.Unclock(); } @@ -403,7 +406,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) // //========================================================================== -void GLSceneDrawer::DoSubsector(subsector_t * sub) +void HWDrawInfo::DoSubsector(subsector_t * sub) { unsigned int i; sector_t * sector; @@ -421,26 +424,26 @@ 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 (!gl_drawinfo->CurrentMapSections[sub->mapsection]) return; + if (!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) + if (ss_renderflags[sub->Index()] & SSRF_SEEN) { // This means that we have reached a subsector in a portal that has been marked 'seen' // from the other side of the portal. This means we must clear the clipper for the // range this subsector spans before going on. UnclipSubsector(sub); } - if (gl_drawinfo->mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. + if (mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. - fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); + fakesector=hw_FakeFlat(sector, &fake, in_area, false); - if (GLRenderer->mClipPortal) + if (mClipPortal) { - int clipres = GLRenderer->mClipPortal->ClipSubsector(sub); + int clipres = mClipPortal->ClipSubsector(sub); if (clipres == PClip_InFront) { - line_t *line = GLRenderer->mClipPortal->ClipLine(); + line_t *line = mClipPortal->ClipLine(); // The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts. if (line) AddSpecialPortalLines(sub, fakesector, line); return; @@ -460,14 +463,14 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) for (i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) { - if (GLRenderer->mClipPortal) + if (mClipPortal) { - int clipres = GLRenderer->mClipPortal->ClipPoint(Particles[i].Pos); + int clipres = mClipPortal->ClipPoint(Particles[i].Pos); if (clipres == PClip_InFront) continue; } GLSprite sprite; - sprite.ProcessParticle(gl_drawinfo, &Particles[i], fakesector); + sprite.ProcessParticle(this, &Particles[i], fakesector); } SetupSprite.Unclock(); } @@ -499,45 +502,43 @@ 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() || gl_drawinfo->in_area!=area_default) + if (!sector->GetHeightSec() || 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, gl_drawinfo->in_area, false); + fakesector = hw_FakeFlat(sector, &fake, in_area, false); } - uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum]; + uint8_t &srf = sectorrenderflags[sub->render_sector->sectornum]; if (!(srf & SSRF_PROCESSED)) { srf |= SSRF_PROCESSED; SetupFlat.Clock(); GLFlat flat; - flat.ProcessSector(gl_drawinfo, fakesector); + flat.ProcessSector(this, fakesector); SetupFlat.Unclock(); } // mark subsector as processed - but mark for rendering only if it has an actual area. - gl_drawinfo->ss_renderflags[sub->Index()] = + ss_renderflags[sub->Index()] = (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; - if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); + if (sub->hacked & 1) AddHackedSubsector(sub); FSectorPortalGroup *portal; portal = fakesector->GetPortalGroup(sector_t::ceiling); - if (portal != NULL) + if (portal != nullptr) { - GLSectorStackPortal *glportal = portal->GetRenderState(); - glportal->AddSubsector(sub); + portal->AddSubsector(sub); } portal = fakesector->GetPortalGroup(sector_t::floor); - if (portal != NULL) + if (portal != nullptr) { - GLSectorStackPortal *glportal = portal->GetRenderState(); - glportal->AddSubsector(sub); + portal->AddSubsector(sub); } } } @@ -556,7 +557,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // //========================================================================== -void GLSceneDrawer::RenderBSPNode (void *node) +void HWDrawInfo::RenderBSPNode (void *node) { if (level.nodes.Size() == 0) { @@ -577,9 +578,9 @@ void GLSceneDrawer::RenderBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) + if (!mClipper->CheckBox(bsp->bbox[side])) { - if (!(gl_drawinfo->no_renderflags[bsp->Index()] & SSRF_SEEN)) + if (!(no_renderflags[bsp->Index()] & SSRF_SEEN)) return; } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 93ce4f624b..b67f23fb4b 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -44,7 +44,7 @@ #include "gl/renderer/gl_quaddrawer.h" #include "gl/dynlights/gl_lightbuffer.h" -FDrawInfo * gl_drawinfo; +static FDrawInfo * gl_drawinfo; FDrawInfoList di_list; //========================================================================== @@ -504,12 +504,6 @@ void FDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *su portal->GetRenderState()->AddSubsector(sub); } -int FDrawInfo::ClipPoint(const DVector3 &pos) -{ - return GLRenderer->mClipPortal->ClipPoint(pos); -} - - std::pair FDrawInfo::AllocVertices(unsigned int count) { unsigned int index = -1; diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index a2bf52d1fb..4ab217babb 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -133,7 +133,6 @@ struct FDrawInfo : public HWDrawInfo // These two may be moved to the API independent part of the renderer later. void ProcessLowerMinisegs(TArray &lowersegs) override; void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override; - int ClipPoint(const DVector3 &pos) override; static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer); static void EndDrawInfo(); @@ -162,8 +161,6 @@ public: }; -extern FDrawInfo * gl_drawinfo; - void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending); #endif diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b90cd3dcd9..6a0d86132c 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -277,8 +277,6 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) PrevPortal = GLRenderer->mCurrentPortal; - PrevClipPortal = GLRenderer->mClipPortal; - GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves GLRenderer->mCurrentPortal = this; if (PrevPortal != NULL) PrevPortal->PushState(); @@ -324,8 +322,6 @@ void GLPortal::End(bool usestencil) Clocker c(PortalAll); if (PrevPortal != NULL) PrevPortal->PopState(); - GLRenderer->mCurrentPortal = PrevPortal; - GLRenderer->mClipPortal = PrevClipPortal; if (usestencil) { @@ -878,7 +874,7 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di) return; } - GLRenderer->mClipPortal = this; + di->mClipPortal = this; DAngle StartAngle = r_viewpoint.Angles.Yaw; DVector3 StartPos = r_viewpoint.Pos; @@ -979,7 +975,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) return; } - GLRenderer->mClipPortal = this; + di->mClipPortal = this; line_t *origin = glport->lines[0]->mOrigin; P_TranslatePortalXY(origin, r_viewpoint.Pos.X, r_viewpoint.Pos.Y); @@ -1251,3 +1247,9 @@ const char *GLLineToLinePortal::GetName() { return "LineToLine"; } const char *GLHorizonPortal::GetName() { return "Horizon"; } const char *GLEEHorizonPortal::GetName() { return "EEHorizon"; } +// This needs to remain on the renderer side until the portal interface can be abstracted. +void FSectorPortalGroup::AddSubsector(subsector_t *sub) +{ + GLSectorStackPortal *glportal = GetRenderState(); + glportal->AddSubsector(sub); +} diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 8b4a87f15c..5f646f41c2 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -49,7 +49,7 @@ extern UniqueList UniquePlaneMirrors; struct GLEEHorizonPortal; class GLSceneDrawer; -class GLPortal +class GLPortal : public IPortal { static TArray portals; static int recursion; @@ -77,7 +77,6 @@ private: AActor * savedviewactor; ActorRenderFlags savedvisibility; GLPortal *PrevPortal; - GLPortal *PrevClipPortal; TArray mPrimIndices; protected: @@ -127,10 +126,6 @@ public: static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); } - virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } - virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } - virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } - virtual line_t *ClipLine() { return NULL; } virtual void RenderAttached(FDrawInfo *di) {} static void BeginScene(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 78da1e5aa9..422bb58a6b 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -228,16 +228,18 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) GLRenderer->mVBO->Map(); GLRenderer->mLights->Begin(); - SetView(); + // Give the DrawInfo the viewpoint in fixed point because that's what the nodes are. + di->viewx = FLOAT2FIXED(r_viewpoint.Pos.X); + di->viewy = FLOAT2FIXED(r_viewpoint.Pos.Y); + validcount++; // used for processing sidedefs only once by the renderer. - di->clipPortal = !!GLRenderer->mClipPortal; di->mAngles = GLRenderer->mAngles; di->mViewVector = GLRenderer->mViewVector; di->mViewActor = GLRenderer->mViewActor; di->mShadowMap = &GLRenderer->mShadowMap; - RenderBSPNode (level.HeadNode()); + di->RenderBSPNode (level.HeadNode()); di->PreparePlayerSprites(r_viewpoint.sector, di->in_area); // Process all the sprites on the current portal's back side which touch the portal. @@ -453,7 +455,6 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode) { CreateScene(di); } - GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. RenderScene(di, recursion); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index e6c30239bd..d075e14183 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -13,26 +13,10 @@ struct HUDSprite; class GLSceneDrawer { - fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. - - subsector_t *currentsubsector; // used by the line processing code. - sector_t *currentsector; - TMap weapondynlightindex; void RenderMultipassStuff(FDrawInfo *di); - void UnclipSubsector(subsector_t *sub); - void AddLine (seg_t *seg, bool portalclip); - void PolySubsector(subsector_t * sub); - void RenderPolyBSPNode (void *node); - void AddPolyobjs(subsector_t *sub); - void AddLines(subsector_t * sub, sector_t * sector); - void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line); - void RenderThings(subsector_t * sub, sector_t * sector); - void DoSubsector(subsector_t * sub); - void RenderBSPNode(void *node); - void RenderScene(FDrawInfo *di, int recursion); void RenderTranslucent(FDrawInfo *di); @@ -64,12 +48,6 @@ public: sector_t *RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void SetView() - { - viewx = FLOAT2FIXED(r_viewpoint.Pos.X); - viewy = FLOAT2FIXED(r_viewpoint.Pos.Y); - } - void SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon = false) { gl_SetColor(light, rellight, FixedColormap != CM_DEFAULT, cm, alpha, weapon); diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 369bfe3992..ad34a4c529 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -15,6 +15,7 @@ struct particle_t; struct FDynLightData; struct HUDSprite; class Clipper; +class IPortal; //========================================================================== // @@ -79,7 +80,7 @@ struct HWDrawInfo int FixedColormap; std::atomic spriteindex; - bool clipPortal; + IPortal *mClipPortal; FRotator mAngles; FVector2 mViewVector; AActor *mViewActor; @@ -108,15 +109,31 @@ struct HWDrawInfo 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; + fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. + private: // For ProcessLowerMiniseg bool inview; subsector_t * viewsubsector; TArray lowersegs; - + + subsector_t *currentsubsector; // used by the line processing code. + sector_t *currentsector; + sector_t fakesec; // this is a struct member because it gets used in recursively called functions so it cannot be put on the stack. + + void UnclipSubsector(subsector_t *sub); + void AddLine(seg_t *seg, bool portalclip); + void PolySubsector(subsector_t * sub); + void RenderPolyBSPNode(void *node); + void AddPolyobjs(subsector_t *sub); + void AddLines(subsector_t * sub, sector_t * sector); + void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line); + void RenderThings(subsector_t * sub, sector_t * sector); + void DoSubsector(subsector_t * sub); public: + void RenderBSPNode(void *node); void ClearBuffers(); void SetViewArea(); @@ -175,8 +192,5 @@ public: virtual GLDecal *AddDecal(bool onmirror) = 0; virtual std::pair AllocVertices(unsigned int count) = 0; - virtual int ClipPoint(const DVector3 &pos) = 0; - - }; diff --git a/src/hwrenderer/scene/hw_portal.h b/src/hwrenderer/scene/hw_portal.h index 3037ed8c18..2347be86df 100644 --- a/src/hwrenderer/scene/hw_portal.h +++ b/src/hwrenderer/scene/hw_portal.h @@ -1,5 +1,6 @@ #pragma once +#include "hw_drawinfo.h" #include "hwrenderer/textures/hw_material.h" struct GLSkyInfo @@ -32,3 +33,12 @@ struct GLHorizonInfo PalEntry specialcolor; }; +class IPortal +{ +public: + virtual ~IPortal(); + virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } + virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } + virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } + virtual line_t *ClipLine() { return nullptr; } +}; diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 89352007cf..d92951aa9a 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -82,6 +82,8 @@ void HWDrawInfo::ClearBuffers() 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])); + + mClipPortal = nullptr; } //========================================================================== diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 6814d1760f..d5c0ea99e2 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -45,6 +45,7 @@ #include "hwrenderer/scene/hw_drawstructs.h" #include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_fakeflat.h" +#include "hwrenderer/scene/hw_portal.h" #include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_lighting.h" @@ -471,9 +472,9 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again. } - if (thruportal != 2 && di->clipPortal) + if (thruportal != 2 && di->mClipPortal != nullptr) { - int clipres = di->ClipPoint(thingpos); + int clipres = di->mClipPortal->ClipPoint(thingpos); if (clipres == PClip_InFront) return; } // disabled because almost none of the actual game code is even remotely prepared for this. If desired, use the INTERPOLATE flag. diff --git a/src/portal.h b/src/portal.h index f194c3886e..343e09b29e 100644 --- a/src/portal.h +++ b/src/portal.h @@ -7,6 +7,7 @@ struct FPortalGroupArray; struct portnode_t; +struct subsector_t; //============================================================================ // // This table holds the offsets for the different parts of a map @@ -256,6 +257,8 @@ struct FSectorPortalGroup GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! GLSectorStackPortal *GetRenderState(); + + void AddSubsector(subsector_t *sub); };