diff options
Diffstat (limited to 'src/mesa/main/light.c')
-rw-r--r-- | src/mesa/main/light.c | 254 |
1 files changed, 123 insertions, 131 deletions
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 123ae89adee..e5159253e6a 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,4 +1,4 @@ -/* $Id: light.c,v 1.23 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: light.c,v 1.24 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -91,93 +91,85 @@ void _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); - GLint l; - GLint nParams; + GLint i = (GLint) (light - GL_LIGHT0); + struct gl_light *l = &ctx->Light.Light[i]; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight"); - l = (GLint) (light - GL_LIGHT0); - - if (l < 0 || l >= MAX_LIGHTS) { + if (i < 0 || i >= MAX_LIGHTS) { gl_error( ctx, GL_INVALID_ENUM, "glLight" ); return; } switch (pname) { case GL_AMBIENT: - COPY_4V( ctx->Light.Light[l].Ambient, params ); - nParams = 4; + COPY_4V( l->Ambient, params ); break; case GL_DIFFUSE: - COPY_4V( ctx->Light.Light[l].Diffuse, params ); - nParams = 4; + COPY_4V( l->Diffuse, params ); break; case GL_SPECULAR: - COPY_4V( ctx->Light.Light[l].Specular, params ); - nParams = 4; + COPY_4V( l->Specular, params ); break; case GL_POSITION: /* transform position by ModelView matrix */ - TRANSFORM_POINT( ctx->Light.Light[l].EyePosition, - ctx->ModelView.m, - params ); - nParams = 4; + TRANSFORM_POINT( l->EyePosition, ctx->ModelView.m, params ); + if (l->EyePosition[3] != 0.0F) + l->_Flags |= LIGHT_POSITIONAL; + else + l->_Flags &= ~LIGHT_POSITIONAL; break; case GL_SPOT_DIRECTION: /* transform direction by inverse modelview */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { gl_matrix_analyze( &ctx->ModelView ); } - TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection, - params, - ctx->ModelView.inv ); - nParams = 3; + TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv ); break; case GL_SPOT_EXPONENT: if (params[0]<0.0 || params[0]>128.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - if (ctx->Light.Light[l].SpotExponent != params[0]) { - ctx->Light.Light[l].SpotExponent = params[0]; - gl_compute_spot_exp_table( &ctx->Light.Light[l] ); + if (l->SpotExponent != params[0]) { + l->SpotExponent = params[0]; + gl_compute_spot_exp_table( l ); } - nParams = 1; break; case GL_SPOT_CUTOFF: if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].SpotCutoff = params[0]; - ctx->Light.Light[l]._CosCutoff = cos(params[0]*DEG2RAD); - if (ctx->Light.Light[l]._CosCutoff < 0) - ctx->Light.Light[l]._CosCutoff = 0; - nParams = 1; + l->SpotCutoff = params[0]; + l->_CosCutoff = cos(params[0]*DEG2RAD); + if (l->_CosCutoff < 0) + l->_CosCutoff = 0; + if (l->SpotCutoff != 180.0F) + l->_Flags |= LIGHT_SPOT; + else + l->_Flags &= ~LIGHT_SPOT; break; case GL_CONSTANT_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].ConstantAttenuation = params[0]; - nParams = 1; + l->ConstantAttenuation = params[0]; break; case GL_LINEAR_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].LinearAttenuation = params[0]; - nParams = 1; + l->LinearAttenuation = params[0]; break; case GL_QUADRATIC_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].QuadraticAttenuation = params[0]; - nParams = 1; + l->QuadraticAttenuation = params[0]; break; default: gl_error( ctx, GL_INVALID_ENUM, "glLight" ); @@ -185,7 +177,7 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) } if (ctx->Driver.Lightfv) - ctx->Driver.Lightfv( ctx, light, pname, params, nParams ); + ctx->Driver.Lightfv( ctx, light, pname, params ); ctx->NewState |= _NEW_LIGHT; } @@ -612,11 +604,9 @@ void gl_update_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, src[0].Specular, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); - light->_IsMatSpecular[0] = - (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); + light->_IsMatSpecular[0] = + (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); } COPY_4FV( mat->Specular, src[0].Specular ); } @@ -625,11 +615,9 @@ void gl_update_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, src[1].Specular, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); - light->_IsMatSpecular[1] = - (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); + light->_IsMatSpecular[1] = + (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); } COPY_4FV( mat->Specular, src[1].Specular ); } @@ -771,11 +759,9 @@ void gl_update_color_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, color, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); - light->_IsMatSpecular[0] = - (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); + light->_IsMatSpecular[0] = + (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); } COPY_4FV( mat->Specular, color ); } @@ -785,11 +771,9 @@ void gl_update_color_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, color, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); - light->_IsMatSpecular[1] = - (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); + light->_IsMatSpecular[1] = + (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); } COPY_4FV( mat->Specular, color ); } @@ -1225,35 +1209,45 @@ void gl_update_lighting( GLcontext *ctx ) { struct gl_light *light; - + ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); + ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT; + ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT; ctx->Light._Flags = 0; + + if (!ctx->Light.Enabled) + return; - foreach(light, &ctx->Light.EnabledList) { - - light->_Flags = 0; + ctx->_NeedNormals |= NEED_NORMALS_LIGHT; - if (light->EyePosition[3] != 0.0F) - light->_Flags |= LIGHT_POSITIONAL; - - if (LEN_SQUARED_3FV(light->Specular) > 1e-16) - light->_Flags |= LIGHT_SPECULAR; - - if (light->SpotCutoff != 180.0F) - light->_Flags |= LIGHT_SPOT; + if (ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); + foreach(light, &ctx->Light.EnabledList) { ctx->Light._Flags |= light->_Flags; } ctx->Light._NeedVertices = ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || - (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) || - (ctx->Light.Model.LocalViewer && (ctx->Light._Flags & LIGHT_SPECULAR))); - + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || + ctx->Light.Model.LocalViewer); + + if ((ctx->Light._Flags & LIGHT_POSITIONAL) || + ctx->Light.Model.LocalViewer) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + + + /* XXX: This test is overkill & needs to be fixed both for software and + * hardware t&l drivers. The above should be sufficient & should + * be tested to verify this. + */ + if (ctx->Light._NeedVertices) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + /* Precompute some shading values. */ if (ctx->Visual.RGBAflag) { - GLuint sides = ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1); + GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1; GLuint side; for (side=0; side < sides; side++) { struct gl_material *mat = &ctx->Light.Material[side]; @@ -1272,14 +1266,10 @@ gl_update_lighting( GLcontext *ctx ) const struct gl_material *mat = &ctx->Light.Material[side]; SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse ); SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient ); - if (light->_Flags & LIGHT_SPECULAR) { - SCALE_3V( light->_MatSpecular[side], light->Specular, - mat->Specular); - light->_IsMatSpecular[side] = - (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16); - } - else - light->_IsMatSpecular[side] = 0; + SCALE_3V( light->_MatSpecular[side], light->Specular, + mat->Specular); + light->_IsMatSpecular[side] = + (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16); } } } @@ -1290,28 +1280,34 @@ gl_update_lighting( GLcontext *ctx ) light->_sli = DOT3(ci, light->Specular); } } -} + gl_update_lighting_function(ctx); +} -/* Need to seriously restrict the circumstances under which these - * calc's are performed. +/* _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. */ void gl_compute_light_positions( GLcontext *ctx ) { struct gl_light *light; - - if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) { - static const GLfloat eye_z[3] = { 0, 0, 1 }; - if (ctx->_NeedEyeCoords) { - COPY_3V( ctx->_EyeZDir, eye_z ); - } - else { - TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m ); - } - } + 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->ModelView.m ); + } + foreach (light, &ctx->Light.EnabledList) { if (ctx->_NeedEyeCoords) { @@ -1336,7 +1332,7 @@ gl_compute_light_positions( GLcontext *ctx ) } if (light->_Flags & LIGHT_SPOT) { - if (ctx->_NeedEyeNormals) { + if (ctx->_NeedEyeCoords) { COPY_3V( light->_NormDirection, light->EyeDirection ); } else { @@ -1347,9 +1343,6 @@ gl_compute_light_positions( GLcontext *ctx ) NORMALIZE_3FV( light->_NormDirection ); - - /* Unlikely occurrance? - */ if (!(light->_Flags & LIGHT_POSITIONAL)) { GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm, light->_NormDirection); @@ -1370,52 +1363,51 @@ gl_compute_light_positions( GLcontext *ctx ) } +/* _NEW_TRANSFORM + * _NEW_MODELVIEW + * _TNL_NEW_NEED_NORMALS + * _TNL_NEW_NEED_EYE_COORDS + * + * Update on (_NEW_TRANSFORM|_NEW_MODELVIEW) + * And also on NewLightingSpaces() callback. + */ void gl_update_normal_transform( GLcontext *ctx ) { - ctx->_vb_rescale_factor = 1.0; + + if (!ctx->_NeedNormals) { + ctx->_NormalTransform = 0; + return; + } if (ctx->_NeedEyeCoords) { - if (ctx->_NeedNormals) { - GLuint transform = NORM_TRANSFORM_NO_ROT; - - if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) - transform = NORM_TRANSFORM; + GLuint transform = NORM_TRANSFORM_NO_ROT; + + if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | + MAT_FLAG_ROTATION | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_PERSPECTIVE)) + transform = NORM_TRANSFORM; - ctx->_vb_rescale_factor = ctx->_rescale_factor; - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE]; - } - else if (ctx->Transform.RescaleNormals && - ctx->_rescale_factor != 1.0) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE]; - } - else { - ctx->_NormalTransform = gl_normal_tab[transform]; - } + if (ctx->Transform.Normalize) { + ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE]; + } + else if (ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE]; } else { - ctx->_NormalTransform = 0; + ctx->_NormalTransform = gl_normal_tab[transform]; } } else { - if (ctx->_NeedNormals) { - ctx->_vb_rescale_factor = 1.0/ctx->_rescale_factor; - - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE]; - } - else if (!ctx->Transform.RescaleNormals && - ctx->_rescale_factor != 1.0) { - ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE]; - } - else { - ctx->_NormalTransform = 0; - } + if (ctx->Transform.Normalize) { + ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE]; + } + else if (!ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE]; } else { ctx->_NormalTransform = 0; |