Make scenecache less... flickery.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5953 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-07-06 00:12:20 +00:00
parent 18c0e79c47
commit 139b916e46
7 changed files with 63 additions and 27 deletions

View File

@ -1799,7 +1799,7 @@ void CL_ClearState (qboolean gamestart)
CL_ClearParseState();
CL_ClearTEnts();
CL_ClearCustomTEnts();
Surf_ClearLightmaps();
Surf_ClearSceneCache();
#ifdef HEXEN2
T_FreeInfoStrings();
#endif

View File

@ -3384,6 +3384,8 @@ static void Surf_SimpleWorld_Q3BSP(struct webostate_s *es, qbyte *pvs)
}
if (eb->inefficient)
{ //slow path that needs to create a single ram-backed mesh
//FIXME: for portal/refract surfaces, track surfaces for refract pvs info
if (eb->maxverts < eb->m.numvertexes + mesh->numvertexes)
{
//FIXME: pre-allocate
@ -3426,11 +3428,12 @@ void R_GenWorldEBO(void *ctx, void *data, size_t a, size_t b)
struct webostate_s *es = ctx;
qbyte *pvs;
int sortid;
batch_t *batch;
qboolean inefficient;
if (!es->numbatches)
{
int sortid;
batch_t *batch;
es->numbatches = es->wmodel->numbatches;
for (i = 0; i < es->numbatches; i++)
@ -3445,19 +3448,6 @@ void R_GenWorldEBO(void *ctx, void *data, size_t a, size_t b)
memset(&es->batches[i].m, 0, sizeof(es->batches[i].m));
memset(&es->batches[i].vbo, 0, sizeof(es->batches[i].vbo));
}
//set to 2 to reveal the inefficient surfaces...
if (r_temporalscenecache.ival < 2)
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = currentmodel->batches[sortid]; batch != NULL; batch = batch->next)
{
#if MAXRLIGHTMAPS > 1
if (batch->lmlightstyle[1] != INVALID_LIGHTSTYLE || batch->vtlightstyle[1] != INVALID_VLIGHTSTYLE)
continue; //not supported here, show fallback shader instead (would work but with screwed lighting, we prefer a better-defined result).
#endif
if (!batch->shader || batch->shader->flags & SHADER_NEEDSARRAYS)
es->batches[batch->user.bmodel.ebobatch].inefficient = true;
}
}
else
{
@ -3469,6 +3459,43 @@ void R_GenWorldEBO(void *ctx, void *data, size_t a, size_t b)
}
}
//set to 2 to reveal the inefficient surfaces...
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = es->wmodel->batches[sortid]; batch != NULL; batch = batch->next)
{
inefficient = false;
if (r_temporalscenecache.ival < 2)
{
#if MAXRLIGHTMAPS > 1
if (batch->lmlightstyle[1] != INVALID_LIGHTSTYLE || batch->vtlightstyle[1] != INVALID_VLIGHTSTYLE)
continue; //not supported here, show fallback shader instead (would work but with screwed lighting, we prefer a better-defined result).
#endif
if (!batch->shader)
inefficient = true;
else if (batch->shader->flags & SHADER_NEEDSARRAYS)
inefficient = true;
}
if (es->batches[batch->user.bmodel.ebobatch].inefficient != inefficient)
{
es->batches[batch->user.bmodel.ebobatch].inefficient = inefficient;
if (!inefficient)
{
if (es->batches[i].inefficient)
{
BZ_Free(es->batches[i].m.xyz_array);
BZ_Free(es->batches[i].m.st_array);
BZ_Free(es->batches[i].m.lmst_array[0]);
BZ_Free(es->batches[i].m.normals_array);
BZ_Free(es->batches[i].m.snormals_array);
BZ_Free(es->batches[i].m.tnormals_array);
}
BZ_Free(es->batches[i].idxbuffer);
memset(&es->batches[i], 0, sizeof(es->batches[i]));
}
}
}
//maybe we should just use fatpvs instead, and wait for completion when outside?
if (r_novis.ival)
{
@ -3554,23 +3581,26 @@ void Surf_DrawWorld (void)
r_temporalscenecache.ival = sc;
r_temporalscenecache.modified = true;
}
if (r_temporalscenecache.modified || r_dynamic.modified)
{
r_dynamic.modified = false;
r_temporalscenecache.modified = false;
Sh_CheckSettings(); //fiddle with r_dynamic vs r_shadow_realtime_dlight.
}
if (!r_temporalscenecache.ival)
{
r_dynamic.ival = r_dynamic.value;
webo_blocklightmapupdates = false;
COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true);
while (webostates)
{
void *webostate = webostates;
webostates = webostates->next;
R_DestroyWorldEBO(webostate);
}
webo_blocklightmapupdates = false;
}
if (!r_temporalscenecache.ival)
{
r_dynamic.ival = r_dynamic.value;
}
else if (!r_refdef.recurse && currentmodel->type == mod_brush)
{
@ -3673,7 +3703,7 @@ void Surf_DrawWorld (void)
if (kill->lastvalid < cls.framecount-5 && kill->wmodel == currentmodel && kill != webostate)
{ //this one looks old... kill it.
if (webogenerating)
R_DestroyWorldEBO(webogenerating); //can't use more than one!
R_DestroyWorldEBO(webogenerating); //can't use more than one, tidy up stale ones
webogenerating = kill;
*link = kill->next;
}
@ -4486,7 +4516,7 @@ void Surf_BuildModelLightmaps (model_t *m)
m->lightmaps.first = newfirst;
}
void Surf_ClearLightmaps(void)
void Surf_ClearSceneCache(void)
{
#ifdef THREADEDWORLD
while(webogenerating)

View File

@ -358,7 +358,7 @@ void Surf_WipeStains(void);
void Surf_DeInit(void);
void Surf_Clear(struct model_s *mod);
void Surf_BuildLightmaps(void); //enables Surf_BuildModelLightmaps, calls it for each bsp.
void Surf_ClearLightmaps(void); //stops Surf_BuildModelLightmaps from working.
void Surf_ClearSceneCache(void); //stops Surf_BuildModelLightmaps from working.
void Surf_BuildModelLightmaps (struct model_s *m); //rebuild lightmaps for a single bsp. beware of submodels.
void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);

View File

@ -1439,7 +1439,7 @@ void R_ShutdownRenderer(qboolean devicetoo)
if (host_basepal)
BZ_Free(host_basepal);
host_basepal = NULL;
Surf_ClearLightmaps();
Surf_ClearSceneCache();
RQ_Shutdown();

View File

@ -303,6 +303,7 @@ void Mod_RebuildLightmaps (void)
}
}
#ifdef HAVE_CLIENT
void Mod_ResortShaders(void)
{
//called when some shader changed its sort key.
@ -332,7 +333,10 @@ void Mod_ResortShaders(void)
}
}
}
Surf_ClearSceneCache(); //make sure their caches are updated.
}
#endif
const char *Mod_GetEntitiesString(model_t *mod)
{

View File

@ -3914,7 +3914,7 @@ void Sh_CheckSettings(void)
}
r_dynamic.ival = r_dynamic.value;
if (canshadowless && r_dynamic.value && !r_shadow_realtime_dlight.ival && (r_temporalscenecache.ival || (cl.worldmodel && cl.worldmodel->fromgame == fg_quake3)))
if (canshadowless && r_dynamic.value && !r_shadow_realtime_dlight.ival && (r_temporalscenecache.ival))// || (cl.worldmodel && cl.worldmodel->fromgame == fg_quake3)))
{
r_shadow_realtime_dlight.ival = 1;
r_shadow_realtime_dlight_shadows.ival = 0;

View File

@ -3266,6 +3266,8 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommandAD ("mapedit", SV_Map_f, SV_Map_c, "Loads the named map without any gamecode active.");
#ifdef Q3SERVER
Cmd_AddCommandAD ("spmap", SV_Map_f, SV_Map_c, NULL);
Cmd_AddCommandAD ("spdevmap", SV_Map_f, SV_Map_c, NULL);
Cmd_AddCommandAD ("devmap", SV_Map_f, SV_Map_c, NULL);
#endif
Cmd_AddCommandAD ("gamemap", SV_Map_f, SV_Map_c, NULL);
Cmd_AddCommandAD ("changelevel", SV_Map_f, SV_Map_c, NULL);