Share R_CullBox and R_SetFrustum

0cd2eed28b
This commit is contained in:
Denis Pauk 2023-01-22 00:30:47 +02:00
parent 4c6bc1a14c
commit 4bcaa90af7
5 changed files with 78 additions and 66 deletions

View file

@ -219,5 +219,8 @@ extern void R_MarkLights (dlight_t *light, int bit, mnode_t *node, int r_dlightf
extern struct image_s *R_TextureAnimation(const entity_t *currententity,
const mtexinfo_t *tex);
extern qboolean R_AreaVisible(const byte *areabits, mleaf_t *pleaf);
extern qboolean R_CullBox(vec3_t mins, vec3_t maxs, cplane_t *frustum);
extern void R_SetFrustum(vec3_t vup, vec3_t vpn, vec3_t vright, vec3_t r_origin,
float fov_x, float fov_y, cplane_t *frustum);
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */

View file

@ -116,3 +116,68 @@ R_MarkLights(dlight_t *light, int bit, mnode_t *node, int r_dlightframecount,
R_MarkLights(light, bit, node->children[1], r_dlightframecount,
mark_surface_lights);
}
/*
* Returns true if the box is completely outside the frustom
*/
qboolean
R_CullBox(vec3_t mins, vec3_t maxs, cplane_t *frustum)
{
int i;
for (i = 0; i < 4; i++)
{
if (BOX_ON_PLANE_SIDE(mins, maxs, frustum + i) == 2)
{
return true;
}
}
return false;
}
static int
R_SignbitsForPlane(cplane_t *out)
{
int bits, j;
/* for fast box on planeside test */
bits = 0;
for (j = 0; j < 3; j++)
{
if (out->normal[j] < 0)
{
bits |= 1 << j;
}
}
return bits;
}
void
R_SetFrustum(vec3_t vup, vec3_t vpn, vec3_t vright, vec3_t r_origin,
float fov_x, float fov_y, cplane_t *frustum)
{
int i;
/* rotate VPN right by FOV_X/2 degrees */
RotatePointAroundVector(frustum[0].normal, vup, vpn,
-(90 - fov_x / 2));
/* rotate VPN left by FOV_X/2 degrees */
RotatePointAroundVector(frustum[1].normal,
vup, vpn, 90 - fov_x / 2);
/* rotate VPN up by FOV_X/2 degrees */
RotatePointAroundVector(frustum[2].normal,
vright, vpn, 90 - fov_y / 2);
/* rotate VPN down by FOV_X/2 degrees */
RotatePointAroundVector(frustum[3].normal, vright, vpn,
-(90 - fov_y / 2));
for (i = 0; i < 4; i++)
{
frustum[i].type = PLANE_ANYZ;
frustum[i].dist = DotProduct(r_origin, frustum[i].normal);
frustum[i].signbits = R_SignbitsForPlane(&frustum[i]);
}
}

View file

@ -135,6 +135,7 @@ extern cvar_t *r_farsee;
extern cvar_t *vk_overbrightbits;
extern cvar_t *r_validation;
extern cvar_t *r_cull;
extern cvar_t *vk_picmip;
extern cvar_t *r_palettedtexture;
extern cvar_t *vk_flashblend;
@ -211,7 +212,6 @@ void R_DrawAlphaSurfaces (void);
void RE_InitParticleTexture (void);
void Draw_InitLocal (void);
void Vk_SubdivideSurface (msurface_t *fa, model_t *loadmodel);
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
void R_RotateForEntity (entity_t *e, float *mvMatrix);
void R_MarkLeaves (void);

View file

@ -79,7 +79,7 @@ cvar_t *r_drawworld;
static cvar_t *r_speeds;
static cvar_t *r_fullbright;
cvar_t *r_novis;
static cvar_t *r_nocull;
cvar_t *r_cull;
cvar_t *r_lerpmodels;
cvar_t *r_lefthand;
cvar_t *r_vsync;
@ -144,27 +144,6 @@ PFN_vkGetMoltenVKConfigurationMVK qvkGetMoltenVKConfigurationMVK;
PFN_vkSetMoltenVKConfigurationMVK qvkSetMoltenVKConfigurationMVK;
#endif
/*
=================
R_CullBox
Returns true if the box is completely outside the frustom
=================
*/
qboolean R_CullBox (vec3_t mins, vec3_t maxs)
{
int i;
if (r_nocull->value)
return false;
for (i=0 ; i<4 ; i++)
if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
return true;
return false;
}
void R_RotateForEntity (entity_t *e, float *mvMatrix)
{
Mat_Rotate(mvMatrix, -e->angles[2], 1.f, 0.f, 0.f);
@ -638,45 +617,6 @@ R_PolyBlend (void)
//=======================================================================
static int
SignbitsForPlane (cplane_t *out)
{
int bits, j;
// for fast box on planeside test
bits = 0;
for (j = 0; j<3; j++)
{
if (out->normal[j] < 0)
bits |= 1 << j;
}
return bits;
}
static void
R_SetFrustum (float fovx, float fovy)
{
// rotate VPN right by FOV_X/2 degrees
RotatePointAroundVector(frustum[0].normal, vup, vpn, -(90 - fovx / 2));
// rotate VPN left by FOV_X/2 degrees
RotatePointAroundVector(frustum[1].normal, vup, vpn, 90 - fovx / 2);
// rotate VPN up by FOV_X/2 degrees
RotatePointAroundVector(frustum[2].normal, vright, vpn, 90 - fovy / 2);
// rotate VPN down by FOV_X/2 degrees
RotatePointAroundVector(frustum[3].normal, vright, vpn, -(90 - fovy / 2));
for (int i = 0; i < 4; i++)
{
frustum[i].type = PLANE_ANYZ;
frustum[i].dist = DotProduct(r_origin, frustum[i].normal);
frustum[i].signbits = SignbitsForPlane(&frustum[i]);
}
}
//=======================================================================
/*
===============
R_SetupFrame
@ -929,7 +869,8 @@ R_SetupVulkan (void)
r_proj_aspect = (float)r_newrefdef.width / r_newrefdef.height;
Mat_Perspective(r_projection_matrix, r_vulkan_correction, r_proj_fovy, r_proj_aspect, 4, dist);
R_SetFrustum(r_proj_fovx, r_proj_fovy);
R_SetFrustum(vup, vpn, vright, r_origin, r_proj_fovx, r_proj_fovy,
frustum);
// set up view matrix
Mat_Identity(r_view_matrix);
@ -1177,7 +1118,7 @@ R_Register( void )
r_drawentities = ri.Cvar_Get("r_drawentities", "1", 0);
r_drawworld = ri.Cvar_Get("r_drawworld", "1", 0);
r_novis = ri.Cvar_Get("r_novis", "0", 0);
r_nocull = ri.Cvar_Get("r_nocull", "0", 0);
r_cull = ri.Cvar_Get("r_cull", "1", 0);
r_lerpmodels = ri.Cvar_Get("r_lerpmodels", "1", 0);
r_speeds = ri.Cvar_Get("r_speeds", "0", 0);
r_lightlevel = ri.Cvar_Get("r_lightlevel", "0", 0);

View file

@ -746,8 +746,10 @@ void R_DrawBrushModel (entity_t *currententity, model_t *currentmodel)
VectorAdd(currententity->origin, currentmodel->maxs, maxs);
}
if (R_CullBox(mins, maxs))
if (r_cull->value && R_CullBox(mins, maxs, frustum))
{
return;
}
memset(vk_lms.lightmap_surfaces, 0, sizeof(vk_lms.lightmap_surfaces));
@ -802,7 +804,8 @@ static void R_RecursiveWorldNode (mnode_t *node, entity_t *currententity)
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3))
if (r_cull->value && R_CullBox (node->minmaxs, node->minmaxs+3, frustum))
return;
// if a leaf node, draw stuff