- use an indexed vertex buffer to render the flats.

Right now this has no advantage but it allows optimizing the data, e.g. rendering an entire sector in one go instead of per subsector.
This commit is contained in:
Christoph Oelckers 2018-05-19 13:33:28 +02:00
commit fd3681dae2
10 changed files with 202 additions and 9 deletions

View file

@ -181,10 +181,9 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t
if (dotop || dobottom)
{
if (dotop) ffloor->top.vindex = vbo_shadowdata.Size();
if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size();
CreateSectorVertices(fsec, plane, false);
auto ndx = CreateSectorVertices(fsec, plane, false);
if (dotop) ffloor->top.vindex = ndx;
if (dobottom) ffloor->bottom.vindex = ndx;
}
}
}
@ -227,6 +226,147 @@ void FFlatVertexGenerator::CreateFlatVertices()
}
}
//==========================================================================
//
// Creates the vertices for one plane in one subsector
//
//==========================================================================
int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen)
{
int idx = ibo_data.Reserve(sub->numlines);
for (unsigned int k = 0; k<sub->numlines; k++)
{
auto ndx = gen.GetIndex(sub->firstline[k].v1);
ibo_data[idx + k] = vi + ndx;
}
return idx;
}
//==========================================================================
//
// Creates the vertices for one plane in one subsector
//
//==========================================================================
int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FFlatVertexGenerator::FIndexGenerationInfo &gen)
{
int rt = ibo_data.Size();
int vi = vbo_shadowdata.Reserve(gen.vertices.Size());
float diff;
// Create the actual vertices.
if (sec->transdoor && floor) diff = -1.f;
else diff = 0.f;
for (unsigned i = 0; i < gen.vertices.Size(); i++)
{
vbo_shadowdata[vi + i].SetFlatVertex(gen.vertices[i], plane);
vbo_shadowdata[vi + i].z += diff;
}
// Create the indices for the subsectors
for (int j = 0; j<sec->subsectorcount; j++)
{
subsector_t *sub = sec->subsectors[j];
CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen);
}
return rt;
}
//==========================================================================
//
//
//
//==========================================================================
int FFlatVertexGenerator::CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FFlatVertexGenerator::FIndexGenerationInfo> &gen)
{
// First calculate the vertices for the sector itself
sec->vboheight[h] = sec->GetPlaneTexZ(h);
sec->vboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]);
// Next are all sectors using this one as heightsec
TArray<sector_t *> &fakes = sec->e->FakeFloor.Sectors;
for (unsigned g = 0; g<fakes.Size(); g++)
{
sector_t *fsec = fakes[g];
fsec->vboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
}
// and finally all attached 3D floors
TArray<sector_t *> &xf = sec->e->XFloor.attached;
for (unsigned g = 0; g<xf.Size(); g++)
{
sector_t *fsec = xf[g];
F3DFloor *ffloor = Find3DFloor(fsec, sec);
if (ffloor != NULL && ffloor->flags & FF_RENDERPLANES)
{
bool dotop = (ffloor->top.model == sec) && (ffloor->top.isceiling == h);
bool dobottom = (ffloor->bottom.model == sec) && (ffloor->bottom.isceiling == h);
if (dotop || dobottom)
{
auto ndx = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
if (dotop) ffloor->top.vindex = ndx;
if (dobottom) ffloor->bottom.vindex = ndx;
}
}
}
sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h];
return sec->vboindex[h];
}
//==========================================================================
//
//
//
//==========================================================================
void FFlatVertexGenerator::CreateIndexedFlatVertices()
{
TArray<FIndexGenerationInfo> gen;
gen.Resize(level.sectors.Size());
// This must be generated up front so that the following code knows how many vertices a sector contains.
for (unsigned i = 0; i < level.sectors.Size(); i++)
{
for (int j = 0; j < level.sectors[i].subsectorcount; j++)
{
auto sub = level.sectors[i].subsectors[j];
for (unsigned k = 0; k < sub->numlines; k++)
{
auto vert = sub->firstline[k].v1;
gen[i].AddVertex(vert);
}
}
}
for (int h = sector_t::floor; h <= sector_t::ceiling; h++)
{
for (auto &sec : level.sectors)
{
CreateIndexedVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor, gen);
}
}
// We need to do a final check for Vavoom water and FF_FIX sectors.
// No new vertices are needed here. The planes come from the actual sector
for (auto &sec : level.sectors)
{
for (auto ff : sec.e->XFloor.ffloors)
{
if (ff->top.model == &sec)
{
ff->top.vindex = sec.vboindex[ff->top.isceiling];
}
if (ff->bottom.model == &sec)
{
ff->bottom.vindex = sec.vboindex[ff->top.isceiling];
}
}
}
}
//==========================================================================
//
//
@ -257,7 +397,7 @@ void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVe
void FFlatVertexGenerator::CreateVertices()
{
vbo_shadowdata.Resize(NUM_RESERVED);
CreateFlatVertices();
CreateIndexedFlatVertices();
}
//==========================================================================

View file

@ -45,9 +45,31 @@ class FFlatVertexGenerator
{
protected:
TArray<FFlatVertex> vbo_shadowdata;
TArray<uint32_t> ibo_data;
// Temporary data for creating an indexed buffer
struct FIndexGenerationInfo
{
TArray<vertex_t *> vertices;
TMap<vertex_t*, uint32_t> vertexmap;
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 ~0;
}
};
void CheckPlanes(sector_t *sector);
public:
enum
@ -70,6 +92,12 @@ private:
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor);
void CreateFlatVertices();
int CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FIndexGenerationInfo &gen);
int CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FIndexGenerationInfo &gen);
int CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FIndexGenerationInfo> &gen);
void CreateIndexedFlatVertices();
void UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map);
protected:
void CreateVertices();