FLUSH_VERTICES(ctx, _NEW_LIGHT);
COPY_4V( light->Specular, params );
break;
- case GL_POSITION:
+ case GL_POSITION: {
/* NOTE: position has already been transformed by ModelView! */
if (TEST_EQ_4V(light->EyePosition, params))
return;
light->_Flags |= LIGHT_POSITIONAL;
else
light->_Flags &= ~LIGHT_POSITIONAL;
+
+ static const GLfloat eye_z[] = {0, 0, 1};
+ GLfloat p[3];
+ /* Compute infinite half angle vector:
+ * halfVector = normalize(normalize(lightPos) + (0, 0, 1))
+ * light.EyePosition.w should be 0 for infinite lights.
+ */
+ COPY_3V(p, params);
+ NORMALIZE_3FV(p);
+ ADD_3V(p, p, eye_z);
+ NORMALIZE_3FV(p);
+ COPY_3V(light->_HalfVector, p);
+ light->_HalfVector[3] = 1.0;
break;
+ }
case GL_SPOT_DIRECTION:
/* NOTE: Direction already transformed by inverse ModelView! */
if (TEST_EQ_3V(light->SpotDirection, params))
*/
struct gl_light
{
- GLfloat Ambient[4]; /**< ambient color */
- GLfloat Diffuse[4]; /**< diffuse color */
- GLfloat Specular[4]; /**< specular color */
- GLfloat EyePosition[4]; /**< position in eye coordinates */
- GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */
- GLfloat SpotExponent;
- GLfloat SpotCutoff; /**< in degrees */
- GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
- GLfloat ConstantAttenuation;
- GLfloat LinearAttenuation;
- GLfloat QuadraticAttenuation;
+ union {
+ struct {
+ /* These must be in the same order as the STATE_* enums,
+ * which should also match the order of gl_LightSource members.
+ */
+ GLfloat Ambient[4]; /**< STATE_AMBIENT */
+ GLfloat Diffuse[4]; /**< STATE_DIFFUSE */
+ GLfloat Specular[4]; /**< STATE_SPECULAR */
+ GLfloat EyePosition[4]; /**< STATE_POSITION in eye coordinates */
+ GLfloat _HalfVector[4]; /**< STATE_HALF_VECTOR */
+ GLfloat SpotDirection[3]; /**< STATE_SPOT_DIRECTION in eye coordinates */
+ GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
+ GLfloat ConstantAttenuation; /**< STATE_ATTENUATION */
+ GLfloat LinearAttenuation;
+ GLfloat QuadraticAttenuation;
+ GLfloat SpotExponent;
+ GLfloat SpotCutoff; /**< STATE_SPOT_CUTOFF in degrees */
+ };
+ GLfloat Values[29];
+ };
+
GLboolean Enabled; /**< On/off flag */
/**
/* state[1] is the light number */
const GLuint ln = (GLuint) state[1];
/* state[2] is the light attribute */
- switch (state[2]) {
- case STATE_AMBIENT:
- COPY_4V(value, ctx->Light.Light[ln].Ambient);
- return;
- case STATE_DIFFUSE:
- COPY_4V(value, ctx->Light.Light[ln].Diffuse);
- return;
- case STATE_SPECULAR:
- COPY_4V(value, ctx->Light.Light[ln].Specular);
- return;
- case STATE_POSITION:
- COPY_4V(value, ctx->Light.Light[ln].EyePosition);
- return;
- case STATE_ATTENUATION:
- value[0] = ctx->Light.Light[ln].ConstantAttenuation;
- value[1] = ctx->Light.Light[ln].LinearAttenuation;
- value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
- value[3] = ctx->Light.Light[ln].SpotExponent;
- return;
- case STATE_SPOT_DIRECTION:
- COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
- value[3] = ctx->Light.Light[ln]._CosCutoff;
- return;
- case STATE_SPOT_CUTOFF:
- value[0] = ctx->Light.Light[ln].SpotCutoff;
- return;
- case STATE_HALF_VECTOR:
- {
- static const GLfloat eye_z[] = {0, 0, 1};
- GLfloat p[3];
- /* Compute infinite half angle vector:
- * halfVector = normalize(normalize(lightPos) + (0, 0, 1))
- * light.EyePosition.w should be 0 for infinite lights.
- */
- COPY_3V(p, ctx->Light.Light[ln].EyePosition);
- NORMALIZE_3FV(p);
- ADD_3V(p, p, eye_z);
- NORMALIZE_3FV(p);
- COPY_3V(value, p);
- value[3] = 1.0;
- }
- return;
- default:
- unreachable("Invalid light state in fetch_state");
- return;
- }
+ const unsigned index = state[2] - STATE_AMBIENT;
+ assert(index < 8);
+ if (index != STATE_SPOT_CUTOFF)
+ COPY_4V(value, &ctx->Light.Light[ln].Values[index * 4]);
+ else
+ value[0] = ctx->Light.Light[ln].Values[index * 4];
+ return;
}
case STATE_LIGHTMODEL_AMBIENT:
COPY_4V(value, ctx->Light.Model.Ambient);
STATE_PROGRAM_MATRIX_TRANSPOSE,
STATE_PROGRAM_MATRIX_INVTRANS,
+ /* These 8 enums must be in the same order as the gl_light union members,
+ * which should also match the order of gl_LightSource members.
+ */
STATE_AMBIENT,
STATE_DIFFUSE,
STATE_SPECULAR,
- STATE_EMISSION,
- STATE_SHININESS,
- STATE_HALF_VECTOR,
-
STATE_POSITION, /**< xyzw = position */
- STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */
+ STATE_HALF_VECTOR,
STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
+ STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */
STATE_SPOT_CUTOFF, /**< x = cutoff, yzw = undefined */
+ STATE_EMISSION,
+ STATE_SHININESS,
+
STATE_TEXGEN_EYE_S,
STATE_TEXGEN_EYE_T,
STATE_TEXGEN_EYE_R,