]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
render: Refactor R_CullBox to simplify it.
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 11 Apr 2021 15:18:38 +0000 (15:18 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 11 Apr 2021 15:18:38 +0000 (15:18 +0000)
Use bitwise comparisons instead of the previous switch. Skip the
nearclip plane on the view frustum.

From divVerent. Cleaned up further by Cloudwalk.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@13108 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
gl_rsurf.c
r_shadow.c
render.h

index 3b9994f0ffdc2bf250d0ed538979a772de0f60d0..6b37179ea9134dcb790596e71f9e9212fd6eec55 100644 (file)
@@ -3449,104 +3449,44 @@ void Render_Init(void)
        Mod_RenderInit();
 }
 
-int R_CullBox(const vec3_t mins, const vec3_t maxs)
+static void R_GetCornerOfBox(vec3_t out, const vec3_t mins, const vec3_t maxs, int signbits)
 {
-       int i;
-       mplane_t *p;
-       if (r_trippy.integer)
-               return false;
-       for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
-       {
-               p = r_refdef.view.frustum + i;
-               switch(p->signbits)
-               {
-               default:
-               case 0:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 1:
-                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 2:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 3:
-                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 4:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 5:
-                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 6:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 7:
-                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               }
-       }
-       return false;
+       out[0] = ((signbits & 1) ? mins : maxs)[0];
+       out[1] = ((signbits & 2) ? mins : maxs)[1];
+       out[2] = ((signbits & 4) ? mins : maxs)[2];
 }
 
-int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
+static qbool _R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes, int ignore)
 {
        int i;
        const mplane_t *p;
+       vec3_t corner;
        if (r_trippy.integer)
                return false;
        for (i = 0;i < numplanes;i++)
        {
+               if(i == ignore)
+                       continue;
                p = planes + i;
-               switch(p->signbits)
-               {
-               default:
-               case 0:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 1:
-                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 2:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 3:
-                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
-                               return true;
-                       break;
-               case 4:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 5:
-                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 6:
-                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               case 7:
-                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
-                               return true;
-                       break;
-               }
+               R_GetCornerOfBox(corner, mins, maxs, p->signbits);
+               if (DotProduct(p->normal, corner) < p->dist)
+                       return true;
        }
        return false;
 }
 
+qbool R_CullFrustum(const vec3_t mins, const vec3_t maxs)
+{
+       // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
+       return _R_CullBox(mins, maxs, r_refdef.view.numfrustumplanes, r_refdef.view.frustum, 4);
+}
+
+qbool R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
+{
+       // nothing to ignore
+       return _R_CullBox(mins, maxs, numplanes, planes, -1);
+}
+
 //==================================================================================
 
 // LadyHavoc: this stores temporary data used within the same frame
@@ -4088,7 +4028,7 @@ static void R_View_UpdateEntityVisible (void)
                                continue;
                        }
                        if (!(ent->flags & renderimask))
-                       if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+                       if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
                        if ((ent->flags & (RENDER_NODEPTHTEST | RENDER_WORLDOBJECT | RENDER_VIEWMODEL)) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs))
                                r_refdef.viewcache.entityvisible[i] = true;
                }
@@ -4100,7 +4040,7 @@ static void R_View_UpdateEntityVisible (void)
                {
                        ent = r_refdef.scene.entities[i];
                        if (!(ent->flags & renderimask))
-                       if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+                       if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
                                r_refdef.viewcache.entityvisible[i] = true;
                }
        }
