Update state derived from light position, spot direction. Called upon: _NEW_MODELVIEW _NEW_LIGHT _TNL_NEW_NEED_EYE_COORDS
Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled. Also update on lighting space changes.
Definition at line 1092 of file light.c.
Referenced by _mesa_update_tnl_spaces().
{
struct gl_light *light;
static const GLfloat eye_z[3] = { 0, 0, 1 };
if (!ctx->Light.Enabled)
return;
if (ctx->_NeedEyeCoords) {
COPY_3V( ctx->_EyeZDir, eye_z );
}
else {
TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
}
foreach (light, &ctx->Light.EnabledList) {
if (ctx->_NeedEyeCoords) {
COPY_4FV( light->_Position, light->EyePosition );
}
else {
TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
light->EyePosition );
}
if (!(light->_Flags & LIGHT_POSITIONAL)) {
COPY_3V( light->_VP_inf_norm, light->_Position );
NORMALIZE_3FV( light->_VP_inf_norm );
if (!ctx->Light.Model.LocalViewer) {
ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
NORMALIZE_3FV( light->_h_inf_norm );
}
light->_VP_inf_spot_attenuation = 1.0;
}
else {
GLfloat wInv = (GLfloat)1.0 / light->_Position[3];
light->_Position[0] *= wInv;
light->_Position[1] *= wInv;
light->_Position[2] *= wInv;
}
if (light->_Flags & LIGHT_SPOT) {
if (ctx->_NeedEyeCoords) {
COPY_3V( light->_NormDirection, light->EyeDirection );
}
else {
TRANSFORM_NORMAL( light->_NormDirection,
light->EyeDirection,
ctx->ModelviewMatrixStack.Top->m);
}
NORMALIZE_3FV( light->_NormDirection );
if (!(light->_Flags & LIGHT_POSITIONAL)) {
GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
light->_NormDirection);
if (PV_dot_dir > light->_CosCutoff) {
double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
int k = (int) x;
light->_VP_inf_spot_attenuation =
(GLfloat) (light->_SpotExpTable[k][0] +
(x-k)*light->_SpotExpTable[k][1]);
}
else {
light->_VP_inf_spot_attenuation = 0;
}
}
}
}
}