From 0cd2eed28bbe3a1792fab81034a65fc2969fd093 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 5 Nov 2022 10:55:57 +0200 Subject: [PATCH] Share R_CullBox and R_SetFrustum --- src/client/refresh/files/surf.c | 65 +++++++++++++++++++++ src/client/refresh/gl1/gl1_main.c | 78 ++------------------------ src/client/refresh/gl1/gl1_surf.c | 4 +- src/client/refresh/gl1/header/local.h | 3 +- src/client/refresh/gl3/gl3_main.c | 57 ++----------------- src/client/refresh/gl3/gl3_surf.c | 28 +-------- src/client/refresh/gl3/header/local.h | 3 +- src/client/refresh/ref_shared.h | 3 + src/client/refresh/soft/header/local.h | 2 + src/client/refresh/soft/sw_bsp.c | 9 +++ src/client/refresh/soft/sw_main.c | 10 +++- src/common/cvar.c | 1 + 12 files changed, 106 insertions(+), 157 deletions(-) diff --git a/src/client/refresh/files/surf.c b/src/client/refresh/files/surf.c index 7f89ae79..93d1e04a 100644 --- a/src/client/refresh/files/surf.c +++ b/src/client/refresh/files/surf.c @@ -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]); + } +} diff --git a/src/client/refresh/gl1/gl1_main.c b/src/client/refresh/gl1/gl1_main.c index 508c0e7e..7c1a6aed 100644 --- a/src/client/refresh/gl1/gl1_main.c +++ b/src/client/refresh/gl1/gl1_main.c @@ -120,7 +120,7 @@ cvar_t *gl1_ztrick; cvar_t *gl_zfix; cvar_t *gl_finish; cvar_t *r_clear; -cvar_t *gl_cull; +cvar_t *r_cull; cvar_t *gl_polyblend; cvar_t *gl1_flashblend; cvar_t *gl1_saturatelighting; @@ -143,30 +143,6 @@ cvar_t *gl1_stereo_convergence; refimport_t ri; -/* - * Returns true if the box is completely outside the frustom - */ -qboolean -R_CullBox(vec3_t mins, vec3_t maxs) -{ - int i; - - if (!gl_cull->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) { @@ -642,51 +618,6 @@ R_PolyBlend(void) glColor4f(1, 1, 1, 1); } -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(void) -{ - int i; - - /* rotate VPN right by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[0].normal, vup, vpn, - -(90 - r_newrefdef.fov_x / 2)); - /* rotate VPN left by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[1].normal, - vup, vpn, 90 - r_newrefdef.fov_x / 2); - /* rotate VPN up by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[2].normal, - vright, vpn, 90 - r_newrefdef.fov_y / 2); - /* rotate VPN down by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[3].normal, vright, vpn, - -(90 - r_newrefdef.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]); - } -} - void R_SetupFrame(void) { @@ -849,7 +780,7 @@ R_SetupGL(void) glGetFloatv(GL_MODELVIEW_MATRIX, r_world_matrix); /* set drawing parms */ - if (gl_cull->value) + if (r_cull->value) { glEnable(GL_CULL_FACE); } @@ -1120,7 +1051,8 @@ R_RenderView(refdef_t *fd) R_SetupFrame(); - R_SetFrustum(); + R_SetFrustum(vup, vpn, vright, r_origin, r_newrefdef.fov_x, r_newrefdef.fov_y, + frustum); R_SetupGL(); @@ -1266,7 +1198,7 @@ R_Register(void) gl_zfix = ri.Cvar_Get("gl_zfix", "0", 0); gl_finish = ri.Cvar_Get("gl_finish", "0", CVAR_ARCHIVE); r_clear = ri.Cvar_Get("r_clear", "0", 0); - gl_cull = ri.Cvar_Get("gl_cull", "1", 0); + r_cull = ri.Cvar_Get("r_cull", "1", 0); gl_polyblend = ri.Cvar_Get("gl_polyblend", "1", 0); gl1_flashblend = ri.Cvar_Get("gl1_flashblend", "0", 0); r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE); diff --git a/src/client/refresh/gl1/gl1_surf.c b/src/client/refresh/gl1/gl1_surf.c index ec42112d..e7fa2342 100644 --- a/src/client/refresh/gl1/gl1_surf.c +++ b/src/client/refresh/gl1/gl1_surf.c @@ -734,7 +734,7 @@ R_DrawBrushModel(entity_t *currententity, const model_t *currentmodel) VectorAdd(currententity->origin, currentmodel->maxs, maxs); } - if (R_CullBox(mins, maxs)) + if (r_cull->value && R_CullBox(mins, maxs, frustum)) { return; } @@ -809,7 +809,7 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node) return; } - if (R_CullBox(node->minmaxs, node->minmaxs + 3)) + if (r_cull->value && R_CullBox(node->minmaxs, node->minmaxs + 3, frustum)) { return; } diff --git a/src/client/refresh/gl1/header/local.h b/src/client/refresh/gl1/header/local.h index 11af0396..d7b764c7 100644 --- a/src/client/refresh/gl1/header/local.h +++ b/src/client/refresh/gl1/header/local.h @@ -213,7 +213,7 @@ extern cvar_t *gl_finish; extern cvar_t *gl1_ztrick; extern cvar_t *gl_zfix; extern cvar_t *r_clear; -extern cvar_t *gl_cull; +extern cvar_t *r_cull; extern cvar_t *gl1_polyblend; extern cvar_t *gl1_flashblend; extern cvar_t *r_modulate; @@ -267,7 +267,6 @@ void R_DrawAlphaSurfaces(void); void R_InitParticleTexture(void); void Draw_InitLocal(void); void R_SubdivideSurface(model_t *loadmodel, msurface_t *fa); -qboolean R_CullBox(vec3_t mins, vec3_t maxs); void R_RotateForEntity(entity_t *e); void R_MarkLeaves(void); diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index c4729205..8af3ce4d 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -121,7 +121,7 @@ cvar_t *r_novis; cvar_t *r_speeds; cvar_t *gl_finish; -cvar_t *gl_cull; +cvar_t *r_cull; cvar_t *gl_zfix; cvar_t *r_fullbright; cvar_t *r_modulate; @@ -262,7 +262,7 @@ GL3_Register(void) r_modulate = ri.Cvar_Get("r_modulate", "1", CVAR_ARCHIVE); gl_zfix = ri.Cvar_Get("gl_zfix", "0", 0); r_clear = ri.Cvar_Get("r_clear", "0", 0); - gl_cull = ri.Cvar_Get("gl_cull", "1", 0); + r_cull = ri.Cvar_Get("r_cull", "1", 0); r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", 0); r_novis = ri.Cvar_Get("r_novis", "0", 0); r_speeds = ri.Cvar_Get("r_speeds", "0", 0); @@ -302,7 +302,6 @@ GL3_Register(void) //gl_zfix = ri.Cvar_Get("gl_zfix", "0", 0); //gl_finish = ri.Cvar_Get("gl_finish", "0", CVAR_ARCHIVE); r_clear = ri.Cvar_Get("r_clear", "0", 0); -// gl_cull = ri.Cvar_Get("gl_cull", "1", 0); //gl1_flashblend = ri.Cvar_Get("gl1_flashblend", "0", 0); //gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE); @@ -1023,7 +1022,7 @@ GL3_DrawParticles(void) glDisable(GL_BLEND); glDepthMask(GL_TRUE); #ifdef YQ2_GL3_GLES - if(gl_cull->value != 0.0f) + if(r_cull->value != 0.0f) glEnable(GL_CULL_FACE); #else glDisable(GL_PROGRAM_POINT_SIZE); @@ -1139,51 +1138,6 @@ GL3_DrawEntitiesOnList(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 -SetFrustum(void) -{ - int i; - - /* rotate VPN right by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[0].normal, vup, vpn, - -(90 - gl3_newrefdef.fov_x / 2)); - /* rotate VPN left by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[1].normal, - vup, vpn, 90 - gl3_newrefdef.fov_x / 2); - /* rotate VPN up by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[2].normal, - vright, vpn, 90 - gl3_newrefdef.fov_y / 2); - /* rotate VPN down by FOV_X/2 degrees */ - RotatePointAroundVector(frustum[3].normal, vright, vpn, - -(90 - gl3_newrefdef.fov_y / 2)); - - for (i = 0; i < 4; i++) - { - frustum[i].type = PLANE_ANYZ; - frustum[i].dist = DotProduct(gl3_origin, frustum[i].normal); - frustum[i].signbits = SignbitsForPlane(&frustum[i]); - } -} - static void SetupFrame(void) { @@ -1502,7 +1456,7 @@ SetupGL(void) GL3_UpdateUBO3D(); /* set drawing parms */ - if (gl_cull->value) + if (r_cull->value) { glEnable(GL_CULL_FACE); } @@ -1659,7 +1613,8 @@ GL3_RenderView(refdef_t *fd) SetupFrame(); - SetFrustum(); + R_SetFrustum(vup, vpn, vright, gl3_origin, + gl3_newrefdef.fov_x, gl3_newrefdef.fov_y, frustum); SetupGL(); diff --git a/src/client/refresh/gl3/gl3_surf.c b/src/client/refresh/gl3/gl3_surf.c index 124090d3..7688645f 100644 --- a/src/client/refresh/gl3/gl3_surf.c +++ b/src/client/refresh/gl3/gl3_surf.c @@ -132,30 +132,6 @@ void GL3_SurfShutdown(void) gl3state.vaoAlias = 0; } -/* - * Returns true if the box is completely outside the frustom - */ -static qboolean -CullBox(vec3_t mins, vec3_t maxs) -{ - int i; - - if (!gl_cull->value) - { - return false; - } - - for (i = 0; i < 4; i++) - { - if (BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2) - { - return true; - } - } - - return false; -} - static void SetLightFlags(msurface_t *surf) { @@ -597,7 +573,7 @@ GL3_DrawBrushModel(entity_t *e, gl3model_t *currentmodel) VectorAdd(e->origin, currentmodel->maxs, maxs); } - if (CullBox(mins, maxs)) + if (r_cull->value && R_CullBox(mins, maxs, frustum)) { return; } @@ -664,7 +640,7 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node) return; } - if (CullBox(node->minmaxs, node->minmaxs + 3)) + if (r_cull->value && R_CullBox(node->minmaxs, node->minmaxs + 3, frustum)) { return; } diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index b1e00f12..5b9475c5 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -381,7 +381,6 @@ GL3_BindEBO(GLuint ebo) extern void GL3_BufferAndDraw3D(const gl3_3D_vtx_t* verts, int numVerts, GLenum drawMode); -extern qboolean GL3_CullBox(vec3_t mins, vec3_t maxs); extern void GL3_RotateForEntity(entity_t *e); // gl3_sdl.c @@ -523,7 +522,7 @@ extern cvar_t *gl_nobind; extern cvar_t *r_lockpvs; extern cvar_t *r_novis; -extern cvar_t *gl_cull; +extern cvar_t *r_cull; extern cvar_t *gl_zfix; extern cvar_t *r_fullbright; diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index 79d166ac..e3836d6b 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -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_ */ diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index 3f5995cf..b76a32da 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -441,10 +441,12 @@ extern cvar_t *r_lerpmodels; extern cvar_t *r_lightlevel; extern cvar_t *r_modulate; extern cvar_t *r_fixsurfsky; +extern cvar_t *r_cull; extern clipplane_t view_clipplanes[4]; extern int *pfrustum_indexes[4]; +extern cplane_t frustum[4]; //============================================================================= diff --git a/src/client/refresh/soft/sw_bsp.c b/src/client/refresh/soft/sw_bsp.c index 3b0a6bcf..2b98e1aa 100644 --- a/src/client/refresh/soft/sw_bsp.c +++ b/src/client/refresh/soft/sw_bsp.c @@ -464,10 +464,19 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod mleaf_t *pleaf; if (node->contents == CONTENTS_SOLID) + { return; // solid + } if (node->visframe != r_visframecount) + { return; + } + + if (r_cull->value && R_CullBox(node->minmaxs, node->minmaxs + 3, frustum)) + { + return; + } // cull the clipping planes if not trivial accept // FIXME: the compiler is doing a lousy job of optimizing here; it could be diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index d6e1193d..6d926a33 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -174,6 +174,7 @@ static cvar_t *vid_gamma; static cvar_t *r_lockpvs; static cvar_t *r_palettedtexture; +cvar_t *r_cull; // sw_vars.c @@ -414,6 +415,7 @@ R_RegisterVariables (void) r_customheight = ri.Cvar_Get("r_customheight", "768", CVAR_ARCHIVE); r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE); r_palettedtexture = ri.Cvar_Get("r_palettedtexture", "0", 0); + r_cull = ri.Cvar_Get("r_cull", "1", 0); vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE ); vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE ); @@ -1008,7 +1010,7 @@ R_FindTopnode (vec3_t mins, vec3_t maxs) } splitplane = node->plane; - sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane); + sides = BOX_ON_PLANE_SIDE(mins, maxs, splitplane); if (sides == 3) return node; // this is the splitter @@ -1299,6 +1301,9 @@ VectorCompareRound(const vec3_t v1, const vec3_t v2) return 1; } +cplane_t frustum[4]; + + /* ================ RE_RenderFrame @@ -1343,6 +1348,9 @@ RE_RenderFrame (refdef_t *fd) R_SetupFrame (); + R_SetFrustum(vup, vpn, vright, r_origin, r_newrefdef.fov_x, r_newrefdef.fov_y, + frustum); + // Using the current view cluster (r_viewcluster), retrieve and decompress // the PVS (Potentially Visible Set) R_MarkLeaves (); // done here so we know if we're in water diff --git a/src/common/cvar.c b/src/common/cvar.c index 75505372..d8bfac13 100644 --- a/src/common/cvar.c +++ b/src/common/cvar.c @@ -90,6 +90,7 @@ replacement_t replacements[] = { {"gl_anisotropic", "r_anisotropic"}, {"gl_lightmap", "r_lighmap"}, {"gl1_polyblend", "gl_polyblend"}, + {"gl_cull", "r_cull"}, {"intensity", "gl1_intensity"} };