Make R_MarkLights use the vis info to speed things up. Oddly, even though

R_MarkLights is now about 3% instead of about 15%, I've lost 8 fps on my
null GL speed test. However, R_AddDynamicLights has jumped up a bit, so I'm
wording if maybe more surfaces are being lit.
This commit is contained in:
Bill Currie 2001-08-05 04:01:45 +00:00
parent 874a2c6716
commit 647d38fa40
9 changed files with 145 additions and 21 deletions

View file

@ -45,6 +45,7 @@ extern int nanmask;
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} #define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} #define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} #define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
#define VectorMA(a,s,b,c) {(c)[0]=(a)[0]+(s)*(b)[0];(c)[1]=(a)[1]+(s)*(b)[1];(c)[2]=(a)[2]+(s)*(b)[2];}
/* /*
* VectorDistance, the distance between two points. * VectorDistance, the distance between two points.
@ -66,7 +67,7 @@ extern int nanmask;
// fall over // fall over
#define ROLL 2 #define ROLL 2
void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); void _VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
vec_t _DotProduct (vec3_t v1, vec3_t v2); vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
@ -113,6 +114,10 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
: \ : \
BoxOnPlaneSide( (emins), (emaxs), (p))) BoxOnPlaneSide( (emins), (emaxs), (p)))
#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
extern mplane_t frustum[4]; extern mplane_t frustum[4];
#ifndef IMPLEMENT_R_CullBox #ifndef IMPLEMENT_R_CullBox

View file

@ -194,6 +194,9 @@ typedef struct mleaf_s
struct mnode_s *parent; struct mnode_s *parent;
// leaf specific // leaf specific
int dlightbits;
int dlightframe;
byte *compressed_vis; byte *compressed_vis;
efrag_t *efrags; efrag_t *efrags;

View file

@ -335,7 +335,7 @@ void R_cshift_f (void);
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1); void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip); void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
void R_SplitEntityOnNode2 (mnode_t *node); void R_SplitEntityOnNode2 (mnode_t *node);
void R_MarkLights (vec3_t lightorigin, struct dlight_s *light, int bit, mnode_t *node); void R_MarkLights (vec3_t lightorigin, struct dlight_s *light, int bit, model_t *model);
void R_LoadSkys (const char *); void R_LoadSkys (const char *);

View file

@ -388,7 +388,7 @@ VectorCompare (vec3_t v1, vec3_t v2)
} }
void void
VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) _VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
{ {
vecc[0] = veca[0] + scale * vecb[0]; vecc[0] = veca[0] + scale * vecb[0];
vecc[1] = veca[1] + scale * vecb[1]; vecc[1] = veca[1] + scale * vecb[1];

View file

@ -44,6 +44,7 @@
#include "QF/GL/defines.h" #include "QF/GL/defines.h"
#include "QF/GL/funcs.h" #include "QF/GL/funcs.h"
#include "r_local.h"
#include "r_shared.h" #include "r_shared.h"
#include "r_cvar.h" #include "r_cvar.h"
@ -193,7 +194,8 @@ R_RenderDlights (void)
// 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_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) R_RecursiveMarkLights (vec3_t lightorigin, dlight_t *light, int bit,
mnode_t *node)
{ {
mplane_t *splitplane; mplane_t *splitplane;
float ndist, maxdist; float ndist, maxdist;
@ -272,7 +274,7 @@ loc0:
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_MarkLights (lightorigin, light, bit, node->children[1]); R_RecursiveMarkLights (lightorigin, light, bit, node->children[1]);
node = node->children[0]; node = node->children[0];
goto loc0; goto loc0;
@ -282,13 +284,127 @@ loc0:
} }
} }
static void
mark_surfaces (msurface_t *surf, vec3_t lightorigin, dlight_t *light,
int bit)
{
float dist, dist2, d;
float maxdist = light->radius * light->radius;
vec3_t impact;
surf->dlightframe = r_framecount;
dist = PlaneDiff(lightorigin, surf->plane);
if (surf->flags & SURF_PLANEBACK)
dist = -dist;
#if 0
//FIXME SURF_LIGHTBOTHSIDES seems to be a darkplaces thing. need to investigate
if ((dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES))
|| dist > radius)
return;
#else
if (dist < -0.25f || dist > light->radius)
return;
#endif
dist2 = dist * dist;
dist = -dist;
VectorMA (light->origin, dist, surf->plane->normal, impact);
d = DotProduct (impact, surf->texinfo->vecs[0])
+ surf->texinfo->vecs[0][3] - surf->texturemins[0];
if (d < 0) {
dist2 += d * d;
if (dist2 >= maxdist)
return;
} else {
d -= surf->extents[0] + 16;
if (d > 0) {
dist2 += d * d;
if (dist2 >= maxdist)
return;
}
}
d = DotProduct (impact, surf->texinfo->vecs[1])
+ surf->texinfo->vecs[1][3] - surf->texturemins[1];
if (d < 0) {
dist2 += d * d;
if (dist2 >= maxdist)
return;
} else {
d -= surf->extents[1] + 16;
if (d > 0) {
dist2 += d * d;
if (dist2 >= maxdist)
return;
}
}
if (surf->dlightframe != r_framecount) {
surf->dlightbits = 0;
surf->dlightframe = r_framecount;
}
surf->dlightbits |= bit;
}
void
R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, model_t *model)
{
mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
if (!pvsleaf->compressed_vis) {
R_RecursiveMarkLights (lightorigin, light, bit, model->nodes);
} else {
float radius = light->radius;
vec3_t mins, maxs;
int leafnum = 0;
byte *in = pvsleaf->compressed_vis;
byte vis_bits;
mins[0] = lightorigin[0] - radius;
mins[1] = lightorigin[1] - radius;
mins[2] = lightorigin[2] - radius;
maxs[0] = lightorigin[0] + radius;
maxs[1] = lightorigin[1] + radius;
maxs[2] = lightorigin[2] + radius;
while (leafnum < model->numleafs) {
int i;
if (!(vis_bits = *in++)) {
leafnum += (*in++) * 8;
continue;
}
for (i = 0; i < 8 && leafnum < model->numleafs; i++, leafnum++) {
int m;
mleaf_t *leaf = &model->leafs[leafnum];
if (!(vis_bits & (1 << i)))
continue;
if (leaf->visframe != r_visframecount)
continue;
if (leaf->mins[0] > maxs[0] || leaf->maxs[0] < mins[0]
|| leaf->mins[1] > maxs[1] || leaf->maxs[1] < mins[1]
|| leaf->mins[2] > maxs[2] || leaf->maxs[2] < mins[2])
continue;
if (leaf->dlightframe != r_framecount) {
leaf->dlightbits = 0;
leaf->dlightframe = r_framecount;
}
leaf->dlightbits |= bit;
for (m = 0; m < leaf->nummarksurfaces; m++) {
msurface_t *surf = leaf->firstmarksurface[m];
if (surf->visframe != r_visframecount
|| surf->dlightframe == r_framecount)
continue;
mark_surfaces (surf, lightorigin, light, bit);
}
}
}
}
}
void void
R_PushDlights (vec3_t entorigin) R_PushDlights (vec3_t entorigin)
{ {
int i; int i;
dlight_t *l; dlight_t *l;
vec3_t lightorigin;
if (!gl_dlight_lightmap->int_val) if (!gl_dlight_lightmap->int_val)
return; return;
@ -298,8 +414,7 @@ R_PushDlights (vec3_t entorigin)
for (i = 0; i < MAX_DLIGHTS; i++, l++) { for (i = 0; i < MAX_DLIGHTS; i++, l++) {
if (l->die < r_realtime || !l->radius) if (l->die < r_realtime || !l->radius)
continue; continue;
VectorSubtract (l->origin, entorigin, lightorigin); R_MarkLights (l->origin, l, 1 << i, r_worldentity.model);
R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model->nodes);
} }
} }

View file

@ -1058,10 +1058,10 @@ R_RenderScene (void)
R_SetupGL (); R_SetupGL ();
R_PushDlights (vec3_origin);
R_MarkLeaves (); // done here so we know if we're in water R_MarkLeaves (); // done here so we know if we're in water
R_PushDlights (vec3_origin);
R_DrawWorld (); // adds static entities to the list R_DrawWorld (); // adds static entities to the list
S_ExtraUpdate (); // don't let sound get messed up if going slow S_ExtraUpdate (); // don't let sound get messed up if going slow

View file

@ -727,8 +727,7 @@ R_DrawBrushModel (entity_t *e)
continue; continue;
VectorSubtract (r_dlights[k].origin, e->origin, lightorigin); VectorSubtract (r_dlights[k].origin, e->origin, lightorigin);
R_MarkLights (lightorigin, &r_dlights[k], 1 << k, R_MarkLights (lightorigin, &r_dlights[k], 1 << k, clmodel);
clmodel->nodes + clmodel->hulls[0].firstclipnode);
} }
} }
@ -807,7 +806,7 @@ R_RecursiveWorldNode (mnode_t *node)
if ((c = pleaf->nummarksurfaces)) { if ((c = pleaf->nummarksurfaces)) {
mark = pleaf->firstmarksurface; mark = pleaf->firstmarksurface;
do { do {
(*mark)->visframe = r_framecount; (*mark)->visframe = r_visframecount;
mark++; mark++;
} while (--c); } while (--c);
} }
@ -857,7 +856,7 @@ R_RecursiveWorldNode (mnode_t *node)
side = 0; side = 0;
for (; c; c--, surf++) { for (; c; c--, surf++) {
if (surf->visframe != r_framecount) if (surf->visframe != r_visframecount)
continue; continue;
if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))

View file

@ -64,8 +64,9 @@ R_AnimateLight (void)
void void
R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, model_t *model)
{ {
mnode_t *node = (mnode_t *)model;//FIXME evilness
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist;
msurface_t *surf; msurface_t *surf;
@ -78,11 +79,11 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
dist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; dist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
if (dist > light->radius) { if (dist > light->radius) {
R_MarkLights (lightorigin, light, bit, node->children[0]); R_MarkLights (lightorigin, light, bit, (model_t*)node->children[0]);
return; return;
} }
if (dist < -light->radius) { if (dist < -light->radius) {
R_MarkLights (lightorigin, light, bit, node->children[1]); R_MarkLights (lightorigin, light, bit, (model_t*)node->children[1]);
return; return;
} }
// mark the polygons // mark the polygons
@ -95,8 +96,8 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
surf->dlightbits |= bit; surf->dlightbits |= bit;
} }
R_MarkLights (lightorigin, light, bit, node->children[0]); R_MarkLights (lightorigin, light, bit, (model_t*)node->children[0]);
R_MarkLights (lightorigin, light, bit, node->children[1]); R_MarkLights (lightorigin, light, bit, (model_t*)node->children[1]);
} }
@ -115,7 +116,7 @@ R_PushDlights (vec3_t entorigin)
if (l->die < r_realtime || !l->radius) if (l->die < r_realtime || !l->radius)
continue; continue;
VectorSubtract (l->origin, entorigin, lightorigin); VectorSubtract (l->origin, entorigin, lightorigin);
R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model->nodes); R_MarkLights (lightorigin, l, 1 << i, (model_t*)r_worldentity.model->nodes);
} }
} }

View file

@ -714,8 +714,9 @@ R_DrawBEntitiesOnList (void)
VectorSubtract (r_dlights[k].origin, VectorSubtract (r_dlights[k].origin,
currententity->origin, lightorigin); currententity->origin, lightorigin);
R_MarkLights (lightorigin, &r_dlights[k], 1 << k, R_MarkLights (lightorigin, &r_dlights[k], 1 << k,
(model_t*)(//FIXME this is so evil
clmodel->nodes + clmodel->nodes +
clmodel->hulls[0].firstclipnode); clmodel->hulls[0].firstclipnode));
} }
} }
// if the driver wants polygons, deliver those. // if the driver wants polygons, deliver those.