@@ -9835,7 +9775,7 @@ static void R_DrawDebugModel(void)
                GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
                for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
                {
-                       if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
+                       if (cullbox && R_CullFrustum(bihleaf->mins, bihleaf->maxs))
                                continue;
                        switch (bihleaf->type)
                        {
index d9497d4367b76f867eaab72a8f07dd5d4429baab..723e9fb4ce3ee2028ffcc20b6924f1e02955dedd 100644 (file)
@@ -394,7 +394,7 @@ void R_DrawPortals(void)
                        for (portal = model->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
                        {
                                if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
-                               if (!R_CullBox(portal->mins, portal->maxs))
+                               if (!R_CullFrustum(portal->mins, portal->maxs))
                                {
                                        VectorClear(center);
                                        for (i = 0;i < portal->numpoints;i++)
@@ -426,7 +426,7 @@ static void R_View_WorldVisibility_CullSurfaces(void)
        {
                if (surfacevisible[surfaceindex])
                {
-                       if (R_CullBox(surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs)
+                       if (R_CullFrustum(surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs)
                         || (r_vis_trace_surfaces.integer && !R_CanSeeBox(r_vis_trace_samples.integer, r_vis_trace_eyejitter.value, r_vis_trace_enlarge.value, r_vis_trace_expand.value, r_vis_trace_pad.value, r_refdef.view.origin, surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs)))
                                surfacevisible[surfaceindex] = 0;
                }
@@ -459,7 +459,7 @@ void R_View_WorldVisibility(qbool forcenovis)
                for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                {
                        // if leaf is in current pvs and on the screen, mark its surfaces
-                       if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+                       if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullFrustum(leaf->mins, leaf->maxs))
                        {
                                r_refdef.stats[r_stat_world_leafs]++;
                                r_refdef.viewcache.world_leafvisible[j] = true;
@@ -490,7 +490,7 @@ void R_View_WorldVisibility(qbool forcenovis)
                                if (leaf->clusterindex < 0)
                                        continue;
                                // if leaf is in current pvs and on the screen, mark its surfaces
-                               if (!R_CullBox(leaf->mins, leaf->maxs))
+                               if (!R_CullFrustum(leaf->mins, leaf->maxs))
                                {
                                        r_refdef.stats[r_stat_world_leafs]++;
                                        r_refdef.viewcache.world_leafvisible[j] = true;
@@ -513,7 +513,7 @@ void R_View_WorldVisibility(qbool forcenovis)
                                if (leaf->clusterindex < 0)
                                        continue;
                                // if leaf is in current pvs and on the screen, mark its surfaces
-                               if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+                               if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullFrustum(leaf->mins, leaf->maxs))
                                {
                                        r_refdef.stats[r_stat_world_leafs]++;
                                        r_refdef.viewcache.world_leafvisible[j] = true;
@@ -572,7 +572,7 @@ void R_View_WorldVisibility(qbool forcenovis)
                                        cullmaxs[0] = p->maxs[0] + cullbias;
                                        cullmaxs[1] = p->maxs[1] + cullbias;
                                        cullmaxs[2] = p->maxs[2] + cullbias;
-                                       if (R_CullBox(cullmins, cullmaxs))
+                                       if (R_CullFrustum(cullmins, cullmaxs))
                                                continue;
                                        if (r_vis_trace.integer)
                                        {
@@ -752,7 +752,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo
                                continue;
 #endif
 #if 0
-                       if (!r_shadow_compilingrtlight && R_CullBoxCustomPlanes(node->mins, node->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
+                       if (!r_shadow_compilingrtlight && R_CullBox(node->mins, node->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
                                continue;
 #endif
                        // axial planes can be processed much more quickly
@@ -825,7 +825,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo
                                continue;
 #endif
 #if 1
-                       if (!r_shadow_compilingrtlight && R_CullBoxCustomPlanes(leaf->mins, leaf->maxs, info->numfrustumplanes, info->frustumplanes))
+                       if (!r_shadow_compilingrtlight && R_CullBox(leaf->mins, leaf->maxs, info->numfrustumplanes, info->frustumplanes))
                                continue;
 #endif
 
@@ -1009,7 +1009,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BIH(r_q1bsp_getlightinfo_t *info, cons
                                        continue;
 #endif
 #if 1
-                               if (!r_shadow_compilingrtlight && R_CullBoxCustomPlanes(leaf->mins, leaf->maxs, info->numfrustumplanes, info->frustumplanes))
+                               if (!r_shadow_compilingrtlight && R_CullBox(leaf->mins, leaf->maxs, info->numfrustumplanes, info->frustumplanes))
                                        continue;
 #endif
                                surfaceindex = leaf->surfaceindex;
@@ -1076,7 +1076,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BIH(r_q1bsp_getlightinfo_t *info, cons
                                continue;
 #endif
 #if 0
-                       if (!r_shadow_compilingrtlight && R_CullBoxCustomPlanes(node->mins, node->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
+                       if (!r_shadow_compilingrtlight && R_CullBox(node->mins, node->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
                                continue;
 #endif
                        if (info->lightmins[axis] <= node->backmax)
index c6ee977f2c4c54807249a53510bc8d369a45e376..3abad9d0aff13f50b902409dd993d798318baa46 100644 (file)
@@ -2023,7 +2023,7 @@ static void R_Shadow_BounceGrid_AssignPhotons_Task(taskqueue_task_t *t)
                                        continue;
                        }
                        // skip if expanded light box is offscreen
-                       if (R_CullBox(cullmins, cullmaxs))
+                       if (R_CullFrustum(cullmins, cullmaxs))
                                continue;
                        // skip if overall light intensity is zero
                        if (w * VectorLength2(rtlight->color) == 0.0f)
@@ -2636,7 +2636,7 @@ static void R_Shadow_BounceGrid_TracePhotons_Shot(r_shadow_bouncegrid_photon_t *
        if ((remainingbounces == r_shadow_bouncegrid_state.settings.maxbounce || r_shadow_bouncegrid_state.settings.includedirectlighting) && p->numpaths < PHOTON_MAX_PATHS)
        {
                qbool notculled = true;
-               // cull paths that fail R_CullBox in dynamic mode
+               // cull paths that fail R_CullFrustum in dynamic mode
                if (!r_shadow_bouncegrid_state.settings.staticmode
                        && r_shadow_bouncegrid_dynamic_culllightpaths.integer)
                {
@@ -2647,7 +2647,7 @@ static void R_Shadow_BounceGrid_TracePhotons_Shot(r_shadow_bouncegrid_photon_t *
                        cullmaxs[0] = max(shotstart[0], shothit[0]) + r_shadow_bouncegrid_state.settings.spacing[0] + r_shadow_bouncegrid_state.settings.lightpathsize;
                        cullmaxs[1] = max(shotstart[1], shothit[1]) + r_shadow_bouncegrid_state.settings.spacing[1] + r_shadow_bouncegrid_state.settings.lightpathsize;
                        cullmaxs[2] = max(shotstart[2], shothit[2]) + r_shadow_bouncegrid_state.settings.spacing[2] + r_shadow_bouncegrid_state.settings.lightpathsize;
-                       if (R_CullBox(cullmins, cullmaxs))
+                       if (R_CullFrustum(cullmins, cullmaxs))
                                notculled = false;
                }
                if (notculled)
@@ -3507,7 +3507,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight)
        }
 
        // skip if the light box is off screen
-       if (R_CullBox(rtlight->cullmins, rtlight->cullmaxs))
+       if (R_CullFrustum(rtlight->cullmins, rtlight->cullmaxs))
                return;
 
        // in the typical case this will be quickly replaced by GetLightInfo
@@ -3546,7 +3546,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight)
                shadowtrispvs = r_shadow_buffer_shadowtrispvs;
                lighttrispvs = r_shadow_buffer_lighttrispvs;
                // if the reduced leaf bounds are offscreen, skip it
-               if (R_CullBox(rtlight->cached_cullmins, rtlight->cached_cullmaxs))
+               if (R_CullFrustum(rtlight->cached_cullmins, rtlight->cached_cullmaxs))
                        return;
        }
        else
@@ -3587,7 +3587,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight)
                        continue;
                // skip the object entirely if it is not within the valid
                // shadow-casting region (which includes the lit region)
-               if (R_CullBoxCustomPlanes(ent->mins, ent->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
+               if (R_CullBox(ent->mins, ent->maxs, rtlight->cached_numfrustumplanes, rtlight->cached_frustumplanes))
                        continue;
                if (!(model = ent->model))
                        continue;
index 5016b4b2f122fa8f19ddeed7bb33e47f03d880b4..e7b99a665ff59bed1deb7394c2f8659bf9ec313d 100644 (file)
--- a/render.h
+++ b/render.h
@@ -501,8 +501,8 @@ void R_DrawExplosions(void);
 #define gl_solid_format 3
 #define gl_alpha_format 4
 
-int R_CullBox(const vec3_t mins, const vec3_t maxs);
-int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes);
+qbool R_CullFrustum(const vec3_t mins, const vec3_t maxs);
+qbool R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes);
 qbool R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec_t entboxexpand, vec_t pad, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs);
 
 #include "r_modules.h"