- render sector planes in one draw call.

On a fast and modern graphics card this is a lot faster than doing it per subsector but it may not be without drawbacks on older hardware so it will require some testing on older hardware.
For me Frozen Time's view over the bridge went from 46 fps to 51 fps with this change, the time saved was roughly 2 ms.
This commit is contained in:
Christoph Oelckers 2018-05-19 15:20:46 +02:00
parent 352279a52f
commit 3e204080ae
6 changed files with 72 additions and 10 deletions

View File

@ -121,6 +121,7 @@ struct FDrawInfo : public HWDrawInfo
void ProcessLights(GLFlat *flat, bool istrans);
void DrawSubsector(GLFlat *flat, subsector_t * sub);
void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli);
void SetupSectorLights(GLFlat *flat, int pass, int *dli);
// Sprite drawer
void DrawSprite(GLSprite *sprite, int pass);

View File

@ -62,7 +62,35 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub,
(*dli)++;
return;
}
if (flat->SetupSubsectorLights(pass, sub, lightdata))
if (flat->SetupSectorLights(pass, flat->sector, lightdata))
{
int d = GLRenderer->mLights->UploadLights(lightdata);
if (pass == GLPASS_LIGHTSONLY)
{
GLRenderer->mLights->StoreIndex(d);
}
else
{
gl_RenderState.ApplyLightIndex(d);
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::SetupSectorLights(GLFlat *flat, int pass, int *dli)
{
if (dli != NULL && *dli != -1)
{
gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli));
(*dli)++;
return;
}
if (flat->SetupSectorLights(pass, flat->sector, lightdata))
{
int d = GLRenderer->mLights->UploadLights(lightdata);
if (pass == GLPASS_LIGHTSONLY)
@ -137,15 +165,22 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans)
{
flat->dynlightindex = GLRenderer->mLights->GetIndexPtr();
if (flat->sector->ibocount > 0)
{
SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr);
}
else
{
// Draw the subsectors belonging to this sector
for (int i=0; i< flat->sector->subsectorcount; i++)
for (int i = 0; i < flat->sector->subsectorcount; i++)
{
subsector_t * sub = flat->sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans)
if (gl_drawinfo->ss_renderflags[sub->Index()] & flat->renderflags || istrans)
{
SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr);
}
}
}
// Draw the subsectors assigned to it due to missing textures
if (!(flat->renderflags&SSRF_RENDER3DPLANES))
@ -175,7 +210,18 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
gl_RenderState.Apply();
if (gl.legacyMode) processlights = false;
if (flat->vboindex >= 0)
auto vcount = flat->sector->ibocount;
if (vcount > 0)
{
if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli);
drawcalls.Clock();
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->vboindex);
drawcalls.Unclock();
flatvertices += vcount;
flatprimitives++;
}
else if (flat->vboindex >= 0)
{
int index = flat->vboindex;
for (int i=0; i<flat->sector->subsectorcount; i++)

View File

@ -165,6 +165,7 @@ int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secpl
subsector_t *sub = sec->subsectors[j];
CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen);
}
sec->ibocount = ibo_data.Size() - rt;
return rt;
}

View File

@ -311,7 +311,9 @@ public:
int dynlightindex;
bool SetupLights(int pass, FLightNode *head, FDynLightData &lightdata, int portalgroup);
bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata);
bool SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata);
void PutFlat(HWDrawInfo *di, bool fog = false);
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);

View File

@ -92,14 +92,13 @@ bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
//
//==========================================================================
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
bool GLFlat::SetupLights(int pass, FLightNode * node, FDynLightData &lightdata, int portalgroup)
{
Plane p;
if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return false; // no lights on additively blended surfaces.
lightdata.Clear();
FLightNode * node = sub->lighthead;
while (node)
{
ADynamicLight * light = node->lightsource;
@ -121,13 +120,23 @@ bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &li
}
p.Set(plane.plane.Normal(), plane.plane.fD());
lightdata.GetLight(sub->sector->PortalGroup, p, light, false);
lightdata.GetLight(portalgroup, p, light, false);
node = node->nextLight;
}
return true;
}
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
{
return SetupLights(pass, sub->lighthead, lightdata, sub->sector->PortalGroup);
}
bool GLFlat::SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata)
{
return SetupLights(pass, sec->lighthead, lightdata, sec->PortalGroup);
}
//==========================================================================
//
// GLFlat::PutFlat
@ -252,6 +261,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
sector = &level.sectors[frontsector->sectornum];
extsector_t::xfloor &x = sector->e->XFloor;
dynlightindex = -1;
vertexcount = sector->ibocount;
uint8_t &srf = di->sectorrenderflags[sector->sectornum];

View File

@ -1077,6 +1077,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
{
subsector_t *sub = HandledSubsectors[j];
ss_renderflags[sub->Index()] &= ~SSRF_RENDERCEILING;
sub->sector->ibocount = -1; // cannot render this sector in one go.
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
{
@ -1122,6 +1123,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
{
subsector_t *sub = HandledSubsectors[j];
ss_renderflags[sub->Index()] &= ~SSRF_RENDERFLOOR;
sub->sector->ibocount = -1; // cannot render this sector in one go.
if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
{