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 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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue