From 356bdb25a1b4d36db3fe4c3a385a14f34e5e687a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Sep 2022 12:36:59 -0700 Subject: [PATCH 01/13] Add a hitbox renderer to Software mode renderhitbox - Tangible - collision activating objects, minus rings - All - every object - Intangible - the opposite of Tangible, also no rings - Rings - rings --- src/Sourcefile | 1 + src/d_netcmd.c | 1 + src/p_mobj.h | 2 +- src/r_bbox.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++ src/r_things.c | 8 ++ src/r_things.h | 3 + src/screen.h | 2 +- 7 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 src/r_bbox.c diff --git a/src/Sourcefile b/src/Sourcefile index de90bb609..fb08c2171 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -64,6 +64,7 @@ r_skins.c r_sky.c r_splats.c r_things.c +r_bbox.c r_textures.c r_patch.c r_patchrotation.c diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4e90db0dc..ceb94fb1f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -868,6 +868,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); diff --git a/src/p_mobj.h b/src/p_mobj.h index 60601692c..a7e25f461 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -122,7 +122,7 @@ typedef enum MF_AMBIENT = 1<<10, // Slide this object when it hits a wall. MF_SLIDEME = 1<<11, - // Player cheat. + // Don't collide with walls or solid objects. Two MF_NOCLIP objects can't touch each other at all! MF_NOCLIP = 1<<12, // Allow moves to any height, no gravity. For active floaters. MF_FLOAT = 1<<13, diff --git a/src/r_bbox.c b/src/r_bbox.c new file mode 100644 index 000000000..e3b5216bf --- /dev/null +++ b/src/r_bbox.c @@ -0,0 +1,290 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2022 by Kart Krew. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_bbox.c +/// \brief Boundary box (cube) renderer + +#include "doomdef.h" +#include "command.h" +#include "r_local.h" +#include "screen.h" // cv_renderhitbox +#include "v_video.h" // V_DrawFill + +enum { + RENDERHITBOX_OFF, + RENDERHITBOX_TANGIBLE, + RENDERHITBOX_ALL, + RENDERHITBOX_INTANGIBLE, + RENDERHITBOX_RINGS, +}; + +static CV_PossibleValue_t renderhitbox_cons_t[] = { + {RENDERHITBOX_OFF, "Off"}, + {RENDERHITBOX_TANGIBLE, "Tangible"}, + {RENDERHITBOX_ALL, "All"}, + {RENDERHITBOX_INTANGIBLE, "Intangible"}, + {RENDERHITBOX_RINGS, "Rings"}, + {0}}; + +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); + +struct bbox_col { + INT32 x; + INT32 y; + INT32 h; +}; + +struct bbox_config { + fixed_t height; + fixed_t tz; + struct bbox_col col[4]; + UINT8 color; +}; + +static inline void +raster_bbox_seg +( INT32 x, + fixed_t y, + fixed_t h, + UINT8 pixel) +{ + y /= FRACUNIT; + + if (y < 0) + y = 0; + + h = y + (FixedCeil(abs(h)) / FRACUNIT); + + if (h >= viewheight) + h = viewheight; + + while (y < h) + { + topleft[x + y * vid.width] = pixel; + y++; + } +} + +static void +draw_bbox_col +( struct bbox_config * bb, + int p, + fixed_t tx, + fixed_t ty) +{ + struct bbox_col *col = &bb->col[p]; + + fixed_t xscale = FixedDiv(projection, ty); + fixed_t yscale = FixedDiv(projectiony, ty); + + col->x = (centerxfrac + FixedMul(tx, xscale)) / FRACUNIT; + col->y = (centeryfrac - FixedMul(bb->tz, yscale)); + col->h = FixedMul(bb->height, yscale); + + // Using this function is TOO EASY! + V_DrawFill( + viewwindowx + col->x, + viewwindowy + col->y / FRACUNIT, 1, + col->h / FRACUNIT, V_NOSCALESTART | bb->color); +} + +static void +draw_bbox_row +( struct bbox_config * bb, + int p1, + int p2) +{ + struct bbox_col + *a = &bb->col[p1], + *b = &bb->col[p2]; + + INT32 x1, x2; // left, right + INT32 dx; // width + + fixed_t y1, y2; // top, bottom + fixed_t s1, s2; // top and bottom increment + + if (a->x > b->x) + { + struct bbox_col *c = a; + a = b; + b = c; + } + + x1 = a->x; + x2 = b->x; + + if (x2 >= viewwidth) + x2 = viewwidth - 1; + + if (x1 == x2 || x1 >= viewwidth || x2 < 0) + return; + + dx = x2 - x1; + + y1 = a->y; + y2 = b->y; + s1 = (y2 - y1) / dx; + + y2 = y1 + a->h; + s2 = ((b->y + b->h) - y2) / dx; + + // FixedCeil needs a minimum!!! :D :D + + if (s1 == 0) + s1 = 1; + + if (s2 == 0) + s2 = 1; + + if (x1 < 0) + { + y1 -= x1 * s1; + y2 -= x1 * s2; + x1 = 0; + } + + while (x1 < x2) + { + raster_bbox_seg(x1, y1, s1, bb->color); + raster_bbox_seg(x1, y2, s2, bb->color); + + y1 += s1; + y2 += s2; + + x1++; + } +} + +static UINT8 +get_bbox_color (mobj_t *thing) +{ + UINT32 flags = thing->flags; + + if (thing->player) + return 255; // 0FF + + if (flags & (MF_NOCLIPTHING)) + return 7; // BFBFBF + + if (flags & (MF_BOSS|MF_MISSILE|MF_ENEMY|MF_PAIN)) + return 35; // F00 + + if (flags & (MF_SPECIAL|MF_MONITOR)) + return 73; // FF0 + + if (flags & (MF_NOCLIP)) + return 152; // 00F + + return 0; // FFF +} + +void R_DrawThingBoundingBox(mobj_t *thing) +{ + fixed_t rs, rc; // radius offsets + fixed_t gx, gy; // origin + fixed_t tx, ty; // translated coordinates + + struct bbox_config bb = {0}; + + rs = FixedMul(thing->radius, viewsin); + rc = FixedMul(thing->radius, viewcos); + + gx = thing->x - viewx; + gy = thing->y - viewy; + + tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); + ty = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); + + bb.height = thing->height; + bb.tz = (thing->z + bb.height) - viewz; + bb.color = get_bbox_color(thing); + + // 1--3 + // | | + // 0--2 + + // left + + tx -= rs; + ty -= rc; + + draw_bbox_col(&bb, 0, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 1, tx - rc, ty + rs); // top + + // right + + tx += rs + rs; + ty += rc + rc; + + draw_bbox_col(&bb, 2, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 3, tx - rc, ty + rs); // top + + // connect all four columns + + draw_bbox_row(&bb, 0, 1); + draw_bbox_row(&bb, 1, 3); + draw_bbox_row(&bb, 3, 2); + draw_bbox_row(&bb, 2, 0); +} + +static boolean is_tangible (mobj_t *thing) +{ + // These objects can never touch another + if (thing->flags & (MF_NOCLIPTHING)) + { + return false; + } + + // These objects probably do nothing! :D + if ((thing->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE + |MF_PUSHABLE|MF_BOSS|MF_MISSILE|MF_SPRING + |MF_BOUNCE|MF_MONITOR|MF_FIRE|MF_ENEMY + |MF_PAIN|MF_STICKY + |MF_GRENADEBOUNCE)) == 0U) + { + return false; + } + + return true; +} + +boolean R_ThingBoundingBoxVisible(mobj_t *thing) +{ + INT32 cvmode = cv_renderhitbox.value; + + switch (cvmode) + { + case RENDERHITBOX_OFF: + return false; + + case RENDERHITBOX_ALL: + return true; + + case RENDERHITBOX_INTANGIBLE: + return !is_tangible(thing); + + case RENDERHITBOX_TANGIBLE: + // Exclude rings from here, lots of them! + if (thing->type == MT_RING) + { + return false; + } + + return is_tangible(thing); + + case RENDERHITBOX_RINGS: + return (thing->type == MT_RING); + + default: + return false; + } +} diff --git a/src/r_things.c b/src/r_things.c index fed873fd6..65047176d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2939,6 +2939,14 @@ static void R_DrawSprite(vissprite_t *spr) R_DrawFloorSplat(spr); else R_DrawVisSprite(spr); + + if (R_ThingBoundingBoxVisible(spr->mobj)) + { + // fuck you fuck you fuck you FUCK YOU + // (shadows are linked to their mobj) + if (!(spr->cut & SC_SHADOW)) + R_DrawThingBoundingBox(spr->mobj); + } } // Special drawer for precipitation sprites Tails 08-18-2002 diff --git a/src/r_things.h b/src/r_things.h index 35eeb9ce1..4ba649c30 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -66,6 +66,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); +boolean R_ThingBoundingBoxVisible(mobj_t *thing); +void R_DrawThingBoundingBox(mobj_t *thing); + boolean R_ThingVisible (mobj_t *thing); boolean R_ThingVisibleWithinDist (mobj_t *thing, diff --git a/src/screen.h b/src/screen.h index add048b25..5a69be659 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,7 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From 694804cd96cafb1bfb146406f775e2bd23b1fb7a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 10 Sep 2022 21:27:37 -0700 Subject: [PATCH 02/13] Refactor hitbox renderer to project vissprites Properly accounts for portals (skyboxes). --- src/r_bbox.c | 46 ++++++--------- src/r_things.c | 155 ++++++++++++++++++++++++++++++++++++++++++------- src/r_things.h | 9 ++- 3 files changed, 161 insertions(+), 49 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index e3b5216bf..bbac0f56b 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -165,11 +165,11 @@ draw_bbox_row } static UINT8 -get_bbox_color (mobj_t *thing) +get_bbox_color (vissprite_t *vis) { - UINT32 flags = thing->flags; + UINT32 flags = vis->mobjflags; - if (thing->player) + if (vis->mobj->player) return 255; // 0FF if (flags & (MF_NOCLIPTHING)) @@ -187,26 +187,21 @@ get_bbox_color (mobj_t *thing) return 0; // FFF } -void R_DrawThingBoundingBox(mobj_t *thing) +void R_DrawThingBoundingBox(vissprite_t *vis) { - fixed_t rs, rc; // radius offsets - fixed_t gx, gy; // origin - fixed_t tx, ty; // translated coordinates + // radius offsets + fixed_t rs = vis->scale; + fixed_t rc = vis->xscale; - struct bbox_config bb = {0}; + // translated coordinates + fixed_t tx = vis->gx; + fixed_t ty = vis->gy; - rs = FixedMul(thing->radius, viewsin); - rc = FixedMul(thing->radius, viewcos); - - gx = thing->x - viewx; - gy = thing->y - viewy; - - tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); - ty = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); - - bb.height = thing->height; - bb.tz = (thing->z + bb.height) - viewz; - bb.color = get_bbox_color(thing); + struct bbox_config bb = { + .height = vis->thingheight, + .tz = vis->texturemid, + .color = get_bbox_color(vis), + }; // 1--3 // | | @@ -214,18 +209,15 @@ void R_DrawThingBoundingBox(mobj_t *thing) // left - tx -= rs; - ty -= rc; - - draw_bbox_col(&bb, 0, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 0, tx, ty); // bottom draw_bbox_col(&bb, 1, tx - rc, ty + rs); // top // right - tx += rs + rs; - ty += rc + rc; + tx += rs; + ty += rc; - draw_bbox_col(&bb, 2, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 2, tx, ty); // bottom draw_bbox_col(&bb, 3, tx - rc, ty + rs); // top // connect all four columns diff --git a/src/r_things.c b/src/r_things.c index 65047176d..6e4062219 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1424,6 +1424,91 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, objectsdrawn++; } +static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) +{ + fixed_t gx, gy; + fixed_t tx, tz; + + vissprite_t *box; + + if (!R_ThingBoundingBoxVisible(thing)) + { + return; + } + + // 1--3 + // | | + // 0--2 + + // start in the (0) corner + gx = thing->x - thing->radius - viewx; + gy = thing->y - thing->radius - viewy; + + tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); + + // thing is behind view plane? + // if parent vis is visible, ignore this + if (!vis && (tz < FixedMul(MINZ, thing->scale))) + { + return; + } + + tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); + + // too far off the side? + if (!vis && abs(tx) > FixedMul(tz, fovtan)<<2) + { + return; + } + + box = R_NewVisSprite(); + box->mobj = thing; + box->mobjflags = thing->flags; + box->thingheight = thing->height; + box->cut = SC_BBOX; + + box->gx = tx; + box->gy = tz; + + box->scale = 2 * FixedMul(thing->radius, viewsin); + box->xscale = 2 * FixedMul(thing->radius, viewcos); + + box->pz = thing->z; + box->pzt = box->pz + box->thingheight; + + box->gzt = box->pzt; + box->gz = box->pz; + box->texturemid = box->gzt - viewz; + + if (vis) + { + box->x1 = vis->x1; + box->x2 = vis->x2; + box->szt = vis->szt; + box->sz = vis->sz; + + box->sortscale = vis->sortscale; // link sorting to sprite + box->dispoffset = vis->dispoffset + 5; + + box->cut |= SC_LINKDRAW; + } + else + { + fixed_t xscale = FixedDiv(projection, tz); + fixed_t yscale = FixedDiv(projectiony, tz); + fixed_t top = (centeryfrac - FixedMul(box->texturemid, yscale)); + + box->x1 = (centerxfrac + FixedMul(box->gx, xscale)) / FRACUNIT; + box->x2 = box->x1; + + box->szt = top / FRACUNIT; + box->sz = (top + FixedMul(box->thingheight, yscale)) / FRACUNIT; + + box->sortscale = yscale; + box->dispoffset = 0; + } +} + // // R_ProjectSprite // Generates a vissprite for a thing @@ -2181,6 +2266,8 @@ static void R_ProjectSprite(mobj_t *thing) if (oldthing->shadowscale && cv_shadow.value) R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz); + R_ProjectBoundingBox(oldthing, vis); + // Debug ++objectsdrawn; } @@ -2406,8 +2493,26 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) - R_ProjectSprite(thing); + if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist)) + { + const INT32 oldobjectsdrawn = objectsdrawn; + + if (R_ThingVisible(thing)) + { + R_ProjectSprite(thing); + } + + // I'm so smart :^) + if (objectsdrawn == oldobjectsdrawn) + { + /* + Object is invisible OR is off screen but + render its bbox even if the latter because + radius could be bigger than sprite. + */ + R_ProjectBoundingBox(thing, NULL); + } + } } // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off @@ -2495,6 +2600,10 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e if (dsfirst->cut & SC_SHADOW) continue; + // don't connect to your bounding box! + if (dsfirst->cut & SC_BBOX) + continue; + // don't connect if it's not the tracer if (dsfirst->mobj != ds->mobj) continue; @@ -2935,18 +3044,12 @@ static void R_DrawSprite(vissprite_t *spr) mfloorclip = spr->clipbot; mceilingclip = spr->cliptop; - if (spr->cut & SC_SPLAT) + if (spr->cut & SC_BBOX) + R_DrawThingBoundingBox(spr); + else if (spr->cut & SC_SPLAT) R_DrawFloorSplat(spr); else R_DrawVisSprite(spr); - - if (R_ThingBoundingBoxVisible(spr->mobj)) - { - // fuck you fuck you fuck you FUCK YOU - // (shadows are linked to their mobj) - if (!(spr->cut & SC_SHADOW)) - R_DrawThingBoundingBox(spr->mobj); - } } // Special drawer for precipitation sprites Tails 08-18-2002 @@ -3182,9 +3285,13 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) for (; clippedvissprites < visspritecount; clippedvissprites++) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; - INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; - R_ClipVisSprite(spr, x1, x2, dsstart, portal); + + if (!(spr->cut & SC_BBOX)) // Do not clip bounding boxes + { + INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; + INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; + R_ClipVisSprite(spr, x1, x2, dsstart, portal); + } } } @@ -3198,16 +3305,11 @@ boolean R_ThingVisible (mobj_t *thing) )); } -boolean R_ThingVisibleWithinDist (mobj_t *thing, +boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist, fixed_t hoop_limit_dist) { - fixed_t approx_dist; - - if (! R_ThingVisible(thing)) - return false; - - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); + const fixed_t approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (thing->sprite == SPR_HOOP) { @@ -3223,6 +3325,17 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing, return true; } +// For OpenGL, TODO: REMOVE!! +boolean R_ThingVisibleWithinDist (mobj_t *thing, + fixed_t limit_dist, + fixed_t hoop_limit_dist) +{ + if (! R_ThingVisible(thing)) + return false; + + return R_ThingWithinDist(thing, limit_dist, hoop_limit_dist); +} + /* Check if precipitation may be drawn from our current view. */ boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t limit_dist) diff --git a/src/r_things.h b/src/r_things.h index 4ba649c30..f1855dfd8 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -67,10 +67,13 @@ void R_InitSprites(void); void R_ClearSprites(void); boolean R_ThingBoundingBoxVisible(mobj_t *thing); -void R_DrawThingBoundingBox(mobj_t *thing); boolean R_ThingVisible (mobj_t *thing); +boolean R_ThingWithinDist (mobj_t *thing, + fixed_t draw_dist, + fixed_t nights_draw_dist); + boolean R_ThingVisibleWithinDist (mobj_t *thing, fixed_t draw_dist, fixed_t nights_draw_dist); @@ -135,6 +138,7 @@ typedef enum SC_SHADOW = 1<<10, SC_SHEAR = 1<<11, SC_SPLAT = 1<<12, + SC_BBOX = 1<<13, // masks SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_FLAGMASK = ~SC_CUTMASK @@ -224,6 +228,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); boolean R_SpriteIsFlashing(vissprite_t *vis); + +void R_DrawThingBoundingBox(vissprite_t *spr); + UINT8 *R_GetSpriteTranslation(vissprite_t *vis); // ---------- From 99653de13431d91ae9259dfd6c002861ea396156 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 06:25:08 -0700 Subject: [PATCH 03/13] Do not render viewmobj or skybox viewpoint hitbox If you are a spectator (or in first person), the hitbox exists right ontop of you and hitboxes don't render correctly if they are too close to the viewpoint. --- src/r_bbox.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/r_bbox.c b/src/r_bbox.c index bbac0f56b..3d46aa566 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -253,6 +253,27 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing) { INT32 cvmode = cv_renderhitbox.value; + // Do not render bbox for these + switch (thing->type) + { + default: + // First person / awayviewmobj -- rendering + // a bbox too close to the viewpoint causes + // anomalies and these are exactly on the + // viewpoint! + if (thing != r_viewmobj) + { + break; + } + // FALLTHRU + + case MT_SKYBOX: + // Ditto for skybox viewpoint but because they + // are rendered using portals in Software, + // r_viewmobj does not point here. + return false; + } + switch (cvmode) { case RENDERHITBOX_OFF: From 7527fdbb568358bc56755220945255c8adaefeae Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 07:08:10 -0700 Subject: [PATCH 04/13] Remedy some quirky rendering of hitboxes if your viewpoint is too close It's not correct but it's better than before. --- src/r_bbox.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 3d46aa566..e1749225c 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -82,8 +82,13 @@ draw_bbox_col { struct bbox_col *col = &bb->col[p]; - fixed_t xscale = FixedDiv(projection, ty); - fixed_t yscale = FixedDiv(projectiony, ty); + fixed_t xscale, yscale; + + if (ty < FRACUNIT) // projection breaks down here + ty = FRACUNIT; + + xscale = FixedDiv(projection, ty); + yscale = FixedDiv(projectiony, ty); col->x = (centerxfrac + FixedMul(tx, xscale)) / FRACUNIT; col->y = (centeryfrac - FixedMul(bb->tz, yscale)); From 5b53017a09eb70c94ffaae259350d765de901988 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:54:15 -0700 Subject: [PATCH 05/13] r_opengl: add PF_WireFrame and SHADER_NONE Draw lines instead of tris and disable shader entirely. --- src/hardware/hw_defs.h | 4 +++- src/hardware/r_opengl/r_opengl.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index fca9b80a3..bb27c34fa 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -136,6 +136,7 @@ typedef struct // Predefined shader types enum { + SHADER_NONE = -1, SHADER_DEFAULT = 0, SHADER_FLOOR, @@ -237,7 +238,8 @@ enum EPolyFlags PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y PF_ForceWrapX = 0x00020000, // Forces repeat texture on X PF_ForceWrapY = 0x00040000, // Forces repeat texture on Y - PF_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything. + PF_Ripple = 0x00100000, // Water ripple effect. The current backend doesn't use it for anything. + PF_WireFrame = 0x00200000, // Draws vertices as lines instead of triangles }; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9d1630abb..3a97f9315 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1030,6 +1030,12 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole EXPORT void HWRAPI(SetShader) (int type) { #ifdef GL_SHADERS + if (type == SHADER_NONE) + { + HWRAPI(UnSetShader)(); + return; + } + if (gl_allowshaders != HWD_SHADEROPTION_OFF) { gl_shader_t *shader = gl_shaderstate.current; @@ -2290,7 +2296,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + pglDrawArrays(PolyFlags & PF_WireFrame ? GL_LINES : GL_TRIANGLE_FAN, 0, iNumPts); if (PolyFlags & PF_RemoveYWrap) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); From bfaf2bc6f3635f3e95b8bf6172d9a2f6d3e22edf Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:57:58 -0700 Subject: [PATCH 06/13] OpenGL hitbox renderer I apologize for that vertex array. --- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 118 +++++++++++++++++++++++++++++++++++++++-- src/r_bbox.c | 9 ++-- src/r_things.h | 1 + 4 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 1ec9101c3..504cdf148 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -81,6 +81,7 @@ typedef struct gl_vissprite_s boolean flip, vflip; boolean precip; // Tails 08-25-2002 + boolean bbox; boolean rotated; UINT8 translucency; //alpha level 0-255 diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3cb7275a0..24d5925bd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -66,6 +66,7 @@ static void HWR_ProjectSprite(mobj_t *thing); #ifdef HWPRECIP static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); #endif +static void HWR_ProjectBoundingBox(mobj_t *thing); void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, @@ -4036,6 +4037,54 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) HWR_LinkDrawHackAdd(wallVerts, spr); } +static void HWR_DrawBoundingBox(gl_vissprite_t *vis) +{ + FOutVector v[24]; + FSurfaceInfo Surf = {0}; + + // + // create a cube (side view) + // + // 5--4 3 + // | + // | + // 0--1 2 + // + // repeat this 4 times (overhead) + // + // + // 17 20 21 11 + // 16 15 14 10 + // 27 22 *--* 07 12 + // | | + // 26 23 *--* 06 13 + // 24 00 01 02 + // 25 05 04 03 + // + + v[000].x = v[005].x = v[015].x = v[016].x = v[017].x = v[020].x = + v[022].x = v[023].x = v[024].x = v[025].x = v[026].x = v[027].x = vis->x1; // west + + v[001].x = v[002].x = v[003].x = v[004].x = v[006].x = v[007].x = + v[010].x = v[011].x = v[012].x = v[013].x = v[014].x = v[021].x = vis->x2; // east + + v[000].z = v[001].z = v[002].z = v[003].z = v[004].z = v[005].z = + v[006].z = v[013].z = v[023].z = v[024].z = v[025].z = v[026].z = vis->z1; // south + + v[007].z = v[010].z = v[011].z = v[012].z = v[014].z = v[015].z = + v[016].z = v[017].z = v[020].z = v[021].z = v[022].z = v[027].z = vis->z2; // north + + v[000].y = v[001].y = v[002].y = v[006].y = v[007].y = v[010].y = + v[014].y = v[015].y = v[016].y = v[022].y = v[023].y = v[024].y = vis->gz; // bottom + + v[003].y = v[004].y = v[005].y = v[011].y = v[012].y = v[013].y = + v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top + + Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj)); + + HWR_ProcessPolygon(&Surf, v, 24, PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); +} + // -----------------+ // HWR_DrawSprite : Draw flat sprites // : (monsters, bonuses, weapons, lights, ...) @@ -4480,9 +4529,16 @@ static int CompareVisSprites(const void *p1, const void *p2) int transparency1; int transparency2; + int linkdraw1; + int linkdraw2; + + // bbox doesn't need to be sorted + if (spr1->bbox || spr2->bbox) + return 0; + // check for precip first, because then sprX->mobj is actually a precipmobj_t and does not have flags2 or tracer - int linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; - int linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer; + linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; + linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer; // ^ is the XOR operation // if comparing a linkdraw and non-linkdraw sprite or 2 linkdraw sprites with different tracers, then use @@ -4852,6 +4908,9 @@ static void HWR_DrawSprites(void) for (i = 0; i < gl_visspritecount; i++) { gl_vissprite_t *spr = gl_vsprorder[i]; + if (spr->bbox) + HWR_DrawBoundingBox(spr); + else #ifdef HWPRECIP if (spr->precip) HWR_DrawPrecipitationSprite(spr); @@ -4951,8 +5010,15 @@ static void HWR_AddSprites(sector_t *sec) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) - HWR_ProjectSprite(thing); + if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist)) + { + if (R_ThingVisible(thing)) + { + HWR_ProjectSprite(thing); + } + + HWR_ProjectBoundingBox(thing); + } } #ifdef HWPRECIP @@ -5462,6 +5528,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->vflip = vflip; vis->precip = false; + vis->bbox = false; vis->angle = interp.angle; } @@ -5584,6 +5651,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height); vis->precip = true; + vis->bbox = false; // okay... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) @@ -5597,6 +5665,48 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) } #endif +static void HWR_ProjectBoundingBox(mobj_t *thing) +{ + gl_vissprite_t *vis; + float tr_x, tr_y; + float tz; + float rad; + + if (!thing) + return; + + if (!R_ThingBoundingBoxVisible(thing)) + return; + + // transform the origin point + tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; + + // rotation around vertical axis + tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); + + // thing is behind view plane? + if (tz < ZCLIP_PLANE) + return; + + tr_x += gl_viewx; + tr_y += gl_viewy; + + rad = FIXED_TO_FLOAT(thing->radius); + + vis = HWR_NewVisSprite(); + vis->x1 = tr_x - rad; + vis->x2 = tr_x + rad; + vis->z1 = tr_y - rad; + vis->z2 = tr_y + rad; + vis->gz = FIXED_TO_FLOAT(thing->z); + vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height); + vis->mobj = thing; + + vis->precip = false; + vis->bbox = true; +} + // ========================================================================== // Sky dome rendering, ported from PrBoom+ // ========================================================================== diff --git a/src/r_bbox.c b/src/r_bbox.c index e1749225c..9108ec0c0 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -169,12 +169,11 @@ draw_bbox_row } } -static UINT8 -get_bbox_color (vissprite_t *vis) +UINT8 R_GetBoundingBoxColor(mobj_t *thing) { - UINT32 flags = vis->mobjflags; + UINT32 flags = thing->flags; - if (vis->mobj->player) + if (thing->player) return 255; // 0FF if (flags & (MF_NOCLIPTHING)) @@ -205,7 +204,7 @@ void R_DrawThingBoundingBox(vissprite_t *vis) struct bbox_config bb = { .height = vis->thingheight, .tz = vis->texturemid, - .color = get_bbox_color(vis), + .color = R_GetBoundingBoxColor(vis->mobj), }; // 1--3 diff --git a/src/r_things.h b/src/r_things.h index f1855dfd8..9aa1003da 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -66,6 +66,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); +UINT8 R_GetBoundingBoxColor(mobj_t *thing); boolean R_ThingBoundingBoxVisible(mobj_t *thing); boolean R_ThingVisible (mobj_t *thing); From 7855bae8a13f4787ecc6badb11fbf2c96e582515 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:59:25 -0700 Subject: [PATCH 07/13] Remove R_ThingVisibleWithinDist It's no longer used! --- src/r_things.c | 11 ----------- src/r_things.h | 4 ---- 2 files changed, 15 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 6e4062219..953f12ea6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3325,17 +3325,6 @@ boolean R_ThingWithinDist (mobj_t *thing, return true; } -// For OpenGL, TODO: REMOVE!! -boolean R_ThingVisibleWithinDist (mobj_t *thing, - fixed_t limit_dist, - fixed_t hoop_limit_dist) -{ - if (! R_ThingVisible(thing)) - return false; - - return R_ThingWithinDist(thing, limit_dist, hoop_limit_dist); -} - /* Check if precipitation may be drawn from our current view. */ boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t limit_dist) diff --git a/src/r_things.h b/src/r_things.h index 9aa1003da..84d5967ab 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -75,10 +75,6 @@ boolean R_ThingWithinDist (mobj_t *thing, fixed_t draw_dist, fixed_t nights_draw_dist); -boolean R_ThingVisibleWithinDist (mobj_t *thing, - fixed_t draw_dist, - fixed_t nights_draw_dist); - boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t precip_draw_dist); From f7fa9fcc190f0ba4fb8ad3ef15465f6c37ea9443 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 12 Sep 2022 12:58:39 +0100 Subject: [PATCH 08/13] Fix compilation issue with nested defines for r_opengl.c UnSetShader --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 3a97f9315..98929f030 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1032,7 +1032,7 @@ EXPORT void HWRAPI(SetShader) (int type) #ifdef GL_SHADERS if (type == SHADER_NONE) { - HWRAPI(UnSetShader)(); + UnSetShader(); return; } From 8430dfa0639c06b0d48b34a76e1abe14af4885ce Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 25 Oct 2022 12:03:18 -0700 Subject: [PATCH 09/13] Fix copyright year in r_bbox.c --- src/r_bbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 9108ec0c0..cc225eaec 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -2,8 +2,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2021 by Sonic Team Junior. // Copyright (C) 2022 by Kart Krew. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From 5411d522e5143caed15d23693bba175f0b1d19f3 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 26 Oct 2022 13:53:35 -0700 Subject: [PATCH 10/13] r_bbox.c: use size_t to access column array --- src/r_bbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index cc225eaec..b45007bb2 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -76,7 +76,7 @@ raster_bbox_seg static void draw_bbox_col ( struct bbox_config * bb, - int p, + size_t p, fixed_t tx, fixed_t ty) { @@ -104,8 +104,8 @@ draw_bbox_col static void draw_bbox_row ( struct bbox_config * bb, - int p1, - int p2) + size_t p1, + size_t p2) { struct bbox_col *a = &bb->col[p1], From b8a25ae53c5db7017adf2411ebae254ac2ed85c1 Mon Sep 17 00:00:00 2001 From: sphere Date: Tue, 13 Jun 2023 00:05:58 +0000 Subject: [PATCH 11/13] Add interpolation to hitbox viewer, tweak hitbox colors --- src/d_netcmd.c | 1 + src/hardware/hw_main.c | 19 ++++++++++++++++--- src/r_bbox.c | 14 ++++++++++++-- src/r_things.c | 22 ++++++++++++++++++---- src/screen.h | 2 +- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 420621a77..0f859a569 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -873,6 +873,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderhitboxinterpolation); CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 09235ce62..e7550fd6e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5686,9 +5686,22 @@ static void HWR_ProjectBoundingBox(mobj_t *thing) if (!R_ThingBoundingBoxVisible(thing)) return; + // uncapped/interpolation + boolean interpolate = cv_renderhitboxinterpolation.value; + interpmobjstate_t interp = {0}; + + if (R_UsingFrameInterpolation() && !paused && interpolate) + { + R_InterpolateMobjState(thing, rendertimefrac, &interp); + } + else + { + R_InterpolateMobjState(thing, FRACUNIT, &interp); + } + // transform the origin point - tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; - tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; + tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy; // rotation around vertical axis tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); @@ -5707,7 +5720,7 @@ static void HWR_ProjectBoundingBox(mobj_t *thing) vis->x2 = tr_x + rad; vis->z1 = tr_y - rad; vis->z2 = tr_y + rad; - vis->gz = FIXED_TO_FLOAT(thing->z); + vis->gz = FIXED_TO_FLOAT(interp.z); vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height); vis->mobj = thing; diff --git a/src/r_bbox.c b/src/r_bbox.c index b45007bb2..7ed693fd0 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -35,6 +35,7 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {0}}; consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); struct bbox_col { INT32 x; @@ -179,12 +180,21 @@ UINT8 R_GetBoundingBoxColor(mobj_t *thing) if (flags & (MF_NOCLIPTHING)) return 7; // BFBFBF - if (flags & (MF_BOSS|MF_MISSILE|MF_ENEMY|MF_PAIN)) + if (flags & (MF_BOSS|MF_ENEMY)) return 35; // F00 + if (flags & (MF_MISSILE|MF_PAIN)) + return 54; // F70 + if (flags & (MF_SPECIAL|MF_MONITOR)) return 73; // FF0 + if (flags & MF_PUSHABLE) + return 112; // 0F0 + + if (flags & (MF_SPRING)) + return 181; // F0F + if (flags & (MF_NOCLIP)) return 152; // 00F @@ -299,7 +309,7 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing) return is_tangible(thing); case RENDERHITBOX_RINGS: - return (thing->type == MT_RING); + return (thing->type == MT_RING || thing->type == MT_BLUESPHERE); default: return false; diff --git a/src/r_things.c b/src/r_things.c index 7eecb041e..38237e5b3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1436,19 +1436,33 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) return; } + // uncapped/interpolation + boolean interpolate = cv_renderhitboxinterpolation.value; + interpmobjstate_t interp = {0}; + + // do interpolation + if (R_UsingFrameInterpolation() && !paused && interpolate) + { + R_InterpolateMobjState(thing, rendertimefrac, &interp); + } + else + { + R_InterpolateMobjState(thing, FRACUNIT, &interp); + } + // 1--3 // | | // 0--2 // start in the (0) corner - gx = thing->x - thing->radius - viewx; - gy = thing->y - thing->radius - viewy; + gx = interp.x - thing->radius - viewx; + gy = interp.y - thing->radius - viewy; tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); // thing is behind view plane? // if parent vis is visible, ignore this - if (!vis && (tz < FixedMul(MINZ, thing->scale))) + if (!vis && (tz < FixedMul(MINZ, interp.scale))) { return; } @@ -1473,7 +1487,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) box->scale = 2 * FixedMul(thing->radius, viewsin); box->xscale = 2 * FixedMul(thing->radius, viewcos); - box->pz = thing->z; + box->pz = interp.z; box->pzt = box->pz + box->thingheight; box->gzt = box->pzt; diff --git a/src/screen.h b/src/screen.h index a0e04f85e..b021a419d 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,7 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_renderhitboxinterpolation, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From 8b931da6f30414376d22181b558e176a5a408f7c Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Fri, 14 Jul 2023 12:51:16 +0000 Subject: [PATCH 12/13] Draw hitboxes last in OpenGL --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e7550fd6e..bb05f2a6d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4532,9 +4532,9 @@ static int CompareVisSprites(const void *p1, const void *p2) int linkdraw1; int linkdraw2; - // bbox doesn't need to be sorted + // draw bbox after everything else if (spr1->bbox || spr2->bbox) - return 0; + return (spr1->bbox - spr2->bbox); // check for precip first, because then sprX->mobj is actually a precipmobj_t and does not have flags2 or tracer linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; From 34ce172a907778bc4c220dba02cd5ab3761ae761 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 14 Jul 2023 15:03:43 +0200 Subject: [PATCH 13/13] Allow toggling PF_NoDepthTest for OpenGL hitboxes --- src/d_netcmd.c | 1 + src/hardware/hw_main.c | 4 ++-- src/r_bbox.c | 3 ++- src/screen.h | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0f859a569..c3cd7daa8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -874,6 +874,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); CV_RegisterVar(&cv_renderhitboxinterpolation); + CV_RegisterVar(&cv_renderhitboxgldepth); CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bb05f2a6d..194d68c54 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4081,8 +4081,8 @@ static void HWR_DrawBoundingBox(gl_vissprite_t *vis) v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj)); - - HWR_ProcessPolygon(&Surf, v, 24, PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); + + HWR_ProcessPolygon(&Surf, v, 24, (cv_renderhitboxgldepth.value ? 0 : PF_NoDepthTest)|PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); } // -----------------+ diff --git a/src/r_bbox.c b/src/r_bbox.c index 7ed693fd0..59d0893c4 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -34,8 +34,9 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {RENDERHITBOX_RINGS, "Rings"}, {0}}; -consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT, renderhitbox_cons_t, NULL); consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_renderhitboxgldepth = CVAR_INIT ("renderhitbox_gldepth", "Off", CV_SAVE, CV_OnOff, NULL); struct bbox_col { INT32 x; diff --git a/src/screen.h b/src/screen.h index b021a419d..9222805fb 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,8 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_renderhitboxinterpolation, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale;