mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- made the common render hacks functional again as separate render items.
This commit is contained in:
parent
a6e77ae094
commit
ddc75f7ba5
9 changed files with 122 additions and 113 deletions
|
@ -632,10 +632,9 @@ public:
|
|||
void ConstructOutput(FSectionContainer &output)
|
||||
{
|
||||
output.allSections.Resize(groups.Size());
|
||||
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size() + 2*level.sectors.Size());
|
||||
output.sectionForSidedefPtr = &output.allIndices[0];
|
||||
output.firstSectionForSectorPtr = &output.allIndices[level.sides.Size()];
|
||||
output.numberOfSectionForSectorPtr = &output.allIndices[level.sides.Size() + level.sectors.Size()];
|
||||
output.allIndices.Resize(2*level.sectors.Size());
|
||||
output.firstSectionForSectorPtr = &output.allIndices[0];
|
||||
output.numberOfSectionForSectorPtr = &output.allIndices[level.sectors.Size()];
|
||||
memset(output.firstSectionForSectorPtr, -1, sizeof(int) * level.sectors.Size());
|
||||
memset(output.numberOfSectionForSectorPtr, 0, sizeof(int) * level.sectors.Size());
|
||||
|
||||
|
@ -713,7 +712,6 @@ public:
|
|||
while (it.NextPair(pair))
|
||||
{
|
||||
output.allSides[numsides++] = &level.sides[pair->Key];
|
||||
output.sectionForSidedefPtr[pair->Key] = curgroup;
|
||||
}
|
||||
for (auto ssi : group.subsectors)
|
||||
{
|
||||
|
|
|
@ -102,26 +102,9 @@ public:
|
|||
TArray<subsector_t *> allSubsectors;
|
||||
TArray<int> allIndices;
|
||||
|
||||
int *sectionForSidedefPtr; // also stored inside allIndices;
|
||||
int *firstSectionForSectorPtr; // ditto.
|
||||
int *numberOfSectionForSectorPtr; // ditto.
|
||||
|
||||
FSection *SectionForSidedef(side_t *side)
|
||||
{
|
||||
return SectionForSidedef(side->Index());
|
||||
}
|
||||
FSection *SectionForSidedef(int sindex)
|
||||
{
|
||||
return sindex < 0 ? nullptr : &allSections[sectionForSidedefPtr[sindex]];
|
||||
}
|
||||
int SectionNumForSidedef(side_t *side)
|
||||
{
|
||||
return SectionNumForSidedef(side->Index());
|
||||
}
|
||||
int SectionNumForSidedef(int sindex)
|
||||
{
|
||||
return sindex < 0 ? -1 : sectionForSidedefPtr[sindex];
|
||||
}
|
||||
TArrayView<FSection> SectionsForSector(sector_t *sec)
|
||||
{
|
||||
return SectionsForSector(sec->Index());
|
||||
|
|
|
@ -441,8 +441,8 @@ void HWDrawInfo::CreateScene()
|
|||
|
||||
HandleMissingTextures(in_area); // Missing upper/lower textures
|
||||
HandleHackedSubsectors(); // open sector hacks for deep water
|
||||
ProcessSectorStacks(in_area); // merge visplanes of sector stacks
|
||||
PrepareUnhandledMissingTextures();
|
||||
DispatchRenderHacks();
|
||||
screen->mLights->Unmap();
|
||||
screen->mVertexData->Unmap();
|
||||
|
||||
|
|
|
@ -264,6 +264,7 @@ public:
|
|||
void CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor, area_t in_area);
|
||||
void CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor, area_t in_area);
|
||||
|
||||
void DispatchRenderHacks();
|
||||
void AddUpperMissingTexture(side_t * side, subsector_t *sub, float backheight);
|
||||
void AddLowerMissingTexture(side_t * side, subsector_t *sub, float backheight);
|
||||
void HandleMissingTextures(area_t in_area);
|
||||
|
|
|
@ -116,7 +116,7 @@ void HWDrawInfo::AddFlat(GLFlat *flat, bool fog)
|
|||
list = GLDL_PLAINFLATS;
|
||||
}
|
||||
}
|
||||
else
|
||||
else //if (flat->hacktype != SSRF_FLOODHACK) // The flood hack may later need different treatment but with the current setup can go into the existing render list.
|
||||
{
|
||||
bool masked = flat->gltexture->isMasked() && ((flat->renderflags&SSRF_RENDER3DPLANES) || flat->stack);
|
||||
list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS;
|
||||
|
|
|
@ -320,7 +320,7 @@ 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, int which = SSRF_RENDERALL);
|
||||
void ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
|
||||
|
||||
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
|
||||
void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
|
|
|
@ -203,7 +203,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
|
|||
|
||||
void GLFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state)
|
||||
{
|
||||
state.SetMaterial(gltexture, CLAMP_XY, 0, -1);
|
||||
state.SetMaterial(gltexture, CLAMP_NONE, 0, -1);
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
|
||||
|
@ -231,68 +231,58 @@ void GLFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state)
|
|||
|
||||
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)
|
||||
{
|
||||
// Flood gaps with the back side's ceiling/floor texture
|
||||
// This requires a stencil because the projected plane interferes with
|
||||
// the depth buffer
|
||||
|
||||
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
|
||||
di->floodFloorSegs.CheckKey(sector->sectornum) : di->floodCeilingSegs.CheckKey(sector->sectornum);
|
||||
if (!pNode) return;
|
||||
|
||||
auto fnode = *pNode;
|
||||
state.SetMaterial(gltexture, CLAMP_NONE, 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 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,7 +308,15 @@ void GLFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
state.SetFog(lightlevel, rel, di->isFullbrightScene(), &Colormap, false);
|
||||
state.SetObjectColor(FlatColor | 0xff000000);
|
||||
|
||||
if (!translucent)
|
||||
if (hacktype & SSRF_PLANEHACK)
|
||||
{
|
||||
DrawOtherPlanes(di, state);
|
||||
}
|
||||
else if (hacktype & SSRF_FLOODHACK)
|
||||
{
|
||||
DrawFloodPlanes(di, state);
|
||||
}
|
||||
else if (!translucent)
|
||||
{
|
||||
if (sector->special != GLSector_Skybox)
|
||||
{
|
||||
|
@ -335,14 +333,6 @@ 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
|
||||
|
@ -385,7 +375,7 @@ inline void GLFlat::PutFlat(HWDrawInfo *di, bool fog)
|
|||
}
|
||||
else if (!screen->BuffersArePersistent())
|
||||
{
|
||||
if (level.HasDynamicLights && gltexture != nullptr)
|
||||
if (level.HasDynamicLights && gltexture != nullptr && !(hacktype & (SSRF_PLANEHACK|SSRF_FLOODHACK)) )
|
||||
{
|
||||
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
|
||||
}
|
||||
|
@ -434,7 +424,7 @@ void GLFlat::Process(HWDrawInfo *di, sector_t * model, int whichplane, bool fog)
|
|||
}
|
||||
|
||||
// For hacks this won't go into a render list.
|
||||
if (hacktype == 0) PutFlat(di, fog);
|
||||
PutFlat(di, fog);
|
||||
rendered_flats++;
|
||||
}
|
||||
|
||||
|
@ -495,7 +485,8 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which)
|
|||
dynlightindex = -1;
|
||||
hacktype = (which & (SSRF_PLANEHACK|SSRF_FLOODHACK));
|
||||
|
||||
uint8_t &srf = di->section_renderflags[level.sections.SectionIndex(section)];
|
||||
uint8_t sink;
|
||||
uint8_t &srf = hacktype? sink : di->section_renderflags[level.sections.SectionIndex(section)];
|
||||
const auto &vp = di->Viewpoint;
|
||||
|
||||
//
|
||||
|
|
|
@ -41,7 +41,55 @@
|
|||
|
||||
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Create render list entries from the data generated below
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWDrawInfo::DispatchRenderHacks()
|
||||
{
|
||||
TMap<int, gl_subsectorrendernode*>::Pair *pair;
|
||||
TMap<int, gl_floodrendernode*>::Pair *fpair;
|
||||
TMap<int, gl_subsectorrendernode*>::Iterator ofi(otherFloorPlanes);
|
||||
GLFlat glflat;
|
||||
sector_t fakesec;
|
||||
glflat.section = nullptr;
|
||||
while (ofi.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], &fakesec, in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_subsectorrendernode*>::Iterator oci(otherCeilingPlanes);
|
||||
while (ofi.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], &fakesec, in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator ffi(floodFloorSegs);
|
||||
while (ffi.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], &fakesec, in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator fci(floodCeilingSegs);
|
||||
while (fci.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], &fakesec, in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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));
|
||||
|
@ -506,9 +554,6 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
if (DoOneSectorUpper(MissingUpperTextures[i].sub, MissingUpperTextures[i].Planez, in_area))
|
||||
{
|
||||
sector_t * sec = MissingUpperTextures[i].seg->backsector;
|
||||
// The mere fact that this seg has been added to the list means that the back sector
|
||||
// will be rendered so we can safely assume that it is already in the render list
|
||||
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
|
@ -550,9 +595,6 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
backsub->validcount = validcount;
|
||||
if (DoFakeCeilingBridge(backsub, planez, in_area))
|
||||
{
|
||||
// The mere fact that this seg has been added to the list means that the back sector
|
||||
// will be rendered so we can safely assume that it is already in the render list
|
||||
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
|
@ -578,8 +620,6 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
if (DoOneSectorLower(MissingLowerTextures[i].sub, MissingLowerTextures[i].Planez, in_area))
|
||||
{
|
||||
sector_t * sec = MissingLowerTextures[i].seg->backsector;
|
||||
// The mere fact that this seg has been added to the list means that the back sector
|
||||
// will be rendered so we can safely assume that it is already in the render list
|
||||
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
|
@ -621,9 +661,6 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
backsub->validcount = validcount;
|
||||
if (DoFakeBridge(backsub, planez, in_area))
|
||||
{
|
||||
// The mere fact that this seg has been added to the list means that the back sector
|
||||
// will be rendered so we can safely assume that it is already in the render list
|
||||
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
|
@ -840,8 +877,6 @@ void HWDrawInfo::PrepareUnhandledMissingTextures()
|
|||
|
||||
if (seg->linedef->validcount == validcount) continue; // already done
|
||||
seg->linedef->validcount = validcount;
|
||||
int section = level.sections.SectionNumForSidedef(seg->sidedef);
|
||||
if (!(section_renderflags[section] & SSRF_RENDERFLOOR)) continue;
|
||||
if (seg->frontsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) continue; // out of sight
|
||||
if (seg->backsector->transdoor) continue;
|
||||
if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue;
|
||||
|
|
|
@ -536,8 +536,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// This is not a real dynamic array but just a wrapper around a pointer reference.
|
||||
// Used for wrapping some memory allocated elsewhere into a VM compatible data structure.
|
||||
// This is only used for exposing the sector's Lines array to ZScript.
|
||||
// This also must be trivial so that sector_t remains trivial.
|
||||
// For other uses TArrayView should be preferred.
|
||||
|
||||
template <class T>
|
||||
class TStaticPointedArray
|
||||
|
|
Loading…
Reference in a new issue