Make 3D floors cull areas below or above them to reduce overdraw

This commit is contained in:
Jaime Passos 2020-07-22 21:36:19 -03:00
parent 735942a437
commit d141ca450b
4 changed files with 59 additions and 6 deletions

View file

@ -149,6 +149,8 @@ consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo,
consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_3dfloors = {"3dfloors", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ffloorclip = {"ffloorclip", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -1590,6 +1592,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_shadow);
CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_3dfloors);
CV_RegisterVar(&cv_ffloorclip);
CV_RegisterVar(&cv_cam_dist); CV_RegisterVar(&cv_cam_dist);
CV_RegisterVar(&cv_cam_still); CV_RegisterVar(&cv_cam_still);

View file

@ -103,6 +103,7 @@ extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow; extern consvar_t cv_shadow;
extern consvar_t cv_3dfloors, cv_ffloorclip;
extern consvar_t cv_translucency; extern consvar_t cv_translucency;
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_fov; extern consvar_t cv_fov;

View file

@ -688,6 +688,14 @@ static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
} while (sprtopscreen < sprbotscreen); } while (sprtopscreen < sprbotscreen);
} }
// Returns true if the fake floor will be translucent
static boolean R_IsFFloorTranslucent(ffloor_t *pfloor)
{
if (pfloor->flags & FF_TRANSLUCENT)
return (pfloor->alpha < 243);
return false;
}
// //
// R_RenderThickSideRange // R_RenderThickSideRange
// Renders all the thick sides in the given range. // Renders all the thick sides in the given range.
@ -1200,6 +1208,14 @@ static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bott
if (pl->bottom[x] < bottom) pl->bottom[x] = bottom; if (pl->bottom[x] < bottom) pl->bottom[x] = bottom;
} }
// R_FFloorCanClip
//
// Returns true if a fake floor can clip a column away.
static boolean R_FFloorCanClip(visffloor_t *floor)
{
return (cv_ffloorclip.value && !R_IsFFloorTranslucent(floor->ffloor) && !floor->polyobj);
}
// //
// R_RenderSegLoop // R_RenderSegLoop
// Draws zero, one, or two textures (and possibly a masked // Draws zero, one, or two textures (and possibly a masked
@ -1283,6 +1299,8 @@ static void R_RenderSegLoop (void)
if (numffloors) if (numffloors)
{ {
INT16 fftop, ffbottom;
firstseg->frontscale[rw_x] = frontscale[rw_x]; firstseg->frontscale[rw_x] = frontscale[rw_x];
top = ceilingclip[rw_x]+1; // PRBoom top = ceilingclip[rw_x]+1; // PRBoom
bottom = floorclip[rw_x]-1; // PRBoom bottom = floorclip[rw_x]-1; // PRBoom
@ -1313,8 +1331,23 @@ static void R_RenderSegLoop (void)
{ {
if (top_w <= bottom_w) if (top_w <= bottom_w)
{ {
ffloor[i].plane->top[rw_x] = (INT16)top_w; fftop = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; ffbottom = (INT16)bottom_w;
ffloor[i].plane->top[rw_x] = fftop;
ffloor[i].plane->bottom[rw_x] = ffbottom;
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "bottom" is the top pixel of the floor column
if (ffbottom >= bottom && R_FFloorCanClip(&ffloor[i]))
{
floorclip[rw_x] = fftop-1;
if (yh > floorclip[rw_x])
yh = floorclip[rw_x];
if (markfloor && floorplane)
floorplane->top[rw_x] = bottom;
}
} }
} }
} }
@ -1339,8 +1372,23 @@ static void R_RenderSegLoop (void)
{ {
if (top_w <= bottom_w) if (top_w <= bottom_w)
{ {
ffloor[i].plane->top[rw_x] = (INT16)top_w; fftop = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; ffbottom = (INT16)bottom_w;
ffloor[i].plane->top[rw_x] = fftop;
ffloor[i].plane->bottom[rw_x] = ffbottom;
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "top" is the height of the ceiling column
if (fftop <= top && R_FFloorCanClip(&ffloor[i]))
{
ceilingclip[rw_x] = ffbottom+1;
if (yl < ceilingclip[rw_x])
yl = ceilingclip[rw_x];
if (markceiling && ceilingplane)
ceilingplane->bottom[rw_x] = top;
}
} }
} }
} }

View file

@ -2251,7 +2251,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
// Add the 3D floors, thicksides, and masked textures... // Add the 3D floors, thicksides, and masked textures...
for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];)
{ {
if (ds->numthicksides) if (ds->numthicksides && cv_3dfloors.value)
{ {
for (i = 0; i < ds->numthicksides; i++) for (i = 0; i < ds->numthicksides; i++)
{ {
@ -2280,7 +2280,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
entry = R_CreateDrawNode(head); entry = R_CreateDrawNode(head);
entry->seg = ds; entry->seg = ds;
} }
if (ds->numffloorplanes) if (ds->numffloorplanes && cv_3dfloors.value)
{ {
for (i = 0; i < ds->numffloorplanes; i++) for (i = 0; i < ds->numffloorplanes; i++)
{ {