From be3e0cc6956fb2cc910588883c2100de78a40c13 Mon Sep 17 00:00:00 2001 From: Yamagi Date: Sun, 24 Apr 2022 00:01:14 +0200 Subject: [PATCH] Fix `viewsize` not working correctly with the GL renderers. The GL renderers require that the borders are redrawn after every glClear() call, the damage tracking doesn't take that into account. Since the speedup by the damage tracking is neglibiable in the GL renderers, don't use it. Just redraw everything when we're running with everthing which isn't the soft renderer. --- src/client/cl_screen.c | 166 +++++++++++++++++++++---------------- src/client/header/client.h | 1 + 2 files changed, 95 insertions(+), 72 deletions(-) diff --git a/src/client/cl_screen.c b/src/client/cl_screen.c index 69e84e1d..b354e89a 100644 --- a/src/client/cl_screen.c +++ b/src/client/cl_screen.c @@ -734,93 +734,115 @@ SCR_TileClear(void) return; /* full screen cinematic */ } - /* erase rect will be the union of the past three - frames so tripple buffering works properly */ - clear = scr_dirty; - for (i = 0; i < 2; i++) - { - if (scr_old_dirty[i].x1 < clear.x1) + /* This highly complicated pseudo damage tracking is very effective + with the soft render, it gives about 10% speedup. On the GL + renderers the speedup is negligible, but in introduce a bug: + OpenGL requires to redraw the borders after every glClear(), + which the damage tracking doesn't take into account. Fix this + by not using the damage tracking when running somethinge else + than the soft renderer. Just redraw the borders every frame. */ + if (strcmp(vid_renderer->string, "soft") != 0) { + // Top + Draw_TileClear(scr_vrect.x, 0, scr_vrect.width, scr_vrect.y, "backtile"); + + // Bottom + Draw_TileClear(scr_vrect.x, scr_vrect.y + scr_vrect.height, scr_vrect.width, viddef.height, "backtile"); + + // Left + Draw_TileClear(0, 0, scr_vrect.x, viddef.height, "backtile"); + + // Right + Draw_TileClear(scr_vrect.x + scr_vrect.width, 0, viddef.width, viddef.height, "backtile"); + } else { + /* erase rect will be the union of the past three + frames so tripple buffering works properly */ + clear = scr_dirty; + + for (i = 0; i < 2; i++) { - clear.x1 = scr_old_dirty[i].x1; + if (scr_old_dirty[i].x1 < clear.x1) + { + clear.x1 = scr_old_dirty[i].x1; + } + + if (scr_old_dirty[i].x2 > clear.x2) + { + clear.x2 = scr_old_dirty[i].x2; + } + + if (scr_old_dirty[i].y1 < clear.y1) + { + clear.y1 = scr_old_dirty[i].y1; + } + + if (scr_old_dirty[i].y2 > clear.y2) + { + clear.y2 = scr_old_dirty[i].y2; + } } - if (scr_old_dirty[i].x2 > clear.x2) + scr_old_dirty[1] = scr_old_dirty[0]; + scr_old_dirty[0] = scr_dirty; + + scr_dirty.x1 = 9999; + scr_dirty.x2 = -9999; + scr_dirty.y1 = 9999; + scr_dirty.y2 = -9999; + + /* don't bother with anything convered by the console */ + top = (int)(scr_con_current * viddef.height); + + if (top >= clear.y1) { - clear.x2 = scr_old_dirty[i].x2; + clear.y1 = top; } - if (scr_old_dirty[i].y1 < clear.y1) + if (clear.y2 <= clear.y1) { - clear.y1 = scr_old_dirty[i].y1; + return; /* nothing disturbed */ } - if (scr_old_dirty[i].y2 > clear.y2) + top = scr_vrect.y; + bottom = top + scr_vrect.height - 1; + left = scr_vrect.x; + right = left + scr_vrect.width - 1; + + if (clear.y1 < top) { - clear.y2 = scr_old_dirty[i].y2; + /* clear above view screen */ + i = clear.y2 < top - 1 ? clear.y2 : top - 1; + Draw_TileClear(clear.x1, clear.y1, + clear.x2 - clear.x1 + 1, i - clear.y1 + 1, "backtile"); + clear.y1 = top; } - } - scr_old_dirty[1] = scr_old_dirty[0]; - scr_old_dirty[0] = scr_dirty; + if (clear.y2 > bottom) + { + /* clear below view screen */ + i = clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; + Draw_TileClear(clear.x1, i, + clear.x2 - clear.x1 + 1, clear.y2 - i + 1, "backtile"); + clear.y2 = bottom; + } - scr_dirty.x1 = 9999; - scr_dirty.x2 = -9999; - scr_dirty.y1 = 9999; - scr_dirty.y2 = -9999; + if (clear.x1 < left) + { + /* clear left of view screen */ + i = clear.x2 < left - 1 ? clear.x2 : left - 1; + Draw_TileClear(clear.x1, clear.y1, + i - clear.x1 + 1, clear.y2 - clear.y1 + 1, "backtile"); + clear.x1 = left; + } - /* don't bother with anything convered by the console */ - top = (int)(scr_con_current * viddef.height); - - if (top >= clear.y1) - { - clear.y1 = top; - } - - if (clear.y2 <= clear.y1) - { - return; /* nothing disturbed */ - } - - top = scr_vrect.y; - bottom = top + scr_vrect.height - 1; - left = scr_vrect.x; - right = left + scr_vrect.width - 1; - - if (clear.y1 < top) - { - /* clear above view screen */ - i = clear.y2 < top - 1 ? clear.y2 : top - 1; - Draw_TileClear(clear.x1, clear.y1, - clear.x2 - clear.x1 + 1, i - clear.y1 + 1, "backtile"); - clear.y1 = top; - } - - if (clear.y2 > bottom) - { - /* clear below view screen */ - i = clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; - Draw_TileClear(clear.x1, i, - clear.x2 - clear.x1 + 1, clear.y2 - i + 1, "backtile"); - clear.y2 = bottom; - } - - if (clear.x1 < left) - { - /* clear left of view screen */ - i = clear.x2 < left - 1 ? clear.x2 : left - 1; - Draw_TileClear(clear.x1, clear.y1, - i - clear.x1 + 1, clear.y2 - clear.y1 + 1, "backtile"); - clear.x1 = left; - } - - if (clear.x2 > right) - { - /* clear left of view screen */ - i = clear.x1 > right + 1 ? clear.x1 : right + 1; - Draw_TileClear(i, clear.y1, - clear.x2 - i + 1, clear.y2 - clear.y1 + 1, "backtile"); - clear.x2 = right; + if (clear.x2 > right) + { + /* clear left of view screen */ + i = clear.x1 > right + 1 ? clear.x1 : right + 1; + Draw_TileClear(i, clear.y1, + clear.x2 - i + 1, clear.y2 - clear.y1 + 1, "backtile"); + clear.x2 = right; + } } } diff --git a/src/client/header/client.h b/src/client/header/client.h index 04471802..84fa5114 100644 --- a/src/client/header/client.h +++ b/src/client/header/client.h @@ -314,6 +314,7 @@ extern cvar_t *cl_vwep; extern cvar_t *horplus; extern cvar_t *cin_force43; extern cvar_t *vid_fullscreen; +extern cvar_t *vid_renderer; extern cvar_t *cl_kickangles; extern cvar_t *cl_r1q2_lightstyle; extern cvar_t *cl_limitsparksounds;