mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 22:33:17 +00:00
- sector rendering refactoring for sections - work in progress.
This commit is contained in:
parent
0deb388a75
commit
d7db00d92e
9 changed files with 185 additions and 12 deletions
|
@ -53,6 +53,7 @@ struct FBlockNode;
|
|||
struct FPortalGroupArray;
|
||||
struct visstyle_t;
|
||||
class FLightDefaults;
|
||||
struct FSection;
|
||||
//
|
||||
// NOTES: AActor
|
||||
//
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "memarena.h"
|
||||
#include "flatvertices.h"
|
||||
|
||||
using DoublePoint = std::pair<DVector2, DVector2>;
|
||||
|
||||
|
@ -611,6 +612,114 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
// Temporary data for creating an indexed buffer
|
||||
struct VertexIndexGenerationInfo
|
||||
{
|
||||
TArray<vertex_t *> vertices;
|
||||
TMap<vertex_t*, uint32_t> vertexmap;
|
||||
|
||||
TArray<uint32_t> indices;
|
||||
|
||||
uint32_t AddVertex(vertex_t *vert)
|
||||
{
|
||||
auto check = vertexmap.CheckKey(vert);
|
||||
if (check != nullptr) return *check;
|
||||
auto index = vertices.Push(vert);
|
||||
vertexmap[vert] = index;
|
||||
return index;
|
||||
}
|
||||
|
||||
uint32_t GetIndex(vertex_t *vert)
|
||||
{
|
||||
auto check = vertexmap.CheckKey(vert);
|
||||
if (check != nullptr) return *check;
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
uint32_t AddIndexForVertex(vertex_t *vert)
|
||||
{
|
||||
return indices.Push(GetIndex(vert));
|
||||
}
|
||||
|
||||
uint32_t AddIndex(uint32_t indx)
|
||||
{
|
||||
return indices.Push(indx);
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void CreateIndexedSubsectorVertices(subsector_t *sub, VertexIndexGenerationInfo &gen)
|
||||
{
|
||||
if (sub->numlines < 3) return;
|
||||
|
||||
uint32_t startindex = gen.indices.Size();
|
||||
|
||||
if ((sub->flags & SSECF_HOLE) && sub->numlines > 3)
|
||||
{
|
||||
// Hole filling "subsectors" are not necessarily convex so they require real triangulation.
|
||||
// These things are extremely rare so performance is secondary here.
|
||||
|
||||
using Point = std::pair<double, double>;
|
||||
std::vector<std::vector<Point>> polygon;
|
||||
std::vector<Point> *curPoly;
|
||||
|
||||
for (unsigned i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
polygon.resize(1);
|
||||
curPoly = &polygon.back();
|
||||
curPoly->push_back({ sub->firstline[i].v1->fX(), sub->firstline[i].v1->fY() });
|
||||
}
|
||||
auto indices = mapbox::earcut(polygon);
|
||||
for (auto vti : indices)
|
||||
{
|
||||
gen.AddIndexForVertex(sub->firstline[vti].v1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int firstndx = gen.GetIndex(sub->firstline[0].v1);
|
||||
int secondndx = gen.GetIndex(sub->firstline[1].v1);
|
||||
for (unsigned int k = 2; k < sub->numlines; k++)
|
||||
{
|
||||
gen.AddIndex(firstndx);
|
||||
gen.AddIndex(secondndx);
|
||||
auto ndx = gen.GetIndex(sub->firstline[k].v1);
|
||||
gen.AddIndex(ndx);
|
||||
secondndx = ndx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateVerticesForSection(FSectionContainer &output, FSection §ion)
|
||||
{
|
||||
VertexIndexGenerationInfo gen;
|
||||
|
||||
for (auto sub : section.subsectors)
|
||||
{
|
||||
CreateIndexedSubsectorVertices(sub, gen);
|
||||
}
|
||||
section.vertexindex = output.allVertices.Size();
|
||||
section.vertexcount = gen.vertices.Size();
|
||||
section.indexindex = output.allVertexIndices.Size();
|
||||
section.indexcount = gen.indices.Size();
|
||||
output.allVertices.Append(gen.vertices);
|
||||
output.allVertexIndices.Append(gen.indices);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
|
@ -620,10 +729,14 @@ public:
|
|||
void ConstructOutput(FSectionContainer &output)
|
||||
{
|
||||
output.allSections.Resize(groups.Size());
|
||||
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size());
|
||||
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size() + 2*level.sectors.Size());
|
||||
output.sectionForSubsectorPtr = &output.allIndices[0];
|
||||
output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()];
|
||||
output.firstSectionForSectorPtr = &output.allIndices[level.subsectors.Size() + level.sides.Size()];
|
||||
output.numberOfSectionForSectorPtr = &output.allIndices[level.subsectors.Size() + level.sides.Size() + level.sectors.Size()];
|
||||
memset(output.sectionForSubsectorPtr, -1, sizeof(int) * level.subsectors.Size());
|
||||
memset(output.firstSectionForSectorPtr, -1, sizeof(int) * level.sectors.Size());
|
||||
memset(output.numberOfSectionForSectorPtr, 0, sizeof(int) * level.sectors.Size());
|
||||
|
||||
unsigned numsegments = 0;
|
||||
unsigned numsides = 0;
|
||||
|
@ -669,10 +782,15 @@ public:
|
|||
dest.validcount = 0;
|
||||
dest.segments.Set(&output.allLines[numsegments], group.segments.Size());
|
||||
dest.sides.Set(&output.allSides[numsides], group.sideMap.CountUsed());
|
||||
dest.subsectors.Set(&output.allSubsectors[numsubsectors]);
|
||||
dest.subsectors.Set(&output.allSubsectors[numsubsectors], group.subsectors.Size());
|
||||
dest.vertexindex = -1;
|
||||
dest.vertexcount = 0;
|
||||
dest.bounds = {1e32, 1e32, -1e32, -1e32};
|
||||
numsegments += group.segments.Size();
|
||||
|
||||
if (output.firstSectionForSectorPtr[dest.sector->Index()] == -1)
|
||||
output.firstSectionForSectorPtr[dest.sector->Index()] = curgroup;
|
||||
|
||||
for (auto &segment : group.segments)
|
||||
{
|
||||
// Use the indices calculated above to store these elements.
|
||||
|
@ -697,6 +815,7 @@ public:
|
|||
output.sectionForSubsectorPtr[ssi] = curgroup;
|
||||
}
|
||||
numsubsectors += group.subsectors.Size();
|
||||
CreateVerticesForSection(output, dest);
|
||||
curgroup++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,11 +80,15 @@ struct FSection
|
|||
{
|
||||
// tbd: Do we need a list of subsectors here? Ideally the subsectors should not be used anywhere anymore except for finding out where a location is.
|
||||
TArrayView<FSectionLine> segments;
|
||||
TArrayView<side_t *> sides; // contains all sidedefs, including the internal ones that do not make up the outer shape. (this list is not exclusive. A sidedef can be in multiple sections!)
|
||||
TArrayView<subsector_t *> subsectors; // contains all sidedefs, including the internal ones that do not make up the outer shape. (this list is not exclusive. A sidedef can be in multiple sections!)
|
||||
TArrayView<side_t *> sides; // contains all sidedefs, including the internal ones that do not make up the outer shape.
|
||||
TArrayView<subsector_t *> subsectors; // contains all subsectors making up this section
|
||||
sector_t *sector;
|
||||
FLightNode *lighthead; // Light nodes (blended and additive)
|
||||
FLightNode *lighthead; // Light nodes (blended and additive)
|
||||
BoundingRect bounds;
|
||||
int vertexindex;
|
||||
int vertexcount; // index and length of this section's entry in the allVertices array
|
||||
int indexindex;
|
||||
int indexcount; // index and length of this section's entry in the allVertices array
|
||||
int validcount;
|
||||
short mapsection;
|
||||
char hacked; // 1: is part of a render hack
|
||||
|
@ -95,13 +99,16 @@ class FSectionContainer
|
|||
public:
|
||||
TArray<FSectionLine> allLines;
|
||||
TArray<FSection> allSections;
|
||||
//TArray<vertex_t*> allVertices;
|
||||
TArray<vertex_t*> allVertices;
|
||||
TArray<uint32_t> allVertexIndices;
|
||||
TArray<side_t *> allSides;
|
||||
TArray<subsector_t *> allSubsectors;
|
||||
TArray<int> allIndices;
|
||||
|
||||
int *sectionForSubsectorPtr; // stored inside allIndices
|
||||
int *sectionForSidedefPtr; // also stored inside allIndices;
|
||||
int *firstSectionForSectorPtr; // ditto.
|
||||
int *numberOfSectionForSectorPtr; // ditto.
|
||||
|
||||
FSection *SectionForSubsector(subsector_t *sub)
|
||||
{
|
||||
|
@ -111,6 +118,14 @@ public:
|
|||
{
|
||||
return ssindex < 0 ? nullptr : &allSections[sectionForSubsectorPtr[ssindex]];
|
||||
}
|
||||
int SectionNumForSubsector(subsector_t *sub)
|
||||
{
|
||||
return SectionNumForSubsector(sub->Index());
|
||||
}
|
||||
int SectionNumForSubsector(int ssindex)
|
||||
{
|
||||
return ssindex < 0 ? -1 : sectionForSubsectorPtr[ssindex];
|
||||
}
|
||||
FSection *SectionForSidedef(side_t *side)
|
||||
{
|
||||
return SectionForSidedef(side->Index());
|
||||
|
@ -119,11 +134,35 @@ public:
|
|||
{
|
||||
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());
|
||||
}
|
||||
TArrayView<FSection> SectionsForSector(int sindex)
|
||||
{
|
||||
return sindex < 0 ? TArrayView<FSection>(0) : TArrayView<FSection>(&allSections[firstSectionForSectorPtr[sindex]], numberOfSectionForSectorPtr[sindex]);
|
||||
}
|
||||
int SectionIndex(const FSection *sect)
|
||||
{
|
||||
return int(sect - allSections.Data());
|
||||
}
|
||||
void Clear()
|
||||
{
|
||||
allLines.Clear();
|
||||
allSections.Clear();
|
||||
allIndices.Clear();
|
||||
allVertexIndices.Clear();
|
||||
allVertices.Clear();
|
||||
allSides.Clear();
|
||||
allSubsectors.Clear();
|
||||
}
|
||||
void Reset()
|
||||
{
|
||||
|
@ -131,6 +170,10 @@ public:
|
|||
allLines.ShrinkToFit();
|
||||
allSections.ShrinkToFit();
|
||||
allIndices.ShrinkToFit();
|
||||
allVertexIndices.ShrinkToFit();
|
||||
allVertices.ShrinkToFit();
|
||||
allSides.ShrinkToFit();
|
||||
allSubsectors.ShrinkToFit();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ void HWDrawInfo::WorkerThread()
|
|||
{
|
||||
GLFlat flat;
|
||||
SetupFlat.Clock();
|
||||
flat.section = level.sections.SectionForSubsector(job->sub);
|
||||
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
|
||||
flat.ProcessSector(this, front);
|
||||
SetupFlat.Unclock();
|
||||
|
@ -679,7 +680,8 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
|||
fakesector = hw_FakeFlat(sector, &fake, in_area, false);
|
||||
}
|
||||
|
||||
uint8_t &srf = sectorrenderflags[sub->render_sector->sectornum];
|
||||
auto secnum = level.sections.SectionNumForSubsector(sub);
|
||||
uint8_t &srf = section_renderflags[secnum];
|
||||
if (!(srf & SSRF_PROCESSED))
|
||||
{
|
||||
srf |= SSRF_PROCESSED;
|
||||
|
@ -691,6 +693,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
|||
else
|
||||
{
|
||||
GLFlat flat;
|
||||
flat.section = level.sections.SectionForSubsector(sub);
|
||||
SetupFlat.Clock();
|
||||
flat.ProcessSector(this, fakesector);
|
||||
SetupFlat.Unclock();
|
||||
|
|
|
@ -214,11 +214,11 @@ void HWDrawInfo::ClearBuffers()
|
|||
CurrentMapSections.Resize(level.NumMapSections);
|
||||
CurrentMapSections.Zero();
|
||||
|
||||
sectorrenderflags.Resize(level.sectors.Size());
|
||||
section_renderflags.Resize(level.sections.allSections.Size());
|
||||
ss_renderflags.Resize(level.subsectors.Size());
|
||||
no_renderflags.Resize(level.subsectors.Size());
|
||||
|
||||
memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0]));
|
||||
memset(§ion_renderflags[0], 0, level.sections.allSections.Size() * sizeof(section_renderflags[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]));
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ struct HWDrawInfo
|
|||
|
||||
TArray<subsector_t *> HandledSubsectors;
|
||||
|
||||
TArray<uint8_t> sectorrenderflags;
|
||||
TArray<uint8_t> section_renderflags;
|
||||
TArray<uint8_t> ss_renderflags;
|
||||
TArray<uint8_t> no_renderflags;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ struct FSpriteModelFrame;
|
|||
struct particle_t;
|
||||
class FRenderState;
|
||||
struct GLDecal;
|
||||
struct FSection;
|
||||
enum area_t : int;
|
||||
|
||||
enum HWRenderStyle
|
||||
|
@ -293,6 +294,7 @@ class GLFlat
|
|||
{
|
||||
public:
|
||||
sector_t * sector;
|
||||
FSection *section;
|
||||
float z; // the z position of the flat (only valid for non-sloped planes)
|
||||
FMaterial *gltexture;
|
||||
|
||||
|
|
|
@ -189,6 +189,8 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
|
|||
SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup);
|
||||
}
|
||||
state.SetLightIndex(dynlightindex);
|
||||
|
||||
|
||||
if (vcount > 0 && !di->ClipLineShouldBeActive())
|
||||
{
|
||||
state.DrawIndexed(DT_Triangles, iboindex, vcount);
|
||||
|
@ -197,6 +199,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
|
|||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
int index = iboindex;
|
||||
bool applied = false;
|
||||
for (int i = 0; i < sector->subsectorcount; i++)
|
||||
|
@ -213,6 +216,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
|
|||
}
|
||||
index += (sub->numlines - 2) * 3;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (!(renderflags&SSRF_RENDER3DPLANES))
|
||||
|
@ -473,7 +477,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
|
|||
extsector_t::xfloor &x = sector->e->XFloor;
|
||||
dynlightindex = -1;
|
||||
|
||||
uint8_t &srf = di->sectorrenderflags[sector->sectornum];
|
||||
uint8_t &srf = di->section_renderflags[level.sections.SectionIndex(section)];
|
||||
const auto &vp = di->Viewpoint;
|
||||
|
||||
//
|
||||
|
|
|
@ -850,7 +850,8 @@ void HWDrawInfo::PrepareUnhandledMissingTextures()
|
|||
|
||||
if (seg->linedef->validcount == validcount) continue; // already done
|
||||
seg->linedef->validcount = validcount;
|
||||
if (!(sectorrenderflags[seg->backsector->sectornum] & SSRF_RENDERFLOOR)) continue;
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue