sped up nexuiz rtlights benchmark by 4% by optimizing box cull on models to skip...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 30 Sep 2004 16:38:54 +0000 (16:38 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 30 Sep 2004 16:38:54 +0000 (16:38 +0000)
restructured R_Shadow_ConstructShadowVolume loops a bit to make for less stalls, this seems to have only netted a 0.5% speed gain or so

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

gl_models.c
gl_rsurf.c
r_shadow.c
r_shadow.h

index f2d8b3a..c5f2005 100644 (file)
@@ -190,11 +190,21 @@ void R_Model_Alias_Draw(entity_render_t *ent)
 void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
 {
        int meshnum;
+       vec3_t lightmins, lightmaxs;
        aliasmesh_t *mesh;
        aliasskin_t *skin;
        float projectdistance, *vertex3f;
        if (!(ent->flags & RENDER_SHADOW))
                return;
+       lightmins[0] = relativelightorigin[0] - lightradius;
+       lightmins[1] = relativelightorigin[1] - lightradius;
+       lightmins[2] = relativelightorigin[2] - lightradius;
+       lightmaxs[0] = relativelightorigin[0] + lightradius;
+       lightmaxs[1] = relativelightorigin[1] + lightradius;
+       lightmaxs[2] = relativelightorigin[2] + lightradius;
+       // check the box in modelspace, it was already checked in worldspace
+       if (!BoxesOverlap(ent->model->normalmins, ent->model->normalmaxs, lightmins, lightmaxs))
+               return;
        projectdistance = lightradius + ent->model->radius;// - sqrt(DotProduct(relativelightorigin, relativelightorigin));
        if (projectdistance > 0.1)
        {
@@ -211,7 +221,10 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor
                                vertex3f = varray_vertex3f;
                                Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
                        }
-                       R_Shadow_VolumeFromSphere(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, projectdistance, lightradius);
+                       // identify lit faces within the bounding box
+                       R_Shadow_PrepareShadowMark(mesh->num_triangles);
+                       R_Shadow_MarkVolumeFromBox(0, mesh->num_triangles, vertex3f, mesh->data_element3i, relativelightorigin, lightmins, lightmaxs, ent->model->normalmins, ent->model->normalmaxs);
+                       R_Shadow_VolumeFromList(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist);
                }
        }
 }
index 5c9bfd9..e055c6d 100644 (file)
@@ -1835,9 +1835,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        model_t *model = ent->model;
        vec3_t lightmins, lightmaxs;
        msurface_t *surface;
-       int surfacelistindex, j, t;
-       const int *e;
-       const float *v[3];
+       int surfacelistindex;
        if (r_drawcollisionbrushes.integer < 2)
        {
                lightmins[0] = relativelightorigin[0] - lightradius;
@@ -1851,14 +1849,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
                {
                        surface = model->brushq1.surfaces + surfacelist[surfacelistindex];
-                       for (j = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < surface->mesh.num_triangles;j++, t++, e += 3)
-                       {
-                               v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
-                               v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
-                               v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
-                               if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                       shadowmarklist[numshadowmark++] = t;
-                       }
+                       R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->mesh.num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->poly_mins, surface->poly_maxs);
                }
                R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
        }
@@ -2469,9 +2460,7 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        model_t *model = ent->model;
        vec3_t lightmins, lightmaxs;
        q3msurface_t *surface;
-       int surfacelistindex, j, t;
-       const int *e;
-       const float *v[3];
+       int surfacelistindex;
        if (r_drawcollisionbrushes.integer < 2)
        {
                lightmins[0] = relativelightorigin[0] - lightradius;
@@ -2486,17 +2475,8 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                {
                        surface = model->brushq3.data_faces + surfacelist[surfacelistindex];
                        // FIXME: check some manner of face->rendermode here?
-                       if (!(surface->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) && surface->num_triangles && !surface->texture->skin.fog)
-                       {
-                               for (j = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < surface->num_triangles;j++, t++, e += 3)
-                               {
-                                       v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
-                                       v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
-                                       v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
-                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                               shadowmarklist[numshadowmark++] = t;
-                               }
-                       }
+                       if (!(surface->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) && surface->num_triangles && !(surface->texture->surfaceparms & Q3SURFACEPARM_TRANS))
+                               R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs);
                }
                R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
        }
index 79023e7..4a9fadc 100644 (file)
@@ -526,10 +526,13 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
        }
        
        for (i = 0;i < numshadowmarktris;i++)
+               shadowmark[shadowmarktris[i]] = shadowmarkcount;
+
+       for (i = 0;i < numshadowmarktris;i++)
        {
                t = shadowmarktris[i];
-               shadowmark[t] = shadowmarkcount;
                e = inelement3i + t * 3;
+               n = inneighbor3i + t * 3;
                // make sure the vertices are created
                for (j = 0;j < 3;j++)
                {
@@ -554,13 +557,6 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
                outelement3i[5] = vertexremap[e[0]] + 1;
                outelement3i += 6;
                tris += 2;
-       }
-
-       for (i = 0;i < numshadowmarktris;i++)
-       {
-               t = shadowmarktris[i];
-               e = inelement3i + t * 3;
-               n = inneighbor3i + t * 3;
                // output the sides (facing outward from this triangle)
                if (shadowmark[n[0]] != shadowmarkcount)
                {
@@ -624,39 +620,41 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
        R_Shadow_RenderVolume(outverts, tris, varray_vertex3f2, shadowelements);
 }
 
-void R_Shadow_VolumeFromBox(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, const vec3_t mins, const vec3_t maxs)
+void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, vec3_t lightmins, vec3_t lightmaxs, vec3_t surfacemins, vec3_t surfacemaxs)
 {
-       int i;
+       int j, t, tend;
+       const int *e;
        const float *v[3];
-
-       // check which triangles are facing the , and then output
-       // triangle elements and vertices...  by clever use of elements we
-       // can construct the whole shadow from the unprojected vertices and
-       // the projected vertices
-
-       // identify lit faces within the bounding box
-       R_Shadow_PrepareShadowMark(numtris);
-       for (i = 0;i < numtris;i++)
+       if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs))
+               return;
+       tend = firsttriangle + numtris;
+       if (surfacemins[0] >= lightmins[0] && surfacemaxs[0] <= lightmaxs[0]
+        && surfacemins[1] >= lightmins[1] && surfacemaxs[1] <= lightmaxs[1]
+        && surfacemins[2] >= lightmins[2] && surfacemaxs[2] <= lightmaxs[2])
        {
-               v[0] = invertex3f + elements[i*3+0] * 3;
-               v[1] = invertex3f + elements[i*3+1] * 3;
-               v[2] = invertex3f + elements[i*3+2] * 3;
-               if (PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2]) && maxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && mins[0] < max(v[0][0], max(v[1][0], v[2][0])) && maxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && mins[1] < max(v[0][1], max(v[1][1], v[2][1])) && maxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && mins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                       shadowmarklist[numshadowmark++] = i;
+               // surface box entirely inside light box, no box cull
+               for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
+                       if (PointInfrontOfTriangle(projectorigin, invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3))
+                               shadowmarklist[numshadowmark++] = t;
+       }
+       else
+       {
+               // surface box not entirely inside light box, cull each triangle
+               for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
+               {
+                       v[0] = invertex3f + e[0] * 3;
+                       v[1] = invertex3f + e[1] * 3;
+                       v[2] = invertex3f + e[2] * 3;
+                       if (PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2])
+                        && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0]))
+                        && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0]))
+                        && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1]))
+                        && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1]))
+                        && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2]))
+                        && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                               shadowmarklist[numshadowmark++] = t;
+               }
        }
-       R_Shadow_VolumeFromList(numverts, numtris, invertex3f, elements, neighbors, projectorigin, projectdistance, numshadowmark, shadowmarklist);
-}
-
-void R_Shadow_VolumeFromSphere(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, float radius)
-{
-       vec3_t mins, maxs;
-       mins[0] = projectorigin[0] - radius;
-       mins[1] = projectorigin[1] - radius;
-       mins[2] = projectorigin[2] - radius;
-       maxs[0] = projectorigin[0] + radius;
-       maxs[1] = projectorigin[1] + radius;
-       maxs[2] = projectorigin[2] + radius;
-       R_Shadow_VolumeFromBox(numverts, numtris, invertex3f, elements, neighbors, projectorigin, projectdistance, mins, maxs);
 }
 
 void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i)
index ea8601a..29fd65b 100644 (file)
@@ -33,8 +33,7 @@ extern mempool_t *r_shadow_mempool;
 
 void R_Shadow_Init(void);
 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, int nummarktris, const int *marktris);
-void R_Shadow_VolumeFromBox(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, const vec3_t mins, const vec3_t maxs);
-void R_Shadow_VolumeFromSphere(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, float radius);
+void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, vec3_t lightmins, vec3_t lightmaxs, vec3_t surfacemins, vec3_t surfacemaxs);
 #define LIGHTING_DIFFUSE 1
 #define LIGHTING_SPECULAR 2
 void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, const float *lightcolor, const matrix4x4_t *matrix_worldtolight, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, int lightingflags);