Add zbuffer damage checks

Save current player position and compare with a position in the previous
frame, if position is same refresh only changed rectangle in zbuffer.
zBuffer can be damaged by models, particles and static transparent spans.

zBuffer damage is not useful for the screen refresh minimize for now,
as result of explosion can change texture light value.
This commit is contained in:
Denis Pauk 2019-09-05 23:26:11 +03:00
parent aba398c1b9
commit 0bace327f8
6 changed files with 172 additions and 2 deletions

View file

@ -585,6 +585,11 @@ void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, floa
// VID Buffer damage
void VID_DamageBuffer(int u, int v);
// VID zBuffer damage
extern qboolean fastmoving;
void VID_DamageZBuffer(int u, int v);
qboolean VID_CheckDamageZBuffer(int u, int v, int ucount, int vcount);
/*
====================================================================

View file

@ -41,6 +41,12 @@ espan_t *vid_polygon_spans = NULL;
pixel_t *vid_colormap = NULL;
pixel_t *vid_alphamap = NULL;
static int vid_minu, vid_minv, vid_maxu, vid_maxv;
static int vid_zminu, vid_zminv, vid_zmaxu, vid_zmaxv;
// last position on map
static vec3_t lastvieworg;
static vec3_t lastviewangles;
qboolean fastmoving;
refimport_t ri;
@ -206,7 +212,81 @@ static void R_DrawBeam(const entity_t *e);
/*
================
Damage_VIDBuffer
VID_DamageZBuffer
Mark VID Z buffer as damaged and need to be recalculated
================
*/
void
VID_DamageZBuffer(int u, int v)
{
// update U
if (vid_zminu > u)
{
vid_zminu = u;
}
if (vid_zmaxu < u)
{
vid_zmaxu = u;
}
// update V
if (vid_zminv > v)
{
vid_zminv = v;
}
if (vid_zmaxv < v)
{
vid_zmaxv = v;
}
}
// clean z damage state
static void
VID_NoDamageZBuffer(void)
{
vid_zminu = vid.width;
vid_zmaxu = 0;
vid_zminv = vid.height;
vid_zmaxv = 0;
}
qboolean
VID_CheckDamageZBuffer(int u, int v, int ucount, int vcount)
{
if (vid_zminv > (v + vcount) || vid_zmaxv < v)
{
// can be used previous zbuffer
return false;
}
if (vid_zminu > u && vid_zminu > (u + ucount))
{
// can be used previous zbuffer
return false;
}
if (vid_zmaxu < u && vid_zmaxu < (u + ucount))
{
// can be used previous zbuffer
return false;
}
return true;
}
// Need to recalculate whole z buffer
static void
VID_WholeDamageZBuffer(void)
{
vid_zminu = 0;
vid_zmaxu = vid.width;
vid_zminv = 0;
vid_zmaxv = vid.height;
}
/*
================
VID_DamageBuffer
Mark VID buffer as damaged and need to be rewritten
================
@ -1154,6 +1234,16 @@ R_SetLightLevel (const entity_t *currententity)
r_lightlevel->value = 150.0 * light[0];
}
static int
VectorCompareRound(vec3_t v1, vec3_t v2)
{
if ((int)(v1[0] - v2[0]) || (int)(v1[1] - v2[1]) || (int)(v1[2] - v2[2]))
{
return 0;
}
return 1;
}
/*
================
@ -1177,6 +1267,21 @@ RE_RenderFrame (refdef_t *fd)
VectorCopy (fd->vieworg, r_refdef.vieworg);
VectorCopy (fd->viewangles, r_refdef.viewangles);
// compare current possition with old
if (!VectorCompareRound(fd->vieworg, lastvieworg) ||
!VectorCompare(fd->viewangles, lastviewangles))
{
fastmoving = true;
}
else
{
fastmoving = false;
}
// save possition for next check
VectorCopy (fd->vieworg, lastvieworg);
VectorCopy (fd->viewangles, lastviewangles);
if (r_speeds->value || r_dspeeds->value)
r_time1 = SDL_GetTicks();
@ -1199,6 +1304,16 @@ RE_RenderFrame (refdef_t *fd)
de_time1 = se_time2;
}
if (fastmoving)
{
// redraw all
VID_WholeDamageZBuffer();
}
else
{
// No Z rewrite required
VID_NoDamageZBuffer();
}
// Draw enemies, barrel etc...
// Use Z-Buffer mostly in read mode only.
R_DrawEntitiesOnList ();

View file

@ -107,6 +107,10 @@ R_DrawParticle(particle_t *pparticle, int level)
return;
}
// zbuffer particles damage
VID_DamageZBuffer(u, v);
VID_DamageZBuffer(u + count, v + count);
if (custom_particle == 0)
{
switch (level) {

View file

@ -629,6 +629,10 @@ R_PolygonDrawSpans(espan_t *pspan, int iswater, float d_ziorigin, float d_zistep
if (count > 0)
{
// transparent spans damage z buffer
VID_DamageZBuffer(pspan->u, pspan->v);
VID_DamageZBuffer(pspan->u + count, pspan->v);
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;

View file

@ -569,6 +569,7 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
if (lcount > 0)
{
int pos_shift = (pspanpackage->v * vid.width) + pspanpackage->u;
qboolean zdamaged = false;
lpdest = d_viewbuffer + pos_shift;
lpz = d_pzbuffer + pos_shift;
@ -586,6 +587,7 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
*lpdest = vid_alphamap[temp*256 + *lpdest];
*lpz = lzi >> SHIFT16XYZ;
zdamaged = true;
}
lpdest++;
lzi += r_zistepx;
@ -602,6 +604,15 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
ltfrac &= 0xFFFF;
}
} while (--lcount);
if (zdamaged)
{
// damaged only current line
VID_DamageZBuffer(pspanpackage->u, pspanpackage->v);
VID_DamageZBuffer(
pspanpackage->u + d_aspancount - pspanpackage->count,
pspanpackage->v);
}
}
pspanpackage++;
@ -634,6 +645,7 @@ R_PolysetDrawSpansConstant8_66(const entity_t *currententity, spanpackage_t *psp
if (lcount > 0)
{
int pos_shift = (pspanpackage->v * vid.width) + pspanpackage->u;
qboolean zdamaged = false;
lpdest = d_viewbuffer + pos_shift;
lpz = d_pzbuffer + pos_shift;
@ -644,11 +656,21 @@ R_PolysetDrawSpansConstant8_66(const entity_t *currententity, spanpackage_t *psp
if ((lzi >> SHIFT16XYZ) >= *lpz)
{
*lpdest = vid_alphamap[r_aliasblendcolor*256 + *lpdest];
zdamaged = true;
}
lpdest++;
lzi += r_zistepx;
lpz++;
} while (--lcount);
if (zdamaged)
{
// damaged only current line
VID_DamageZBuffer(pspanpackage->u, pspanpackage->v);
VID_DamageZBuffer(
pspanpackage->u + d_aspancount - pspanpackage->count,
pspanpackage->v);
}
}
pspanpackage++;
@ -682,6 +704,7 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp
zvalue_t lzi;
zvalue_t *lpz;
int pos_shift = (pspanpackage->v * vid.width) + pspanpackage->u;
qboolean zdamaged = false;
lpdest = d_viewbuffer + pos_shift;
lpz = d_pzbuffer + pos_shift;
@ -702,6 +725,7 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp
*lpdest = ((byte *)vid_colormap)[*lptex + (llight & 0xFF00)];
*lpz = lzi >> SHIFT16XYZ;
zdamaged = true;
}
lpdest++;
lzi += r_zistepx;
@ -718,6 +742,15 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp
ltfrac &= 0xFFFF;
}
} while (--lcount);
if (zdamaged)
{
// damaged only current line
VID_DamageZBuffer(pspanpackage->u, pspanpackage->v);
VID_DamageZBuffer(
pspanpackage->u + d_aspancount - pspanpackage->count,
pspanpackage->v);
}
}
pspanpackage++;

View file

@ -719,7 +719,7 @@ D_DrawSpansPow2 (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zist
}
// Drawing phrase
if (texture_filtering == 0)
if (texture_filtering == 0 || fastmoving)
{
pdest = D_DrawSpan(pdest, pbase, s, t, sstep, tstep,
spancount);
@ -760,6 +760,15 @@ D_DrawZSpans (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv
float zi;
float du, dv;
if (!VID_CheckDamageZBuffer(pspan->u, pspan->v, pspan->count, 0))
{
continue;
}
// solid map walls damage
VID_DamageZBuffer(pspan->u, pspan->v);
VID_DamageZBuffer(pspan->u + pspan->count, pspan->v);
pdest = d_pzbuffer + (vid.width * pspan->v) + pspan->u;
count = pspan->count;