mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
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:
parent
874a2c6716
commit
647d38fa40
9 changed files with 145 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -194,6 +194,9 @@ typedef struct mleaf_s
|
|||
struct mnode_s *parent;
|
||||
|
||||
// leaf specific
|
||||
int dlightbits;
|
||||
int dlightframe;
|
||||
|
||||
byte *compressed_vis;
|
||||
efrag_t *efrags;
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue