UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
r_light.cpp File Reference
#include "r_local.h"
#include "r_light.h"
#include "r_entity.h"
#include "r_state.h"

Go to the source code of this file.

Functions

void R_AddLight (const vec3_t origin, float radius, const vec3_t color)
 Create light to be rendered in the current frame (will be removed before the next) More...
 
void R_AddSustainedLight (const vec3_t org, float radius, const vec3_t color, float sustain)
 
void R_UpdateSustainedLights (void)
 Updates state of sustained lights; should be called once per frame right before world rendering. More...
 
void R_EnableWorldLights (void)
 Set up lighting data for the GLSL world shader. More...
 
void R_EnableModelLights (const light_t **lights, int numLights, bool inShadow, bool enable)
 Enable or disable realtime dynamic lighting for models. More...
 
void R_AddStaticLight (const vec3_t origin, float radius, const vec3_t color)
 Add static light for model lighting (world already got them baked into lightmap) More...
 
void R_DisableLights (void)
 
void R_ClearStaticLights (void)
 Remove all static light data. More...
 
static void R_AddLightToEntity (const vec_t *pos, lighting_t *ltng, const light_t *light, const float distSqr)
 Adds light to the entity's lights list, sorted by distance. More...
 
void R_UpdateLightList (entity_t *ent)
 Recalculate active lights list for the given entity; R_CalcTransform(ent) should be called before this. More...
 

Variables

static sustain_t r_sustainArray [MAX_GL_LIGHTS]
 
static lighting_t fakeLightingData
 

Function Documentation

void R_AddLight ( const vec3_t  origin,
float  radius,
const vec3_t  color 
)

Create light to be rendered in the current frame (will be removed before the next)

Note
Call before actual 3D rendering begins to avoid missing or partially rendered lights

Definition at line 36 of file r_light.cpp.

References light_s::color, Com_DPrintf(), DEBUG_RENDERER, rendererData_t::dynamicLights, i, MAX_GL_LIGHTS, rendererData_t::numDynamicLights, light_s::origin, light_s::radius, refdef, and VectorCopy.

Referenced by CL_ParticleRun2(), and R_UpdateSustainedLights().

static void R_AddLightToEntity ( const vec_t pos,
lighting_t ltng,
const light_t light,
const float  distSqr 
)
static

Adds light to the entity's lights list, sorted by distance.

Todo:
  • the updating of the per-entity list of nearest lights doesn't necessarily need to be updated before every frame; if the list is a few frames (or even a few seconds) out of date, it would still probably look just fine. Ideally, this updating could be done in the background by a separate, low-priority thread that constantly looped through all the entities and updated their light lists, while the high-priority rendering thread just used the most up to date version available.

In the long run, it would probably be highly beneficial to separate the rendering of the world from the updating of the world. Having a "rendering" thread that was separate from a "thinking" thread (that was responsible for updating the sorted light list, updating models and textures based on animations or material properties, updating the state of the world based on user input, etc.). It would require that care to be taken to ensure proper synchronization and avoid race-conditions, but it would allow us to decouple the framerate of the renderer from the speed at which we can compute all the other stuff which isn't directly linked to the frame-by-frame rendering process (this includes anything that is supposed to change at a fixed rate of time, like animations; we don't want the animation speed to be linked to the framerate).

Obviously, we would need to maintain compatibility with single-core systems, but multi-core systems are becoming so common that it would make sense to take advantage of that extra power when it exists. Additionally, this type of threaded structure can be effective even on a single processor system by allowing us to prioritize things which must be done in real-time (ie. rendering) from things which won't be noticable to the user if they happen a bit slower, or are updated a bit less often.

Note
Since list is very small (8 elements), insertion sort is used - it beats qsort and other fancy algos in case of a small list and allows a better integration with other parts of code.
Parameters
[in]posOrigin of entity for which light is added
[in]ltngLighting data for entity being updated
[in]lightThe light itself
[in]distSqrSquared distance from entity's origin to the light
See also
R_UpdateLightList
Todo:
will caching VectorDistSqr() results improve the rendering speed?

Definition at line 350 of file r_light.cpp.

References i, cvar_s::integer, lighting_s::lights, lighting_s::numLights, r_dynamic_lights, and VectorDistSqr.

Referenced by R_UpdateLightList().

void R_AddStaticLight ( const vec3_t  origin,
float  radius,
const vec3_t  color 
)

Add static light for model lighting (world already got them baked into lightmap)

Note
To be called from map loader only
See also
SP_light

Definition at line 261 of file r_light.cpp.

References light_s::color, Com_DPrintf(), Com_Printf(), DEBUG_RENDERER, MAX_STATIC_LIGHTS, rendererData_t::numStaticLights, light_s::origin, light_s::radius, refdef, rendererData_t::staticLights, and VectorCopy.

Referenced by SP_light().

void R_AddSustainedLight ( const vec3_t  org,
float  radius,
const vec3_t  color,
float  sustain 
)
void R_ClearStaticLights ( void  )

Remove all static light data.

Note
To be called before loading a new map

Definition at line 300 of file r_light.cpp.

References rendererData_t::numStaticLights, and refdef.

Referenced by R_ModBeginLoading(), and R_SetDefaultState().

void R_DisableLights ( void  )

Definition at line 282 of file r_light.cpp.

References i, MAX_GL_LIGHTS, and MIN_GL_CONSTANT_ATTENUATION.

void R_EnableModelLights ( const light_t **  lights,
int  numLights,
bool  inShadow,
bool  enable 
)

Enable or disable realtime dynamic lighting for models.

Parameters
lightsThe lights to enable
numLightsThe amount of lights in the given lights list
inShadowWhether model is shadowed from the sun
enableWhether to turn realtime lighting on or off
Todo:
is it a good idea?
Todo:
assert?

Definition at line 149 of file r_light.cpp.

References light_s::color, defaultMaterial, rstate_s::dynamic_lighting_enabled, GLPositionTransform(), i, cvar_s::integer, rstate_s::lighting_enabled, MAX_GL_LIGHTS, rendererData_t::modelAmbientColor, light_s::origin, R_DisableAttribute(), r_dynamic_lights, R_EnableAttribute(), r_locals, R_ProgramParameter3fv(), R_ProgramParameter3fvs(), R_ProgramParameter4fvs(), r_programs, r_state, R_UseMaterial(), light_s::radius, refdef, rendererData_t::sunDiffuseColor, rendererData_t::sunVector, Vector4Set, VectorCopy, and rlocals_s::world_matrix.

Referenced by R_DrawAliasModel(), and R_DrawMaterialSurfaces().

void R_UpdateLightList ( entity_t ent)

Recalculate active lights list for the given entity; R_CalcTransform(ent) should be called before this.

Todo:
bad implementation – copying light pointers every frame is a very wrong idea
Note
to accelerate math, the diagonal of aabb is used to approximate max distance from entity's origin to its most distant point while this is a gross exaggeration for many models, the sole purpose of it is to be used for filtering out distant lights, so nothing is broken by it.
Parameters
[in]entEntity to recalculate lights for
See also
R_AddLightToEntity

< Worldspace position for which lighting is calculated

< The root entitity of tagent tree, which holds the lighting data (af any)

< Lighting data for the entity being processed

< conservative estimate of entity's bounding sphere diameter, in vector form

< value of this entity's diameter (approx)

Todo:
Replace this hack with something more legit (hack can cause bizarre stencil shadows if enabled)
Todo:
what if origin is NOT inside aabb? then this estimate will not be conservative enough
Todo:
clear caches when r_dynamic_lights cvar is changed OR always keep maximal # of static lights in the cache
Todo:
Hack to avoid dropships being shadowed by lightclips placed at them. Should be removed once correct global illumination model is done

< as if sun wasn't at infinite distance

Definition at line 394 of file r_light.cpp.

References CACHE_CLEAR_TRESHOLD, lighting_s::cachedLights, rendererData_t::dynamicLights, fakeLightingData, trace_s::fraction, rlocals_s::frame, i, lighting_s::inShadow, cvar_s::integer, lighting_s::lastCachePos, lighting_s::lastLitFrame, lighting_s::lights, MASK_SOLID, lighting_s::numCachedLights, rendererData_t::numDynamicLights, lighting_s::numLights, rendererData_t::numStaticLights, OBJZERO, light_s::origin, R_AddLightToEntity(), r_dynamic_lights, r_locals, R_Trace(), light_s::radius, refdef, RF_ACTOR, rendererData_t::staticLights, rendererData_t::sunVector, rendererData_t::trace, VectorCopy, VectorDist, VectorDistSqr, VectorLength(), and VectorMA().

Referenced by R_DrawAliasModel().

void R_UpdateSustainedLights ( void  )

Updates state of sustained lights; should be called once per frame right before world rendering.

See also
R_RenderFrame
R_AddSustainedLight

Definition at line 83 of file r_light.cpp.

References light_s::color, i, sustain_s::light, MAX_GL_LIGHTS, light_s::origin, R_AddLight(), light_s::radius, refdef, sustain_s::sustain, sustain_s::time, rendererData_t::time, and VectorScale.

Referenced by R_RenderFrame().

Variable Documentation

lighting_t fakeLightingData
static

To return if no actual lighting data is provided

Definition at line 384 of file r_light.cpp.

Referenced by R_UpdateLightList().

sustain_t r_sustainArray[MAX_GL_LIGHTS]
static

Definition at line 30 of file r_light.cpp.

Referenced by R_AddSustainedLight().