summaryrefslogtreecommitdiff
path: root/src/cgame
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2002-10-23 00:43:40 +0000
committerTim Angus <tim@ngus.net>2002-10-23 00:43:40 +0000
commit28e5e2f078984294a3430c97223f9508c891fac6 (patch)
treec4e5218a77cfd3dcb8e6c0e001e4adbfd80bfd24 /src/cgame
parenta68abe96d8ab594c220e683da773bd0ac98c01fd (diff)
* Improved performance of real fading light flares
* Added timed light flares and cg_ to switch between flare types
Diffstat (limited to 'src/cgame')
-rw-r--r--src/cgame/cg_ents.c112
-rw-r--r--src/cgame/cg_local.h5
-rw-r--r--src/cgame/cg_main.c2
3 files changed, 103 insertions, 16 deletions
diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c
index 38e4c798..b9041eff 100644
--- a/src/cgame/cg_ents.c
+++ b/src/cgame/cg_ents.c
@@ -435,6 +435,11 @@ static void CG_Portal( centity_t *cent )
(v2)[0]=(r/2),(v2)[1]=(r/2),(v2)[2]=(r/2))
#define RADIUSSTEP 1.0f
+#define FLARE_OFF 0
+#define FLARE_NOFADE 1
+#define FLARE_TIMEFADE 2
+#define FLARE_REALFADE 3
+
/*
=========================
CG_LightFlare
@@ -449,10 +454,18 @@ static void CG_LightFlare( centity_t *cent )
trace_t tr;
float maxAngle;
vec3_t mins, maxs, dir, start, end;
- float srcRadius, srLocal, ratio;
+ float srcRadius, srLocal, ratio = 1.0f;
es = &cent->currentState;
+ //don't draw light flares
+ if( cg_lightFlare.integer == FLARE_OFF )
+ return;
+
+ //flare is "off"
+ if( es->eFlags & EF_NODRAW )
+ return;
+
memset( &flare, 0, sizeof( flare ) );
//bunch of geometry
@@ -496,30 +509,97 @@ static void CG_LightFlare( centity_t *cent )
if( flare.radius < 0.0f )
flare.radius = 0.0f;
- //if can't see the centre do not draw
- CG_Trace( &tr, flare.origin, NULL, NULL, cg.refdef.vieworg, 0, MASK_SHOT );
- if( tr.fraction < 1.0f )
- return;
-
VectorSubtract( cg.refdef.vieworg, flare.origin, dir );
VectorNormalize( dir );
- VectorMA( flare.origin, 1.5f * flare.radius, dir, end );
- VectorMA( cg.refdef.vieworg, -flare.radius, dir, start );
+ VectorMA( flare.origin, flare.radius, dir, end );
+ VectorCopy( cg.refdef.vieworg, start );
- do
+ if( cg_lightFlare.integer == FLARE_REALFADE )
+ {
+ //draw "correct" albeit inefficient flares
+ srLocal = cent->lastFlareRadius;
+
+ //flare radius is likely to be the same as last frame so start with it
+ do
+ {
+ srLocal += RADIUSSTEP;
+ SETBOUNDS( mins, maxs, srLocal );
+ CG_Trace( &tr, start, mins, maxs, end,
+ cg.predictedPlayerState.clientNum, MASK_SHOT );
+
+ } while( ( tr.fraction == 1.0f && !tr.startsolid ) && ( srLocal < srcRadius ) );
+
+ srLocal -= RADIUSSTEP;
+
+ //shink the flare until there is a los
+ do
+ {
+ SETBOUNDS( mins, maxs, srLocal );
+ CG_Trace( &tr, start, mins, maxs, end,
+ cg.predictedPlayerState.clientNum, MASK_SHOT );
+
+ srLocal -= RADIUSSTEP;
+ } while( ( tr.fraction < 1.0f || tr.startsolid ) && ( srLocal > 0.0f ) );
+
+ ratio = srLocal / srcRadius;
+
+ cent->lastFlareRadius = srLocal;
+ }
+ else if( cg_lightFlare.integer == FLARE_TIMEFADE )
{
- SETBOUNDS( mins, maxs, srLocal );
+ //draw timed flares
+ SETBOUNDS( mins, maxs, srcRadius / 2.0f );
CG_Trace( &tr, start, mins, maxs, end,
cg.predictedPlayerState.clientNum, MASK_SHOT );
- srLocal -= RADIUSSTEP;
- } while( ( tr.fraction < 1.0f || tr.startsolid ) && ( srLocal > 0.0f ) );
+ if( ( tr.fraction < 1.0f || tr.startsolid ) && cent->flareStatus )
+ {
+ cent->flareStatus = qfalse;
+ cent->lastFlareTime = cg.time;
+ }
+ else if( ( tr.fraction == 1.0f && !tr.startsolid ) && !cent->flareStatus )
+ {
+ cent->flareStatus = qtrue;
+ cent->lastFlareTime = cg.time;
+ }
- ratio = srLocal / srcRadius;
-
- flare.radius *= ratio;
- flare.shaderRGBA[ 3 ] = (byte)( (float)flare.shaderRGBA[ 3 ] * ratio );
+ //fade flare up
+ if( cent->flareStatus )
+ {
+ if( cent->lastFlareTime + es->time > cg.time )
+ ratio = (float)( cg.time - cent->lastFlareTime ) / es->time;
+ }
+
+ //fade flare down
+ if( !cent->flareStatus )
+ {
+ if( cent->lastFlareTime + es->time > cg.time )
+ {
+ ratio = (float)( cg.time - cent->lastFlareTime ) / es->time;
+ ratio = 1.0f - ratio;
+ }
+ else
+ return;
+ }
+ }
+ else if( cg_lightFlare.integer == FLARE_NOFADE )
+ {
+ //draw nofade flares
+ SETBOUNDS( mins, maxs, srcRadius / 2.0f );
+ CG_Trace( &tr, start, mins, maxs, end,
+ cg.predictedPlayerState.clientNum, MASK_SHOT );
+
+ //flare source occluded
+ if( ( tr.fraction < 1.0f || tr.startsolid ) )
+ return;
+ }
+ if( ratio < 1.0f )
+ {
+ flare.radius *= ratio;
+ flare.shaderRGBA[ 3 ] = (byte)( (float)flare.shaderRGBA[ 3 ] * ratio );
+ }
+
if( flare.radius <= 0.0f )
return;
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 70e7b567..6d3eef44 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -216,6 +216,10 @@ typedef struct centity_s
int buildableSmokeTime;
int buildableSparkTime;
int buildableBleedTime;
+
+ float lastFlareRadius; //caching of likely flare radius
+ int lastFlareTime; //last time flare was visible/occluded
+ qboolean flareStatus; //flare is visble?
} centity_t;
@@ -1122,6 +1126,7 @@ extern vmCvar_t cg_wwSmoothTime;
extern vmCvar_t cg_wwFollow;
extern vmCvar_t cg_zsortLEs;
extern vmCvar_t cg_consoleLatency;
+extern vmCvar_t cg_lightFlare;
//TA: hack to get class an carriage through to UI module
extern vmCvar_t ui_currentClass;
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index a20d193a..6d37e724 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -195,6 +195,7 @@ vmCvar_t cg_wwSmoothTime;
vmCvar_t cg_wwFollow;
vmCvar_t cg_zsortLEs;
vmCvar_t cg_consoleLatency;
+vmCvar_t cg_lightFlare;
//TA: hack to get class and carriage through to UI module
vmCvar_t ui_currentClass;
@@ -288,6 +289,7 @@ static cvarTable_t cvarTable[ ] =
{ &cg_wwFollow, "cg_wwFollow", "1", CVAR_ARCHIVE|CVAR_USERINFO },
{ &cg_zsortLEs, "cg_zsortLEs", "1", CVAR_ARCHIVE },
{ &cg_consoleLatency, "cg_consoleLatency", "3000", CVAR_ARCHIVE },
+ { &cg_lightFlare, "cg_lightFlare", "3", CVAR_ARCHIVE },
{ &ui_currentClass, "ui_currentClass", "0", 0 },
{ &ui_carriage, "ui_carriage", "", 0 },