Merge pull request #442 from 0lvin/for_review

Add zBuffer damage logic
This commit is contained in:
Yamagi 2019-09-12 10:05:32 +02:00 committed by GitHub
commit 5d97bbff8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 196 additions and 26 deletions

View file

@ -655,9 +655,11 @@ V_Render3dCrosshair(void)
void
V_Viewpos_f(void)
{
Com_Printf("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0],
(int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2],
(int)cl.refdef.viewangles[YAW]);
Com_Printf("position: %i %i %i, angles: %i %i %i\n",
(int)cl.refdef.vieworg[0], (int)cl.refdef.vieworg[1],
(int)cl.refdef.vieworg[2],
(int)cl.refdef.viewangles[PITCH], (int)cl.refdef.viewangles[YAW],
(int)cl.refdef.viewangles[ROLL]);
}
void

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 ();
@ -1923,12 +2038,10 @@ RE_CleanFrame(void)
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
return;
}
// only cleanup texture without flush texture to screen
memset(pixels, 0, pitch * vid.height);
SDL_UnlockTexture(texture);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
// All changes flushed
VID_NoDamageBuffer();
}

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;

View file

@ -99,7 +99,7 @@ typedef struct {
float vieworg[3];
float viewangles[3];
float blend[4]; /* rgba 0-1 full screen blend */
float time; /* time is uesed to auto animate */
float time; /* time is used to auto animate */
int rdflags; /* RDF_UNDERWATER, etc */
byte *areabits; /* if not NULL, only areas with set bits will be drawn */