Support up to 128 dlights.

More or less as per MH's tut, but really just finishing something that
should have been done years ago.
This commit is contained in:
Bill Currie 2012-07-21 13:58:54 +09:00
parent 106257d6e9
commit 372defc1be
6 changed files with 25 additions and 19 deletions

View file

@ -141,6 +141,8 @@ typedef struct glpoly_s {
float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2) float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2)
} glpoly_t; } glpoly_t;
#define MAX_DLIGHTS 128
typedef struct msurface_s { typedef struct msurface_s {
int visframe; // should be drawn when node is crossed int visframe; // should be drawn when node is crossed
@ -168,7 +170,7 @@ typedef struct msurface_s {
// lighting info // lighting info
struct subpic_s *lightpic; ///< light map texture ref (glsl) struct subpic_s *lightpic; ///< light map texture ref (glsl)
int dlightframe; int dlightframe;
int dlightbits; uint32_t dlightbits[(MAX_DLIGHTS + 31) >> 5];
int lightmaptexturenum; int lightmaptexturenum;
byte styles[MAXLIGHTMAPS]; byte styles[MAXLIGHTMAPS];

View file

@ -123,7 +123,7 @@ R_AddDynamicLights_1 (msurface_t *surf)
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1;
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
if (!(surf->dlightbits & (1 << lnum))) if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
continue; // not lit by this light continue; // not lit by this light
VectorSubtract (r_dlights[lnum].origin, currententity->origin, local); VectorSubtract (r_dlights[lnum].origin, currententity->origin, local);
@ -188,7 +188,7 @@ R_AddDynamicLights_3 (msurface_t *surf)
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1;
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
if (!(surf->dlightbits & (1 << lnum))) if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
continue; // not lit by this light continue; // not lit by this light
VectorSubtract (r_dlights[lnum].origin, currententity->origin, local); VectorSubtract (r_dlights[lnum].origin, currententity->origin, local);

View file

@ -80,7 +80,7 @@ R_AddDynamicLights_1 (msurface_t *surf)
tex = surf->texinfo; tex = surf->texinfo;
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
if (!(surf->dlightbits & (1 << lnum))) if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
continue; // not lit by this light continue; // not lit by this light
VectorSubtract (r_dlights[lnum].origin, currententity->origin, VectorSubtract (r_dlights[lnum].origin, currententity->origin,

View file

@ -106,7 +106,7 @@ R_FindNearLights (const vec3_t pos, int count, dlight_t **lights)
void void
R_MaxDlightsCheck (cvar_t *var) R_MaxDlightsCheck (cvar_t *var)
{ {
r_maxdlights = bound (0, var->int_val, 32); r_maxdlights = bound (0, var->int_val, MAX_DLIGHTS);
if (r_dlights) if (r_dlights)
free (r_dlights); free (r_dlights);
@ -146,11 +146,12 @@ R_AnimateLight (void)
static inline void static inline void
real_mark_surfaces (float dist, msurface_t *surf, const vec3_t lightorigin, real_mark_surfaces (float dist, msurface_t *surf, const vec3_t lightorigin,
dlight_t *light, int bit) dlight_t *light, unsigned lightnum)
{ {
float dist2, is, it; float dist2, is, it;
float maxdist = light->radius * light->radius; float maxdist = light->radius * light->radius;
vec3_t impact; vec3_t impact;
unsigned ind, bit;
dist2 = maxdist - dist * dist; dist2 = maxdist - dist * dist;
VectorMultSub (light->origin, dist, surf->plane->normal, impact); VectorMultSub (light->origin, dist, surf->plane->normal, impact);
@ -173,15 +174,17 @@ real_mark_surfaces (float dist, msurface_t *surf, const vec3_t lightorigin,
return; return;
if (surf->dlightframe != r_framecount) { if (surf->dlightframe != r_framecount) {
surf->dlightbits = 0; memset (surf->dlightbits, 0, sizeof (surf->dlightbits));
surf->dlightframe = r_framecount; surf->dlightframe = r_framecount;
} }
surf->dlightbits |= bit; ind = lightnum / 32;
bit = 1 << (lightnum % 32);
surf->dlightbits[ind] |= bit;
} }
static inline void static inline void
mark_surfaces (msurface_t *surf, const vec3_t lightorigin, dlight_t *light, mark_surfaces (msurface_t *surf, const vec3_t lightorigin, dlight_t *light,
int bit) int lightnum)
{ {
float dist; float dist;
@ -192,13 +195,13 @@ mark_surfaces (msurface_t *surf, const vec3_t lightorigin, dlight_t *light,
|| dist > light->radius) || dist > light->radius)
return; return;
real_mark_surfaces (dist, surf, lightorigin, light, bit); real_mark_surfaces (dist, surf, lightorigin, light, lightnum);
} }
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads, // LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
// and support bmodel lighting better // and support bmodel lighting better
void void
R_RecursiveMarkLights (const vec3_t lightorigin, dlight_t *light, int bit, R_RecursiveMarkLights (const vec3_t lightorigin, dlight_t *light, int lightnum,
mnode_t *node) mnode_t *node)
{ {
int i; int i;
@ -237,12 +240,13 @@ loc0:
// mark the polygons // mark the polygons
surf = r_worldentity.model->surfaces + node->firstsurface; surf = r_worldentity.model->surfaces + node->firstsurface;
for (i = 0; i < node->numsurfaces; i++, surf++) { for (i = 0; i < node->numsurfaces; i++, surf++) {
mark_surfaces (surf, lightorigin, light, bit); mark_surfaces (surf, lightorigin, light, lightnum);
} }
if (node->children[0]->contents >= 0) { if (node->children[0]->contents >= 0) {
if (node->children[1]->contents >= 0) if (node->children[1]->contents >= 0)
R_RecursiveMarkLights (lightorigin, light, bit, node->children[1]); R_RecursiveMarkLights (lightorigin, light, lightnum,
node->children[1]);
node = node->children[0]; node = node->children[0];
goto loc0; goto loc0;
} else if (node->children[1]->contents >= 0) { } else if (node->children[1]->contents >= 0) {
@ -253,14 +257,14 @@ loc0:
void void
R_MarkLights (const vec3_t lightorigin, dlight_t *light, int bit, R_MarkLights (const vec3_t lightorigin, dlight_t *light, int lightnum,
model_t *model) model_t *model)
{ {
mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model); mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
if (!pvsleaf->compressed_vis) { if (!pvsleaf->compressed_vis) {
mnode_t *node = model->nodes + model->hulls[0].firstclipnode; mnode_t *node = model->nodes + model->hulls[0].firstclipnode;
R_RecursiveMarkLights (lightorigin, light, bit, node); R_RecursiveMarkLights (lightorigin, light, lightnum, node);
} else { } else {
float radius = light->radius; float radius = light->radius;
vec3_t mins, maxs; vec3_t mins, maxs;
@ -298,7 +302,7 @@ R_MarkLights (const vec3_t lightorigin, dlight_t *light, int bit,
msurface_t *surf = leaf->firstmarksurface[m]; msurface_t *surf = leaf->firstmarksurface[m];
if (surf->visframe != r_visframecount) if (surf->visframe != r_visframecount)
continue; continue;
mark_surfaces (surf, lightorigin, light, bit); mark_surfaces (surf, lightorigin, light, lightnum);
} }
} }
} }
@ -321,7 +325,7 @@ R_PushDlights (const vec3_t entorigin)
if (l->die < vr_data.realtime || !l->radius) if (l->die < vr_data.realtime || !l->radius)
continue; continue;
VectorSubtract (l->origin, entorigin, lightorigin); VectorSubtract (l->origin, entorigin, lightorigin);
R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model); R_MarkLights (lightorigin, l, i, r_worldentity.model);
} }
} }

View file

@ -89,7 +89,7 @@ R_AddDynamicLights (void)
tex = surf->texinfo; tex = surf->texinfo;
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
if (!(surf->dlightbits & (1 << lnum))) if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
continue; // not lit by this light continue; // not lit by this light
VectorSubtract (r_dlights[lnum].origin, currententity->origin, VectorSubtract (r_dlights[lnum].origin, currententity->origin,

View file

@ -107,7 +107,7 @@ R_AddDynamicLights (void)
tex = surf->texinfo; tex = surf->texinfo;
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
if (!(surf->dlightbits & (1 << lnum))) if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
continue; // not lit by this light continue; // not lit by this light
VectorSubtract (r_dlights[lnum].origin, currententity->origin, VectorSubtract (r_dlights[lnum].origin, currententity->origin,