- sector rendering refactoring for sections - work in progress.

This commit is contained in:
Christoph Oelckers 2018-11-05 01:01:48 +01:00
parent 0deb388a75
commit d7db00d92e
9 changed files with 185 additions and 12 deletions

View File

@ -53,6 +53,7 @@ struct FBlockNode;
struct FPortalGroupArray; struct FPortalGroupArray;
struct visstyle_t; struct visstyle_t;
class FLightDefaults; class FLightDefaults;
struct FSection;
// //
// NOTES: AActor // NOTES: AActor
// //

View File

@ -34,6 +34,7 @@
#include "p_setup.h" #include "p_setup.h"
#include "c_dispatch.h" #include "c_dispatch.h"
#include "memarena.h" #include "memarena.h"
#include "flatvertices.h"
using DoublePoint = std::pair<DVector2, DVector2>; using DoublePoint = std::pair<DVector2, DVector2>;
@ -611,6 +612,114 @@ public:
return false; 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 &section)
{
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) void ConstructOutput(FSectionContainer &output)
{ {
output.allSections.Resize(groups.Size()); 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.sectionForSubsectorPtr = &output.allIndices[0];
output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()]; 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.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 numsegments = 0;
unsigned numsides = 0; unsigned numsides = 0;
@ -669,10 +782,15 @@ public:
dest.validcount = 0; dest.validcount = 0;
dest.segments.Set(&output.allLines[numsegments], group.segments.Size()); dest.segments.Set(&output.allLines[numsegments], group.segments.Size());
dest.sides.Set(&output.allSides[numsides], group.sideMap.CountUsed()); 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}; dest.bounds = {1e32, 1e32, -1e32, -1e32};
numsegments += group.segments.Size(); numsegments += group.segments.Size();
if (output.firstSectionForSectorPtr[dest.sector->Index()] == -1)
output.firstSectionForSectorPtr[dest.sector->Index()] = curgroup;
for (auto &segment : group.segments) for (auto &segment : group.segments)
{ {
// Use the indices calculated above to store these elements. // Use the indices calculated above to store these elements.
@ -697,6 +815,7 @@ public:
output.sectionForSubsectorPtr[ssi] = curgroup; output.sectionForSubsectorPtr[ssi] = curgroup;
} }
numsubsectors += group.subsectors.Size(); numsubsectors += group.subsectors.Size();
CreateVerticesForSection(output, dest);
curgroup++; curgroup++;
} }
} }

View File

