Refactored the render hack storage so that it can be decoupled from the regular GLFlat render items.

Having these in there makes it impossible to change render techniques so these are better done as separate items.
This commit is contained in:
Christoph Oelckers 2018-11-06 18:20:59 +01:00
parent aee47d23bd
commit a6e77ae094
5 changed files with 174 additions and 182 deletions

View file

@ -56,18 +56,6 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
//
//==========================================================================
template<class T>
inline void DeleteLinkedList(T *node)
{
while (node)
{
auto n = node;
node = node->next;
delete n;
}
}
class FDrawInfoList
{
public:
@ -188,17 +176,10 @@ HWDrawInfo *HWDrawInfo::EndDrawInfo()
void HWDrawInfo::ClearBuffers()
{
for (auto node : otherfloorplanes) DeleteLinkedList(node);
otherfloorplanes.Clear();
for (auto node : otherceilingplanes) DeleteLinkedList(node);
otherceilingplanes.Clear();
for (auto node : floodfloorsegs) DeleteLinkedList(node);
floodfloorsegs.Clear();
for (auto node : floodceilingsegs) DeleteLinkedList(node);
floodceilingsegs.Clear();
otherFloorPlanes.Clear();
otherCeilingPlanes.Clear();
floodFloorSegs.Clear();
floodCeilingSegs.Clear();
// clear all the lists that might not have been cleared already
MissingUpperTextures.Clear();

View file

@ -68,6 +68,8 @@ enum SectorRenderFlags
SSRF_RENDERALL = 7,
SSRF_PROCESSED = 8,
SSRF_SEEN = 16,
SSRF_PLANEHACK = 32,
SSRF_FLOODHACK = 64
};
enum EPortalClip
@ -160,10 +162,10 @@ struct HWDrawInfo
TArray<SubsectorHackInfo> SubsectorHacks;
TArray<gl_subsectorrendernode*> otherfloorplanes;
TArray<gl_subsectorrendernode*> otherceilingplanes;
TArray<gl_floodrendernode*> floodfloorsegs;
TArray<gl_floodrendernode*> floodceilingsegs;
TMap<int, gl_subsectorrendernode*> otherFloorPlanes;
TMap<int, gl_subsectorrendernode*> otherCeilingPlanes;
TMap<int, gl_floodrendernode*> floodFloorSegs;
TMap<int, gl_floodrendernode*> floodCeilingSegs;
TArray<sector_t *> CeilingStacks;
TArray<sector_t *> FloorStacks;
@ -212,32 +214,6 @@ private:
void DrawPSprite(HUDSprite *huds, FRenderState &state);
public:
gl_subsectorrendernode * GetOtherFloorPlanes(unsigned int sector)
{
if (sector<otherfloorplanes.Size()) return otherfloorplanes[sector];
else return nullptr;
}
gl_subsectorrendernode * GetOtherCeilingPlanes(unsigned int sector)
{
if (sector<otherceilingplanes.Size()) return otherceilingplanes[sector];
else return nullptr;
}
gl_floodrendernode * GetFloodFloorSegs(unsigned int sector)
{
if (sector<floodfloorsegs.Size()) return floodfloorsegs[sector];
else return nullptr;
}
gl_floodrendernode * GetFloodCeilingSegs(unsigned int sector)
{
if (sector<floodceilingsegs.Size()) return floodceilingsegs[sector];
else return nullptr;
}
void SetCameraPos(const DVector3 &pos)
{
VPUniforms.mCameraPos = { (float)pos.X, (float)pos.Z, (float)pos.Y, 0.f };

View file

@ -308,6 +308,7 @@ public:
bool stack;
bool ceiling;
uint8_t renderflags;
uint8_t hacktype;
int iboindex;
//int vboheight;
@ -319,10 +320,13 @@ public:
void PutFlat(HWDrawInfo *di, bool fog = false);
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
void ProcessSector(HWDrawInfo *di, sector_t * frontsector);
void ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which = SSRF_RENDERALL);
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent);
void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state);
void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state);
};
//==========================================================================

View file

@ -192,76 +192,110 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
state.DrawIndexed(DT_Triangles, iboindex + section->vertexindex, section->vertexcount);
flatvertices += section->vertexcount;
flatprimitives++;
#if 0
//Temporarily disabled until the render hack code can be redone and refactored into its own draw elements
if (!(renderflags&SSRF_RENDER3DPLANES))
{
// Draw the subsectors assigned to it due to missing textures
gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR) ?
di->GetOtherFloorPlanes(sector->sectornum) :
di->GetOtherCeilingPlanes(sector->sectornum);
while (node)
{
state.SetLightIndex(node->lightindex);
auto num = node->sub->numlines;
flatvertices += num;
flatprimitives++;
state.Draw(DT_TriangleFan,node->vertexindex, num);
node = node->next;
}
// Flood gaps with the back side's ceiling/floor texture
// This requires a stencil because the projected plane interferes with
// the depth buffer
gl_floodrendernode * fnode = (renderflags&SSRF_RENDERFLOOR) ?
di->GetFloodFloorSegs(sector->sectornum) :
di->GetFloodCeilingSegs(sector->sectornum);
state.SetLightIndex(dynlightindex);
while (fnode)
{
flatvertices += 12;
flatprimitives += 3;
// Push bleeding floor/ceiling textures back a little in the z-buffer
// so they don't interfere with overlapping mid textures.
state.SetDepthBias(1, 128);
// Create stencil
state.SetEffect(EFF_STENCIL);
state.EnableTexture(false);
state.SetStencil(0, SOP_Increment, SF_ColorMaskOff);
state.Draw(DT_TriangleFan,fnode->vertexindex, 4);
// Draw projected plane into stencil
state.EnableTexture(true);
state.SetEffect(EFF_NONE);
state.SetStencil(1, SOP_Keep, SF_DepthMaskOff);
state.EnableDepthTest(false);
state.Draw(DT_TriangleFan,fnode->vertexindex + 4, 4);
// clear stencil
state.SetEffect(EFF_STENCIL);
state.EnableTexture(false);
state.SetStencil(1, SOP_Decrement, SF_ColorMaskOff | SF_DepthMaskOff);
state.Draw(DT_TriangleFan,fnode->vertexindex, 4);
// restore old stencil op.
state.EnableTexture(true);
state.EnableDepthTest(true);
state.SetEffect(EFF_NONE);
state.SetDepthBias(0, 0);
state.SetStencil(0, SOP_Keep, SF_AllOn);
fnode = fnode->next;
}
}
#endif
}
//==========================================================================
//
// Drawer for render hacks
//
//==========================================================================
void GLFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state)
{
state.SetMaterial(gltexture, CLAMP_XY, 0, -1);
// Draw the subsectors assigned to it due to missing textures
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
di->otherFloorPlanes.CheckKey(sector->sectornum) : di->otherCeilingPlanes.CheckKey(sector->sectornum);
if (!pNode) return;
auto node = *pNode;
while (node)
{
state.SetLightIndex(node->lightindex);
auto num = node->sub->numlines;
flatvertices += num;
flatprimitives++;
state.Draw(DT_TriangleFan,node->vertexindex, num);
node = node->next;
}
}
//==========================================================================
//
// Drawer for render hacks
//
//==========================================================================
void GLFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state)
{
// Flood gaps with the back side's ceiling/floor texture
// This requires a stencil because the projected plane interferes with
// the depth buffer
state.SetMaterial(gltexture, CLAMP_XY, 0, -1);
// Draw the subsectors assigned to it due to missing textures
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
di->floodFloorSegs.CheckKey(sector->sectornum) : di->floodCeilingSegs.CheckKey(sector->sectornum);
if (!pNode) return;
auto node = *pNode;
while (node)
{
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
di->floodFloorSegs.CheckKey(sector->sectornum) : di->floodCeilingSegs.CheckKey(sector->sectornum);
if (!pNode) return;
auto fnode = *pNode;
state.SetLightIndex(-1);
while (fnode)
{
flatvertices += 12;
flatprimitives += 3;
// Push bleeding floor/ceiling textures back a little in the z-buffer
// so they don't interfere with overlapping mid textures.
state.SetDepthBias(1, 128);
// Create stencil
state.SetEffect(EFF_STENCIL);
state.EnableTexture(false);
state.SetStencil(0, SOP_Increment, SF_ColorMaskOff);
state.Draw(DT_TriangleFan,fnode->vertexindex, 4);
// Draw projected plane into stencil
state.EnableTexture(true);
state.SetEffect(EFF_NONE);
state.SetStencil(1, SOP_Keep, SF_DepthMaskOff);
state.EnableDepthTest(false);
state.Draw(DT_TriangleFan,fnode->vertexindex + 4, 4);
// clear stencil
state.SetEffect(EFF_STENCIL);
state.EnableTexture(false);
state.SetStencil(1, SOP_Decrement, SF_ColorMaskOff | SF_DepthMaskOff);
state.Draw(DT_TriangleFan,fnode->vertexindex, 4);
// restore old stencil op.
state.EnableTexture(true);
state.EnableDepthTest(true);
state.SetEffect(EFF_NONE);
state.SetDepthBias(0, 0);
state.SetStencil(0, SOP_Keep, SF_AllOn);
fnode = fnode->next;
}
}
}
//==========================================================================
//
//
@ -282,8 +316,7 @@ void GLFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, alpha);
state.SetFog(lightlevel, rel, di->isFullbrightScene(), &Colormap, false);
if (!gltexture || !gltexture->tex->isFullbright())
state.SetObjectColor(FlatColor | 0xff000000);
state.SetObjectColor(FlatColor | 0xff000000);
if (!translucent)
{
@ -294,7 +327,7 @@ void GLFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
DrawSubsectors(di, state);
state.EnableTextureMatrix(false);
}
else
else if (!hacktype)
{
state.SetMaterial(gltexture, CLAMP_XY, 0, -1);
state.SetLightIndex(dynlightindex);
@ -302,6 +335,14 @@ void GLFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
flatvertices += 4;
flatprimitives++;
}
else if (hacktype & SSRF_PLANEHACK)
{
DrawOtherPlanes(di, state);
}
else if (hacktype & SSRF_FLOODHACK)
{
DrawFloodPlanes(di, state);
}
state.SetObjectColor(0xffffffff);
}
else
@ -355,8 +396,6 @@ inline void GLFlat::PutFlat(HWDrawInfo *di, bool fog)
//==========================================================================
//
// This draws one flat
// The passed sector does not indicate the area which is rendered.
// It is only used as source for the plane data.
// The whichplane boolean indicates if the flat is a floor(false) or a ceiling(true)
//
//==========================================================================
@ -394,8 +433,8 @@ void GLFlat::Process(HWDrawInfo *di, sector_t * model, int whichplane, bool fog)
iboindex = vert.second;
}
PutFlat(di, fog);
// For hacks this won't go into a render list.
if (hacktype == 0) PutFlat(di, fog);
rendered_flats++;
}
@ -438,7 +477,7 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
//
//==========================================================================
void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which)
{
lightlist_t * light;
FSectorPortal *port;
@ -454,6 +493,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
sector = &level.sectors[frontsector->sectornum];
extsector_t::xfloor &x = sector->e->XFloor;
dynlightindex = -1;
hacktype = (which & (SSRF_PLANEHACK|SSRF_FLOODHACK));
uint8_t &srf = di->section_renderflags[level.sections.SectionIndex(section)];
const auto &vp = di->Viewpoint;
@ -465,7 +505,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
//
//
//
if (frontsector->floorplane.ZatPoint(vp.Pos) <= vp.Pos.Z)
if ((which & SSRF_RENDERFLOOR) && frontsector->floorplane.ZatPoint(vp.Pos) <= vp.Pos.Z)
{
// process the original floor first.
@ -477,10 +517,12 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
port = frontsector->ValidatePortal(sector_t::floor);
if ((stack = (port != NULL)))
{
/* to be redone in a less invasive manner
if (port->mType == PORTS_STACKEDSECTORTHING)
{
di->AddFloorStack(sector); // stacked sector things require visplane merging.
}
*/
alpha = frontsector->GetAlpha(sector_t::floor);
}
else
@ -518,7 +560,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
//
//
//
if (frontsector->ceilingplane.ZatPoint(vp.Pos) >= vp.Pos.Z)
if ((which & SSRF_RENDERCEILING) && frontsector->ceilingplane.ZatPoint(vp.Pos) >= vp.Pos.Z)
{
// process the original ceiling first.
@ -530,10 +572,12 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
port = frontsector->ValidatePortal(sector_t::ceiling);
if ((stack = (port != NULL)))
{
/* as above for floors
if (port->mType == PORTS_STACKEDSECTORTHING)
{
di->AddCeilingStack(sector);
}
*/
alpha = frontsector->GetAlpha(sector_t::ceiling);
}
else
@ -572,7 +616,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
//
stack = false;
if (x.ffloors.Size())
if ((which & SSRF_RENDER3DPLANES) && x.ffloors.Size())
{
player_t * player = players[consoleplayer].camera->player;

View file

@ -41,6 +41,17 @@
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
// Get the nodes from the render data allocator so we don't have to keep track of them ourselves.
static gl_subsectorrendernode *NewSubsectorRenderNode()
{
return (gl_subsectorrendernode*)RenderDataAllocator.Alloc(sizeof(gl_subsectorrendernode));
}
static gl_floodrendernode *NewFloodRenderNode()
{
return (gl_floodrendernode*)RenderDataAllocator.Alloc(sizeof(gl_floodrendernode));
}
//==========================================================================
//
// light setup for render hacks.
@ -110,35 +121,24 @@ int HWDrawInfo::CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *pla
void HWDrawInfo::AddOtherFloorPlane(int sector, gl_subsectorrendernode * node)
{
int oldcnt = otherfloorplanes.Size();
if (oldcnt <= sector)
{
otherfloorplanes.Resize(sector + 1);
for (int i = oldcnt; i <= sector; i++) otherfloorplanes[i] = nullptr;
}
node->next = otherfloorplanes[sector];
auto pNode = otherFloorPlanes.CheckKey(sector);
node->next = pNode? *pNode : nullptr;
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &level.sectors[sector].floorplane);
node->vertexindex = CreateOtherPlaneVertices(node->sub, &level.sectors[sector].floorplane);
otherfloorplanes[sector] = node;
otherFloorPlanes[sector] = node;
}
void HWDrawInfo::AddOtherCeilingPlane(int sector, gl_subsectorrendernode * node)
{
int oldcnt = otherceilingplanes.Size();
if (oldcnt <= sector)
{
otherceilingplanes.Resize(sector + 1);
for (int i = oldcnt; i <= sector; i++) otherceilingplanes[i] = nullptr;
}
node->next = otherceilingplanes[sector];
auto pNode = otherCeilingPlanes.CheckKey(sector);
node->next = pNode? *pNode : nullptr;
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &level.sectors[sector].ceilingplane);
node->vertexindex = CreateOtherPlaneVertices(node->sub, &level.sectors[sector].ceilingplane);
otherceilingplanes[sector] = node;
otherCeilingPlanes[sector] = node;
}
//==========================================================================
//
// Collects all sectors that might need a fake ceiling
@ -511,7 +511,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(sec->sectornum, node);
@ -555,7 +555,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(fakesector->sectornum, node);
}
@ -583,7 +583,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(sec->sectornum, node);
}
@ -626,7 +626,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(fakesector->sectornum, node);
}
@ -730,19 +730,13 @@ void HWDrawInfo::PrepareUpperGap(seg_t * seg)
CreateFloodStencilPoly(&ws, vertices.first);
CreateFloodPoly(&ws, vertices.first+4, ws.z2, fakebsector, true);
gl_floodrendernode *node = new gl_floodrendernode;
int oldcnt = floodfloorsegs.Size();
auto sector = fakebsector->sectornum;
if (oldcnt <= sector)
{
floodfloorsegs.Resize(sector + 1);
for (int i = oldcnt; i <= sector; i++) floodfloorsegs[i] = nullptr;
}
gl_floodrendernode *node = NewFloodRenderNode();
auto pNode = floodFloorSegs.CheckKey(fakebsector->sectornum);
node->next = floodfloorsegs[sector];
node->next = pNode? *pNode : nullptr;
node->seg = seg;
node->vertexindex = vertices.second;
floodfloorsegs[sector] = node;
floodFloorSegs[fakebsector->sectornum] = node;
}
@ -794,19 +788,14 @@ void HWDrawInfo::PrepareLowerGap(seg_t * seg)
CreateFloodStencilPoly(&ws, vertices.first);
CreateFloodPoly(&ws, vertices.first+4, ws.z1, fakebsector, false);
gl_floodrendernode *node = new gl_floodrendernode;
int oldcnt = floodceilingsegs.Size();
auto sector = fakebsector->sectornum;
if (oldcnt <= sector)
{
floodceilingsegs.Resize(sector + 1);
for (int i = oldcnt; i <= sector; i++) floodceilingsegs[i] = nullptr;
}
gl_floodrendernode *node = NewFloodRenderNode();
auto pNode = floodCeilingSegs.CheckKey(fakebsector->sectornum);
node->next = pNode? *pNode : nullptr;
node->next = floodceilingsegs[sector];
node->seg = seg;
node->vertexindex = vertices.second;
floodceilingsegs[sector] = node;
floodCeilingSegs[fakebsector->sectornum] = node;
}
//==========================================================================
@ -1122,8 +1111,7 @@ void HWDrawInfo::HandleHackedSubsectors()
{
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(sub->render_sector->sectornum, node);
}
@ -1145,8 +1133,7 @@ void HWDrawInfo::HandleHackedSubsectors()
{
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(sub->render_sector->sectornum, node);
}
@ -1308,7 +1295,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
if (sec->GetAlpha(sector_t::ceiling) != 0 && sec->GetTexture(sector_t::ceiling) != skyflatnum)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = sub;
AddOtherCeilingPlane(sec->sectornum, node);
}
@ -1353,7 +1340,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
if (sec->GetAlpha(sector_t::floor) != 0 && sec->GetTexture(sector_t::floor) != skyflatnum)
{
gl_subsectorrendernode * node = new gl_subsectorrendernode;
gl_subsectorrendernode * node = NewSubsectorRenderNode();
node->sub = sub;
AddOtherFloorPlane(sec->sectornum, node);
}