From 411eb579527f5ebc543ab11f24fea5383218bac5 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 13 Nov 2016 15:16:55 +0100 Subject: [PATCH] Fix rendering of masked walls --- src/r_poly.cpp | 36 +++++++++++++------- src/r_poly.h | 92 +++++++++++++++++++++++++++----------------------- 2 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/r_poly.cpp b/src/r_poly.cpp index a34853e2e..94e27cd43 100644 --- a/src/r_poly.cpp +++ b/src/r_poly.cpp @@ -50,7 +50,7 @@ void RenderPolyBsp::Render() SectorSpriteRanges.clear(); SectorSpriteRanges.resize(numsectors); SortedSprites.clear(); - SubsectoredSprites.clear(); + TranslucentObjects.clear(); PvsSectors.clear(); ScreenSprites.clear(); PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0); @@ -103,7 +103,7 @@ void RenderPolyBsp::Render() skydome.Render(worldToClip); - RenderSprites(); + RenderTranslucent(); RenderPlayerSprites(); DrawerCommandQueue::WaitForWorkers(); @@ -140,19 +140,24 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub) for (int i = 0; i < sprites.Count; i++) { AActor *thing = SortedSprites[sprites.Start + i].Thing; - SubsectoredSprites.push_back({ thing, sub, subsectorDepth }); + TranslucentObjects.push_back({ thing, sub, subsectorDepth }); } + + TranslucentObjects.insert(TranslucentObjects.end(), TempTranslucentWalls.begin(), TempTranslucentWalls.end()); + TempTranslucentWalls.clear(); } -void RenderPolyBsp::RenderSprites() +void RenderPolyBsp::RenderTranslucent() { - for (auto it = SubsectoredSprites.rbegin(); it != SubsectoredSprites.rend(); ++it) + for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it) { - auto &spr = *it; - if ((spr.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) - AddWallSprite(spr.thing, spr.sub, spr.subsectorDepth); + auto &obj = *it; + if (!obj.thing) + obj.wall.Render(worldToClip); + else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) + AddWallSprite(obj.thing, obj.sub, obj.subsectorDepth); else - AddSprite(spr.thing, spr.sub, spr.subsectorDepth); + AddSprite(obj.thing, obj.sub, obj.subsectorDepth); } } @@ -448,7 +453,7 @@ void RenderPolyBsp::AddLine(seg_t *line, sector_t *frontsector, uint32_t subsect wall.UnpeggedCeil = topceilz1; wall.Texpart = side_t::mid; wall.Masked = true; - wall.Render(worldToClip); + TempTranslucentWalls.push_back({ wall }); } } } @@ -1206,8 +1211,15 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) args.stencilwritevalue = 1; args.SetTexture(tex); - PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + if (!Masked) + { + PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + } + else + { + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); + } } FTexture *RenderPolyWall::GetTexture() diff --git a/src/r_poly.h b/src/r_poly.h index b2a024488..6c5051904 100644 --- a/src/r_poly.h +++ b/src/r_poly.h @@ -50,6 +50,42 @@ public: FDynamicColormap *Colormap = nullptr; }; +class RenderPolyWall +{ +public: + void Render(const TriMatrix &worldToClip); + + void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) + { + this->v1 = v1; + this->v2 = v2; + this->ceil1 = ceil1; + this->floor1 = floor1; + this->ceil2 = ceil2; + this->floor2 = floor2; + } + + DVector2 v1; + DVector2 v2; + double ceil1 = 0.0; + double floor1 = 0.0; + double ceil2 = 0.0; + double floor2 = 0.0; + + const seg_t *Line = nullptr; + side_t::ETexpart Texpart = side_t::mid; + double TopZ = 0.0; + double BottomZ = 0.0; + double UnpeggedCeil = 0.0; + FSWColormap *Colormap = nullptr; + bool Masked = false; + uint32_t SubsectorDepth = 0; + +private: + FTexture *GetTexture(); + int GetLightLevel(); +}; + // Used for sorting things by distance to the camera class PolySortedSprite { @@ -61,13 +97,17 @@ public: double DistanceSquared; }; -class PolySubsectoredSprite +class PolyTranslucentObject { public: - PolySubsectoredSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { } - AActor *thing; - subsector_t *sub; - uint32_t subsectorDepth; + PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { } + PolyTranslucentObject(RenderPolyWall wall) : wall(wall) { } + + AActor *thing = nullptr; + subsector_t *sub = nullptr; + uint32_t subsectorDepth = 0; + + RenderPolyWall wall; }; class SpriteRange @@ -116,7 +156,7 @@ private: void AddLine(seg_t *line, sector_t *frontsector, uint32_t subsectorDepth); TriVertex PlaneVertex(vertex_t *v1, sector_t *sector, double height); - void RenderSprites(); + void RenderTranslucent(); void AddSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth); void AddWallSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth); bool IsThingCulled(AActor *thing); @@ -147,7 +187,9 @@ private: std::vector SectorSpriteRanges; std::vector SortedSprites; - std::vector SubsectoredSprites; + std::vector TranslucentObjects; + + std::vector TempTranslucentWalls; std::vector ScreenSprites; @@ -166,42 +208,6 @@ private: PolySkyDome skydome; }; -class RenderPolyWall -{ -public: - void Render(const TriMatrix &worldToClip); - - void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) - { - this->v1 = v1; - this->v2 = v2; - this->ceil1 = ceil1; - this->floor1 = floor1; - this->ceil2 = ceil2; - this->floor2 = floor2; - } - - DVector2 v1; - DVector2 v2; - double ceil1 = 0.0; - double floor1 = 0.0; - double ceil2 = 0.0; - double floor2 = 0.0; - - const seg_t *Line = nullptr; - side_t::ETexpart Texpart = side_t::mid; - double TopZ = 0.0; - double BottomZ = 0.0; - double UnpeggedCeil = 0.0; - FSWColormap *Colormap = nullptr; - bool Masked = false; - uint32_t SubsectorDepth = 0; - -private: - FTexture *GetTexture(); - int GetLightLevel(); -}; - // Texture coordinates for a wall class PolyWallTextureCoords {