Massive dynamic light speedup.

This commit is contained in:
Forest Hale 2000-06-29 23:27:03 +00:00
parent e25c2e5898
commit def35745d7

View file

@ -212,44 +212,70 @@ DYNAMIC LIGHTS
R_MarkLights R_MarkLights
============= =============
*/ */
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
// and support bmodel lighting better
void R_MarkLights (dlight_t *light, int bit, mnode_t *node) void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
{ {
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist, l, maxdist;
msurface_t *surf; msurface_t *surf;
int i; int i, j, s, t;
vec3_t impact, lightorigin;
if (node->contents < 0) if (node->contents < 0)
return; return;
VectorSubtract(light->origin, currententity->origin, lightorigin);
splitplane = node->plane; splitplane = node->plane;
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; dist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
if (dist > light->radius) if (dist > light->radius)
{ {
R_MarkLights (light, bit, node->children[0]); if (node->children[0]->contents >= 0) // save some time by not pushing another stack frame
R_MarkLights (light, bit, node->children[0]);
return; return;
} }
if (dist < -light->radius) if (dist < -light->radius)
{ {
R_MarkLights (light, bit, node->children[1]); if (node->children[1]->contents >= 0) // save some time by not pushing another stack frame
R_MarkLights (light, bit, node->children[1]);
return; return;
} }
maxdist = light->radius*light->radius;
// mark the polygons // mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface; surf = cl.worldmodel->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++) for (i=0 ; i<node->numsurfaces ; i++, surf++)
{ {
if (surf->dlightframe != r_dlightframecount) // LordHavoc: MAJOR dynamic light speedup here, eliminates marking of surfaces that are too far away from light, thus preventing unnecessary renders and uploads
for (j=0 ; j<3 ; j++)
impact[j] = lightorigin[j] - surf->plane->normal[j]*dist;
// clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = l - s;
l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
t = l - t;
// compare to minimum light
if ((s*s+t*t+dist*dist) < maxdist)
{ {
surf->dlightbits = 0; if (surf->dlightframe != r_dlightframecount) // not dynamic until now
surf->dlightframe = r_dlightframecount; {
surf->dlightbits = bit;
surf->dlightframe = r_dlightframecount;
}
else // already dynamic
surf->dlightbits |= bit;
} }
surf->dlightbits |= bit;
} }
R_MarkLights (light, bit, node->children[0]); if (node->children[0]->contents >= 0) // save some time by not pushing another stack frame
R_MarkLights (light, bit, node->children[1]); R_MarkLights (light, bit, node->children[0]);
if (node->children[1]->contents >= 0) // save some time by not pushing another stack frame
R_MarkLights (light, bit, node->children[1]);
} }