@ -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. // 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<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<side_t *> sides; // contains all sidedefs, including the internal ones that do not make up the outer shape.
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<subsector_t *> subsectors; // contains all subsectors making up this section
sector_t *sector; sector_t *sector;
FLightNode *lighthead; // Light nodes (blended and additive) FLightNode *lighthead; // Light nodes (blended and additive)
BoundingRect bounds; 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; int validcount;
short mapsection; short mapsection;
char hacked; // 1: is part of a render hack char hacked; // 1: is part of a render hack
@ -95,13 +99,16 @@ class FSectionContainer
public: public:
TArray<FSectionLine> allLines; TArray<FSectionLine> allLines;
TArray<FSection> allSections; TArray<FSection> allSections;
//TArray<vertex_t*> allVertices; TArray<vertex_t*> allVertices;
TArray<uint32_t> allVertexIndices;
TArray<side_t *> allSides; TArray<side_t *> allSides;
TArray<subsector_t *> allSubsectors; TArray<subsector_t *> allSubsectors;
TArray<int> allIndices; TArray<int> allIndices;
int *sectionForSubsectorPtr; // stored inside allIndices int *sectionForSubsectorPtr; // stored inside allIndices
int *sectionForSidedefPtr; // also stored inside allIndices; int *sectionForSidedefPtr; // also stored inside allIndices;
int *firstSectionForSectorPtr; // ditto.
int *numberOfSectionForSectorPtr; // ditto.
FSection *SectionForSubsector(subsector_t *sub) FSection *SectionForSubsector(subsector_t *sub)
{ {
@ -111,6 +118,14 @@ public:
{ {
return ssindex < 0 ? nullptr : &allSections[sectionForSubsectorPtr[ssindex]]; 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) FSection *SectionForSidedef(side_t *side)
{ {
return SectionForSidedef(side->Index()); return SectionForSidedef(side->Index());
@ -119,11 +134,35 @@ public:
{ {
return sindex < 0 ? nullptr : &allSections[sectionForSidedefPtr[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());
}
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() void Clear()
{ {
allLines.Clear(); allLines.Clear();
allSections.Clear(); allSections.Clear();
allIndices.Clear(); allIndices.Clear();
allVertexIndices.Clear();
allVertices.Clear();
allSides.Clear();
allSubsectors.Clear();
} }
void Reset() void Reset()
{ {
@ -131,6 +170,10 @@ public:
allLines.ShrinkToFit(); allLines.ShrinkToFit();
allSections.ShrinkToFit(); allSections.ShrinkToFit();
allIndices.ShrinkToFit(); allIndices.ShrinkToFit();
allVertexIndices.ShrinkToFit();
allVertices.ShrinkToFit();
allSides.ShrinkToFit();
allSubsectors.ShrinkToFit();
} }
}; };

View File

@ -155,6 +155,7 @@ void HWDrawInfo::WorkerThread()
{ {
GLFlat flat; GLFlat flat;
SetupFlat.Clock(); SetupFlat.Clock();
flat.section = level.sections.SectionForSubsector(job->sub);
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false); front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
flat.ProcessSector(this, front); flat.ProcessSector(this, front);
SetupFlat.Unclock(); SetupFlat.Unclock();
@ -679,7 +680,8 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
fakesector = hw_FakeFlat(sector, &fake, in_area, false); 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)) if (!(srf & SSRF_PROCESSED))
{ {
srf |= SSRF_PROCESSED; srf |= SSRF_PROCESSED;
@ -691,6 +693,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
else else
{ {
GLFlat flat; GLFlat flat;
flat.section = level.sections.SectionForSubsector(sub);
SetupFlat.Clock(); SetupFlat.Clock();
flat.ProcessSector(this, fakesector); flat.ProcessSector(this, fakesector);
SetupFlat.Unclock(); SetupFlat.Unclock();

View File

@ -214,11 +214,11 @@ void HWDrawInfo::ClearBuffers()
CurrentMapSections.Resize(level.NumMapSections); CurrentMapSections.Resize(level.NumMapSections);
CurrentMapSections.Zero(); CurrentMapSections.Zero();
sectorrenderflags.Resize(level.sectors.Size()); section_renderflags.Resize(level.sections.allSections.Size());
ss_renderflags.Resize(level.subsectors.Size()); ss_renderflags.Resize(level.subsectors.Size());
no_renderflags.Resize(level.subsectors.Size()); no_renderflags.Resize(level.subsectors.Size());
memset(&sectorrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); memset(&section_renderflags[0], 0, level.sections.allSections.Size() * sizeof(section_renderflags[0]));
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_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])); memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));

View File

@ -170,7 +170,7 @@ struct HWDrawInfo
TArray<subsector_t *> HandledSubsectors; TArray<subsector_t *> HandledSubsectors;
TArray<uint8_t> sectorrenderflags; TArray<uint8_t> section_renderflags;
TArray<uint8_t> ss_renderflags; TArray<uint8_t> ss_renderflags;
TArray<uint8_t> no_renderflags; TArray<uint8_t> no_renderflags;

View File

@ -27,6 +27,7 @@ struct FSpriteModelFrame;
struct particle_t; struct particle_t;
class FRenderState; class FRenderState;
struct GLDecal; struct GLDecal;
struct FSection;
enum area_t : int; enum area_t : int;
enum HWRenderStyle enum HWRenderStyle
@ -293,6 +294,7 @@ class GLFlat
{ {
public: public:
sector_t * sector; sector_t * sector;
FSection *section;
float z; // the z position of the flat (only valid for non-sloped planes) float z; // the z position of the flat (only valid for non-sloped planes)
FMaterial *gltexture; FMaterial *gltexture;

View File

@ -189,6 +189,8 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup); SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup);
} }
state.SetLightIndex(dynlightindex); state.SetLightIndex(dynlightindex);
if (vcount > 0 && !di->ClipLineShouldBeActive()) if (vcount > 0 && !di->ClipLineShouldBeActive())
{ {
state.DrawIndexed(DT_Triangles, iboindex, vcount); state.DrawIndexed(DT_Triangles, iboindex, vcount);
@ -197,6 +199,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
} }
else else
{ {
/*
int index = iboindex; int index = iboindex;
bool applied = false; bool applied = false;
for (int i = 0; i < sector->subsectorcount; i++) for (int i = 0; i < sector->subsectorcount; i++)
@ -213,6 +216,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
} }
index += (sub->numlines - 2) * 3; index += (sub->numlines - 2) * 3;
} }
*/
} }
if (!(renderflags&SSRF_RENDER3DPLANES)) if (!(renderflags&SSRF_RENDER3DPLANES))
@ -473,7 +477,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
extsector_t::xfloor &x = sector->e->XFloor; extsector_t::xfloor &x = sector->e->XFloor;
dynlightindex = -1; dynlightindex = -1;
uint8_t &srf = di->sectorrenderflags[sector->sectornum]; uint8_t &srf = di->section_renderflags[level.sections.SectionIndex(section)];
const auto &vp = di->Viewpoint; const auto &vp = di->Viewpoint;
// //

View File

@ -850,7 +850,8 @@ void HWDrawInfo::PrepareUnhandledMissingTextures()
if (seg->linedef->validcount == validcount) continue; // already done if (seg->linedef->validcount == validcount) continue; // already done
seg->linedef->validcount = validcount; 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->frontsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) continue; // out of sight
if (seg->backsector->transdoor) continue; if (seg->backsector->transdoor) continue;
if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue; if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue;