From 74352832136e6439cc0afd1841074d35c55f7399 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 5 Sep 2019 23:09:12 +0300 Subject: [PATCH 1/3] Skip flush screen after palette change Fixes issue with black screen on new game after show the introduction video --- src/client/refresh/soft/sw_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index 3196f9aa..552d197d 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -1923,12 +1923,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(); } From aba398c1b990290d821c1587def867fc947fcdc4 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 10 Sep 2019 08:20:22 +0300 Subject: [PATCH 2/3] dump current possition in world --- src/client/cl_view.c | 42 +++++++++++++++++++------------------ src/client/vid/header/ref.h | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/client/cl_view.c b/src/client/cl_view.c index 914e31fc..db2d7d29 100644 --- a/src/client/cl_view.c +++ b/src/client/cl_view.c @@ -565,18 +565,18 @@ V_RenderView(float stereo_separation) sizeof(cl.refdef.entities[0]), (int (*)(const void *, const void *)) entitycmpfnc); } else if (cl.frame.valid && cl_paused->value && gl1_stereo->value) { - // We need to adjust the refdef in stereo mode when paused. - vec3_t tmp; - CL_CalcViewValues(); - VectorScale( cl.v_right, stereo_separation, tmp ); - VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); - - cl.refdef.vieworg[0] += 1.0/16; - cl.refdef.vieworg[1] += 1.0/16; - cl.refdef.vieworg[2] += 1.0/16; + // We need to adjust the refdef in stereo mode when paused. + vec3_t tmp; + CL_CalcViewValues(); + VectorScale( cl.v_right, stereo_separation, tmp ); + VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); - cl.refdef.time = cl.time*0.001; - } + cl.refdef.vieworg[0] += 1.0/16; + cl.refdef.vieworg[1] += 1.0/16; + cl.refdef.vieworg[2] += 1.0/16; + + cl.refdef.time = cl.time*0.001; + } cl.refdef.x = scr_vrect.x; cl.refdef.y = scr_vrect.y; @@ -606,7 +606,7 @@ V_RenderView(float stereo_separation) SCR_DrawCrosshair(); } -void +void V_Render3dCrosshair(void) { trace_t crosshair_trace; @@ -614,7 +614,7 @@ V_Render3dCrosshair(void) crosshair_3d = Cvar_Get("crosshair_3d", "0", CVAR_ARCHIVE); crosshair_3d_glow = Cvar_Get("crosshair_3d_glow", "0", CVAR_ARCHIVE); - + if(crosshair_3d->value || crosshair_3d_glow->value){ VectorMA(cl.refdef.vieworg,8192,cl.v_forward,end); @@ -626,10 +626,10 @@ V_Render3dCrosshair(void) crosshair_3d_glow_b = Cvar_Get("crosshair_3d_glow_b", "4", CVAR_ARCHIVE); V_AddLight( - crosshair_trace.endpos, - crosshair_3d_glow->value, - crosshair_3d_glow_r->value, - crosshair_3d_glow_g->value, + crosshair_trace.endpos, + crosshair_3d_glow->value, + crosshair_3d_glow_r->value, + crosshair_3d_glow_g->value, crosshair_3d_glow_b->value ); } @@ -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 diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index 4900718d..acfa7205 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -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 */ From 0bace327f8de77234f92ef9044868f5110092ebd Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 5 Sep 2019 23:26:11 +0300 Subject: [PATCH 3/3] 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. --- src/client/refresh/soft/header/local.h | 5 ++ src/client/refresh/soft/sw_main.c | 117 ++++++++++++++++++++++++- src/client/refresh/soft/sw_part.c | 4 + src/client/refresh/soft/sw_poly.c | 4 + src/client/refresh/soft/sw_polyset.c | 33 +++++++ src/client/refresh/soft/sw_scan.c | 11 ++- 6 files changed, 172 insertions(+), 2 deletions(-) diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index f125a31a..e4f6dccb 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -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); + /* ==================================================================== diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index 552d197d..4bf05472 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -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 (); diff --git a/src/client/refresh/soft/sw_part.c b/src/client/refresh/soft/sw_part.c index f875440c..be283d22 100644 --- a/src/client/refresh/soft/sw_part.c +++ b/src/client/refresh/soft/sw_part.c @@ -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) { diff --git a/src/client/refresh/soft/sw_poly.c b/src/client/refresh/soft/sw_poly.c index 99869134..72eb984c 100644 --- a/src/client/refresh/soft/sw_poly.c +++ b/src/client/refresh/soft/sw_poly.c @@ -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; diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index 017ff003..b6e0d2d1 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -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++; diff --git a/src/client/refresh/soft/sw_scan.c b/src/client/refresh/soft/sw_scan.c index b536839e..db1f699f 100644 --- a/src/client/refresh/soft/sw_scan.c +++ b/src/client/refresh/soft/sw_scan.c @@ -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;