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 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 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.
@ -66,7 +67,7 @@ extern int nanmask;
// fall over
#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);
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)))
#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];
#ifndef IMPLEMENT_R_CullBox

View File

@ -194,6 +194,9 @@ typedef struct mleaf_s
struct mnode_s *parent;
// leaf specific
int dlightbits;
int dlightframe;
byte *compressed_vis;
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_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
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 *);

View File

@ -388,7 +388,7 @@ VectorCompare (vec3_t v1, vec3_t v2)
}
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[1] = veca[1] + scale * vecb[1];

View File

@ -44,6 +44,7 @@
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "r_local.h"
#include "r_shared.h"
#include "r_cvar.h"
@ -193,7 +194,8 @@ R_RenderDlights (void)
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
// and support bmodel lighting better
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;
float ndist, maxdist;
@ -272,7 +274,7 @@ loc0:
if (node->children[0]->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];
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
R_PushDlights (vec3_t entorigin)
{
int i;
dlight_t *l;
vec3_t lightorigin;
if (!gl_dlight_lightmap->int_val)
return;
@ -298,8 +414,7 @@ R_PushDlights (vec3_t entorigin)
for (i = 0; i < MAX_DLIGHTS; i++, l++) {
if (l->die < r_realtime || !l->radius)
continue;
VectorSubtract (l->origin, entorigin, lightorigin);
R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model->nodes);
R_MarkLights (l->origin, l, 1 << i, r_worldentity.model);
}
}

View File

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

View File

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

View File

@ -64,8 +64,9 @@ R_AnimateLight (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;
float dist;
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;
if (dist > light->radius) {
R_MarkLights (lightorigin, light, bit, node->children[0]);
R_MarkLights (lightorigin, light, bit, (model_t*)node->children[0]);
return;
}
if (dist < -light->radius) {
R_MarkLights (lightorigin, light, bit, node->children[1]);
R_MarkLights (lightorigin, light, bit, (model_t*)node->children[1]);
return;
}
// mark the polygons
@ -95,8 +96,8 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
surf->dlightbits |= bit;
}
R_MarkLights (lightorigin, light, bit, node->children[0]);
R_MarkLights (lightorigin, light, bit, node->children[1]);
R_MarkLights (lightorigin, light, bit, (model_t*)node->children[0]);
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)
continue;
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,
currententity->origin, lightorigin);
R_MarkLights (lightorigin, &r_dlights[k], 1 << k,
(model_t*)(//FIXME this is so evil
clmodel->nodes +
clmodel->hulls[0].firstclipnode);
clmodel->hulls[0].firstclipnode));
}
}
// if the driver wants polygons, deliver those.