Fix rendering of masked walls

This commit is contained in:
Magnus Norddahl 2016-11-13 15:16:55 +01:00
parent 470046ec5a
commit 411eb57952
2 changed files with 73 additions and 55 deletions

View file

@ -50,7 +50,7 @@ void RenderPolyBsp::Render()
SectorSpriteRanges.clear(); SectorSpriteRanges.clear();
SectorSpriteRanges.resize(numsectors); SectorSpriteRanges.resize(numsectors);
SortedSprites.clear(); SortedSprites.clear();
SubsectoredSprites.clear(); TranslucentObjects.clear();
PvsSectors.clear(); PvsSectors.clear();
ScreenSprites.clear(); ScreenSprites.clear();
PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0); PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0);
@ -103,7 +103,7 @@ void RenderPolyBsp::Render()
skydome.Render(worldToClip); skydome.Render(worldToClip);
RenderSprites(); RenderTranslucent();
RenderPlayerSprites(); RenderPlayerSprites();
DrawerCommandQueue::WaitForWorkers(); DrawerCommandQueue::WaitForWorkers();
@ -140,19 +140,24 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub)
for (int i = 0; i < sprites.Count; i++) for (int i = 0; i < sprites.Count; i++)
{ {
AActor *thing = SortedSprites[sprites.Start + i].Thing; AActor *thing = SortedSprites[sprites.Start + i].Thing;
SubsectoredSprites.push_back({ thing, sub, subsectorDepth }); TranslucentObjects.push_back({ thing, sub, subsectorDepth });
}
} }
void RenderPolyBsp::RenderSprites() TranslucentObjects.insert(TranslucentObjects.end(), TempTranslucentWalls.begin(), TempTranslucentWalls.end());
TempTranslucentWalls.clear();
}
void RenderPolyBsp::RenderTranslucent()
{ {
for (auto it = SubsectoredSprites.rbegin(); it != SubsectoredSprites.rend(); ++it) for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
{ {
auto &spr = *it; auto &obj = *it;
if ((spr.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) if (!obj.thing)
AddWallSprite(spr.thing, spr.sub, spr.subsectorDepth); obj.wall.Render(worldToClip);
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
AddWallSprite(obj.thing, obj.sub, obj.subsectorDepth);
else 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.UnpeggedCeil = topceilz1;
wall.Texpart = side_t::mid; wall.Texpart = side_t::mid;
wall.Masked = true; wall.Masked = true;
wall.Render(worldToClip); TempTranslucentWalls.push_back({ wall });
} }
} }
} }
@ -1206,9 +1211,16 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.SetTexture(tex); args.SetTexture(tex);
if (!Masked)
{
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); PolyTriangleDrawer::draw(args, TriDrawVariant::Draw);
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
} }
else
{
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector);
}
}
FTexture *RenderPolyWall::GetTexture() FTexture *RenderPolyWall::GetTexture()
{ {

View file

@ -50,6 +50,42 @@ public:
FDynamicColormap *Colormap = nullptr; 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 // Used for sorting things by distance to the camera
class PolySortedSprite class PolySortedSprite
{ {
@ -61,13 +97,17 @@ public:
double DistanceSquared; double DistanceSquared;
}; };
class PolySubsectoredSprite class PolyTranslucentObject
{ {
public: public:
PolySubsectoredSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { } PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { }
AActor *thing; PolyTranslucentObject(RenderPolyWall wall) : wall(wall) { }
subsector_t *sub;
uint32_t subsectorDepth; AActor *thing = nullptr;
subsector_t *sub = nullptr;
uint32_t subsectorDepth = 0;
RenderPolyWall wall;
}; };
class SpriteRange class SpriteRange
@ -116,7 +156,7 @@ private:
void AddLine(seg_t *line, sector_t *frontsector, uint32_t subsectorDepth); void AddLine(seg_t *line, sector_t *frontsector, uint32_t subsectorDepth);
TriVertex PlaneVertex(vertex_t *v1, sector_t *sector, double height); 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 AddSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth);
void AddWallSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth); void AddWallSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth);
bool IsThingCulled(AActor *thing); bool IsThingCulled(AActor *thing);
@ -147,7 +187,9 @@ private:
std::vector<SpriteRange> SectorSpriteRanges; std::vector<SpriteRange> SectorSpriteRanges;
std::vector<PolySortedSprite> SortedSprites; std::vector<PolySortedSprite> SortedSprites;
std::vector<PolySubsectoredSprite> SubsectoredSprites; std::vector<PolyTranslucentObject> TranslucentObjects;
std::vector<PolyTranslucentObject> TempTranslucentWalls;
std::vector<PolyScreenSprite> ScreenSprites; std::vector<PolyScreenSprite> ScreenSprites;
@ -166,42 +208,6 @@ private:
PolySkyDome skydome; 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 // Texture coordinates for a wall
class PolyWallTextureCoords class PolyWallTextureCoords
{ {