unsigned light_color_material_mask:12;
unsigned light_material_mask:12;
+ unsigned need_eye_coords:1;
unsigned normalize:1;
unsigned rescale_normals:1;
unsigned fog_source_is_depth:1;
*/
assert(fp);
+ key->need_eye_coords = ctx->_NeedEyeCoords;
+
key->fragprog_inputs_read = fp->Base.InputsRead;
if (ctx->RenderMode == GL_FEEDBACK) {
struct ureg eye_position;
struct ureg eye_position_normalized;
- struct ureg eye_normal;
+ struct ureg transformed_normal;
struct ureg identity;
GLuint materials;
struct ureg src )
{
struct ureg tmp = get_temp(p);
- emit_op2(p, OPCODE_DP3, tmp, 0, src, src);
- emit_op1(p, OPCODE_RSQ, tmp, 0, tmp);
- emit_op2(p, OPCODE_MUL, dest, 0, src, tmp);
+ emit_op2(p, OPCODE_DP3, tmp, WRITEMASK_X, src, src);
+ emit_op1(p, OPCODE_RSQ, tmp, WRITEMASK_X, tmp);
+ emit_op2(p, OPCODE_MUL, dest, 0, src, swizzle1(tmp, X));
release_temp(p, tmp);
}
}
-static struct ureg get_eye_normal( struct tnl_program *p )
+static struct ureg get_transformed_normal( struct tnl_program *p )
{
- if (is_undef(p->eye_normal)) {
+ if (is_undef(p->transformed_normal) &&
+ !p->state->need_eye_coords &&
+ !p->state->normalize &&
+ !(p->state->need_eye_coords == p->state->rescale_normals))
+ {
+ p->transformed_normal = register_input(p, VERT_ATTRIB_NORMAL );
+ }
+ else if (is_undef(p->transformed_normal))
+ {
struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
struct ureg mvinv[3];
+ struct ureg transformed_normal = reserve_temp(p);
- register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,
- STATE_MATRIX_INVTRANS, mvinv );
+ if (p->state->need_eye_coords) {
+ register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,
+ STATE_MATRIX_INVTRANS, mvinv );
- p->eye_normal = reserve_temp(p);
-
- /* Transform to eye space:
- */
- emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal );
+ /* Transform to eye space:
+ */
+ emit_matrix_transform_vec3( p, transformed_normal, mvinv, normal );
+ normal = transformed_normal;
+ }
/* Normalize/Rescale:
*/
if (p->state->normalize) {
- emit_normalize_vec3( p, p->eye_normal, p->eye_normal );
+ emit_normalize_vec3( p, transformed_normal, normal );
+ normal = transformed_normal;
}
- else if (p->state->rescale_normals) {
+ else if (p->state->need_eye_coords == p->state->rescale_normals) {
+ /* This is already adjusted for eye/non-eye rendering:
+ */
struct ureg rescale = register_param2(p, STATE_INTERNAL,
- STATE_NORMAL_SCALE);
+ STATE_NORMAL_SCALE);
- emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_normal,
+ emit_op2( p, OPCODE_MUL, transformed_normal, 0, normal,
swizzle1(rescale, X));
+ normal = transformed_normal;
}
+
+ assert(normal.file == PROGRAM_TEMPORARY);
+ p->transformed_normal = normal;
}
- return p->eye_normal;
+ return p->transformed_normal;
}
*/
if (!p->state->unit[i].light_spotcutoff_is_180) {
struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL,
- STATE_SPOT_DIR_NORMALIZED, i);
+ STATE_LIGHT_SPOT_DIR_NORMALIZED, i);
struct ureg spot = get_temp(p);
struct ureg slt = get_temp(p);
const GLboolean twoside = p->state->light_twoside;
const GLboolean separate = p->state->separate_specular;
GLuint nr_lights = 0, count = 0;
- struct ureg normal = get_eye_normal(p);
+ struct ureg normal = get_transformed_normal(p);
struct ureg lit = get_temp(p);
struct ureg dots = get_temp(p);
struct ureg _col0 = undef, _col1 = undef;
/* Can used precomputed constants in this case.
* Attenuation never applies to infinite lights.
*/
- VPpli = register_param3(p, STATE_LIGHT, i,
- STATE_POSITION_NORMALIZED);
+ VPpli = register_param3(p, STATE_INTERNAL,
+ STATE_LIGHT_POSITION_NORMALIZED, i);
if (p->state->light_local_viewer) {
struct ureg eye_hat = get_eye_position_normalized(p);
half = get_temp(p);
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
emit_normalize_vec3(p, half, half);
} else {
- half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR);
+ half = register_param3(p, STATE_INTERNAL,
+ STATE_LIGHT_HALF_VECTOR, i);
}
}
else {
- struct ureg Ppli = register_param3(p, STATE_LIGHT, i,
- STATE_POSITION);
+ struct ureg Ppli = register_param3(p, STATE_INTERNAL,
+ STATE_LIGHT_POSITION, i);
struct ureg V = get_eye_position(p);
struct ureg dist = get_temp(p);
struct ureg dest,
GLuint writemask )
{
- struct ureg normal = get_eye_normal(p);
+ struct ureg normal = get_transformed_normal(p);
struct ureg eye_hat = get_eye_position_normalized(p);
struct ureg tmp = get_temp(p);
struct ureg dest,
GLuint writemask )
{
- struct ureg normal = get_eye_normal(p);
+ struct ureg normal = get_transformed_normal(p);
struct ureg eye_hat = get_eye_position_normalized(p);
struct ureg tmp = get_temp(p);
struct ureg half = register_scalar_const(p, .5);
}
if (normal_mask) {
- struct ureg normal = get_eye_normal(p);
+ struct ureg normal = get_transformed_normal(p);
emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal );
}
p.program = program;
p.eye_position = undef;
p.eye_position_normalized = undef;
- p.eye_normal = undef;
+ p.transformed_normal = undef;
p.identity = undef;
p.temp_in_use = 0;
value[3] = 1.0;
}
return;
- case STATE_POSITION_NORMALIZED:
- COPY_4V(value, ctx->Light.Light[ln].EyePosition);
- NORMALIZE_3FV( value );
- return;
default:
_mesa_problem(ctx, "Invalid light state in fetch_state");
return;
value[2] = ctx->Fog.Density * ONE_DIV_LN2;
value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2;
return;
- case STATE_SPOT_DIR_NORMALIZED: {
+
+ case STATE_LIGHT_SPOT_DIR_NORMALIZED: {
/* here, state[2] is the light number */
/* pre-normalize spot dir */
const GLuint ln = (GLuint) state[2];
- COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
- NORMALIZE_3FV(value);
+ COPY_3V(value, ctx->Light.Light[ln]._NormDirection);
value[3] = ctx->Light.Light[ln]._CosCutoff;
return;
}
+
+ case STATE_LIGHT_POSITION: {
+ const GLuint ln = (GLuint) state[2];
+ COPY_4V(value, ctx->Light.Light[ln]._Position);
+ return;
+ }
+
+ case STATE_LIGHT_POSITION_NORMALIZED: {
+ const GLuint ln = (GLuint) state[2];
+ COPY_4V(value, ctx->Light.Light[ln]._Position);
+ NORMALIZE_3FV( value );
+ return;
+ }
+
+ case STATE_LIGHT_HALF_VECTOR: {
+ const GLuint ln = (GLuint) state[2];
+ 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]._Position);
+ NORMALIZE_3FV(p);
+ ADD_3V(value, p, ctx->_EyeZDir);
+ NORMALIZE_3FV(value);
+ value[3] = 1.0;
+ return;
+ }
+
+
+
case STATE_PT_SCALE:
value[0] = ctx->Pixel.RedScale;
value[1] = ctx->Pixel.GreenScale;
append(dst, "normalScale");
break;
case STATE_INTERNAL:
- case STATE_POSITION_NORMALIZED:
append(dst, "(internal)");
break;
case STATE_PT_SCALE: