X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Flight.c;h=bae17c76f60da0a57a0f52098ba5c019e1cf6b8f;hb=fd241722006def2dfdffaf260daa74dc19332cae;hp=552efa7f0a671aaa1b158ac1ca64331eb960eb47;hpb=6b48d7e83d4ed09ae8db0da2f8a100d68d6e5e66;p=mesa.git diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 552efa7f0a6..bae17c76f60 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.5 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * Copyright (C) 2009 VMware, Inc. All Rights Reserved. @@ -18,46 +17,43 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ +#include "c99_math.h" #include "glheader.h" -#include "imports.h" +#include "util/imports.h" #include "context.h" #include "enums.h" #include "light.h" #include "macros.h" -#include "simple_list.h" #include "mtypes.h" #include "math/m_matrix.h" +#include "util/bitscan.h" void GLAPIENTRY _mesa_ShadeModel( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode)); + _mesa_debug(ctx, "glShadeModel %s\n", _mesa_enum_to_string(mode)); + + if (ctx->Light.ShadeModel == mode) + return; if (mode != GL_FLAT && mode != GL_SMOOTH) { _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel"); return; } - if (ctx->Light.ShadeModel == mode) - return; - FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ShadeModel = mode; - if (mode == GL_FLAT) - ctx->_TriangleCaps |= DD_FLATSHADE; - else - ctx->_TriangleCaps &= ~DD_FLATSHADE; if (ctx->Driver.ShadeModel) ctx->Driver.ShadeModel( ctx, mode ); @@ -70,14 +66,16 @@ _mesa_ShadeModel( GLenum mode ) * triangle or line. */ void GLAPIENTRY -_mesa_ProvokingVertexEXT(GLenum mode) +_mesa_ProvokingVertex(GLenum mode) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&VERBOSE_API) _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode); + if (ctx->Light.ProvokingVertex == mode) + return; + switch (mode) { case GL_FIRST_VERTEX_CONVENTION_EXT: case GL_LAST_VERTEX_CONVENTION_EXT: @@ -87,9 +85,6 @@ _mesa_ProvokingVertexEXT(GLenum mode) return; } - if (ctx->Light.ProvokingVertex == mode) - return; - FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ProvokingVertex = mode; } @@ -107,7 +102,7 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa { struct gl_light *light; - ASSERT(lnum < MAX_LIGHTS); + assert(lnum < MAX_LIGHTS); light = &ctx->Light.Light[lnum]; switch (pname) { @@ -148,20 +143,20 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa COPY_3V(light->SpotDirection, params); break; case GL_SPOT_EXPONENT: - ASSERT(params[0] >= 0.0); - ASSERT(params[0] <= ctx->Const.MaxSpotExponent); + assert(params[0] >= 0.0F); + assert(params[0] <= ctx->Const.MaxSpotExponent); if (light->SpotExponent == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->SpotExponent = params[0]; break; case GL_SPOT_CUTOFF: - ASSERT(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0)); + assert(params[0] == 180.0F || (params[0] >= 0.0F && params[0] <= 90.0F)); if (light->SpotCutoff == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->SpotCutoff = params[0]; - light->_CosCutoff = (GLfloat) (cos(light->SpotCutoff * DEG2RAD)); + light->_CosCutoff = (cosf(light->SpotCutoff * M_PI / 180.0)); if (light->_CosCutoff < 0) light->_CosCutoff = 0; if (light->SpotCutoff != 180.0F) @@ -170,29 +165,28 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa light->_Flags &= ~LIGHT_SPOT; break; case GL_CONSTANT_ATTENUATION: - ASSERT(params[0] >= 0.0); + assert(params[0] >= 0.0F); if (light->ConstantAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->ConstantAttenuation = params[0]; break; case GL_LINEAR_ATTENUATION: - ASSERT(params[0] >= 0.0); + assert(params[0] >= 0.0F); if (light->LinearAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->LinearAttenuation = params[0]; break; case GL_QUADRATIC_ATTENUATION: - ASSERT(params[0] >= 0.0); + assert(params[0] >= 0.0F); if (light->QuadraticAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->QuadraticAttenuation = params[0]; break; default: - _mesa_problem(ctx, "Unexpected pname in _mesa_light()"); - return; + unreachable("Unexpected pname in _mesa_light()"); } if (ctx->Driver.Lightfv) @@ -216,7 +210,6 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) GET_CURRENT_CONTEXT(ctx); GLint i = (GLint) (light - GL_LIGHT0); GLfloat temp[4]; - ASSERT_OUTSIDE_BEGIN_END(ctx); if (i < 0 || i >= (GLint) ctx->Const.MaxLights) { _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light ); @@ -244,31 +237,21 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) params = temp; break; case GL_SPOT_EXPONENT: - if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) { + if (params[0] < 0.0F || params[0] > ctx->Const.MaxSpotExponent) { _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); return; } break; case GL_SPOT_CUTOFF: - if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) { + if ((params[0] < 0.0F || params[0] > 90.0F) && params[0] != 180.0F) { _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); return; } break; case GL_CONSTANT_ATTENUATION: - if (params[0] < 0.0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); - return; - } - break; case GL_LINEAR_ATTENUATION: - if (params[0] < 0.0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); - return; - } - break; case GL_QUADRATIC_ATTENUATION: - if (params[0] < 0.0) { + if (params[0] < 0.0F) { _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); return; } @@ -339,7 +322,6 @@ _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); GLint l = (GLint) (light - GL_LIGHT0); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" ); @@ -389,7 +371,6 @@ _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params ) { GET_CURRENT_CONTEXT(ctx); GLint l = (GLint) (light - GL_LIGHT0); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" ); @@ -460,7 +441,6 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params ) GLenum newenum; GLboolean newbool; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: @@ -470,24 +450,24 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params ) COPY_4V( ctx->Light.Model.Ambient, params ); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: - newbool = (params[0]!=0.0); + if (ctx->API != API_OPENGL_COMPAT) + goto invalid_pname; + newbool = (params[0] != 0.0F); if (ctx->Light.Model.LocalViewer == newbool) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.LocalViewer = newbool; break; case GL_LIGHT_MODEL_TWO_SIDE: - newbool = (params[0]!=0.0); + newbool = (params[0] != 0.0F); if (ctx->Light.Model.TwoSide == newbool) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.TwoSide = newbool; - if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) - ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; - else - ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; break; case GL_LIGHT_MODEL_COLOR_CONTROL: + if (ctx->API != API_OPENGL_COMPAT) + goto invalid_pname; if (params[0] == (GLfloat) GL_SINGLE_COLOR) newenum = GL_SINGLE_COLOR; else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) @@ -503,12 +483,17 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params ) ctx->Light.Model.ColorControl = newenum; break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname ); - break; + goto invalid_pname; } if (ctx->Driver.LightModelfv) ctx->Driver.LightModelfv( ctx, pname, params ); + + return; + +invalid_pname: + _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname ); + return; } @@ -621,17 +606,11 @@ _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname, -static void -invalidate_shine_table( struct gl_context *ctx, GLuint side ); - - - /* Update derived values following a change in ctx->Light.Material */ void _mesa_update_material( struct gl_context *ctx, GLuint bitmask ) { - struct gl_light *light, *list = &ctx->Light.EnabledList; GLfloat (*mat)[4] = ctx->Light.Material.Attrib; if (MESA_VERBOSE & VERBOSE_MATERIAL) @@ -642,14 +621,20 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask ) /* update material ambience */ if (bitmask & MAT_BIT_FRONT_AMBIENT) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatAmbient[0], light->Ambient, mat[MAT_ATTRIB_FRONT_AMBIENT]); } } if (bitmask & MAT_BIT_BACK_AMBIENT) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatAmbient[1], light->Ambient, mat[MAT_ATTRIB_BACK_AMBIENT]); } @@ -670,14 +655,20 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask ) /* update material diffuse values */ if (bitmask & MAT_BIT_FRONT_DIFFUSE) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat[MAT_ATTRIB_FRONT_DIFFUSE] ); } } if (bitmask & MAT_BIT_BACK_DIFFUSE) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat[MAT_ATTRIB_BACK_DIFFUSE] ); } @@ -685,44 +676,43 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask ) /* update material specular values */ if (bitmask & MAT_BIT_FRONT_SPECULAR) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatSpecular[0], light->Specular, mat[MAT_ATTRIB_FRONT_SPECULAR]); } } if (bitmask & MAT_BIT_BACK_SPECULAR) { - foreach (light, list) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; SCALE_3V( light->_MatSpecular[1], light->Specular, mat[MAT_ATTRIB_BACK_SPECULAR]); } } - - if (bitmask & MAT_BIT_FRONT_SHININESS) { - invalidate_shine_table( ctx, 0 ); - } - - if (bitmask & MAT_BIT_BACK_SHININESS) { - invalidate_shine_table( ctx, 1 ); - } } /* * Update the current materials from the given rgba color - * according to the bitmask in ColorMaterialBitmask, which is + * according to the bitmask in _ColorMaterialBitmask, which is * set by glColorMaterial(). */ void _mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] ) { - GLuint bitmask = ctx->Light.ColorMaterialBitmask; + GLbitfield bitmask = ctx->Light._ColorMaterialBitmask; struct gl_material *mat = &ctx->Light.Material; - int i; - for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) - if (bitmask & (1<Attrib[i], color ); + while (bitmask) { + const int i = u_bit_scan(&bitmask); + + COPY_4FV( mat->Attrib[i], color ); + } _mesa_update_material( ctx, bitmask ); } @@ -737,22 +727,23 @@ _mesa_ColorMaterial( GLenum face, GLenum mode ) MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR | MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE | MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&VERBOSE_API) _mesa_debug(ctx, "glColorMaterial %s %s\n", - _mesa_lookup_enum_by_nr(face), - _mesa_lookup_enum_by_nr(mode)); + _mesa_enum_to_string(face), + _mesa_enum_to_string(mode)); bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial"); + if (bitmask == 0) + return; /* error was recorded */ - if (ctx->Light.ColorMaterialBitmask == bitmask && + if (ctx->Light._ColorMaterialBitmask == bitmask && ctx->Light.ColorMaterialFace == face && ctx->Light.ColorMaterialMode == mode) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); - ctx->Light.ColorMaterialBitmask = bitmask; + ctx->Light._ColorMaterialBitmask = bitmask; ctx->Light.ColorMaterialFace = face; ctx->Light.ColorMaterialMode = mode; @@ -772,7 +763,7 @@ _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) GET_CURRENT_CONTEXT(ctx); GLuint f; GLfloat (*mat)[4] = ctx->Light.Material.Attrib; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ + FLUSH_VERTICES(ctx, 0); /* update materials */ FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ @@ -804,6 +795,10 @@ _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) *params = mat[MAT_ATTRIB_SHININESS(f)][0]; break; case GL_COLOR_INDEXES: + if (ctx->API != API_OPENGL_COMPAT) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); + return; + } params[0] = mat[MAT_ATTRIB_INDEXES(f)][0]; params[1] = mat[MAT_ATTRIB_INDEXES(f)][1]; params[2] = mat[MAT_ATTRIB_INDEXES(f)][2]; @@ -820,8 +815,10 @@ _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) GET_CURRENT_CONTEXT(ctx); GLuint f; GLfloat (*mat)[4] = ctx->Light.Material.Attrib; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ + assert(ctx->API == API_OPENGL_COMPAT); + + FLUSH_VERTICES(ctx, 0); /* update materials */ FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ if (face==GL_FRONT) { @@ -874,126 +871,6 @@ _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) -/**********************************************************************/ -/***** Lighting computation *****/ -/**********************************************************************/ - - -/* - * Notes: - * When two-sided lighting is enabled we compute the color (or index) - * for both the front and back side of the primitive. Then, when the - * orientation of the facet is later learned, we can determine which - * color (or index) to use for rendering. - * - * KW: We now know orientation in advance and only shade for - * the side or sides which are actually required. - * - * Variables: - * n = normal vector - * V = vertex position - * P = light source position - * Pe = (0,0,0,1) - * - * Precomputed: - * IF P[3]==0 THEN - * // light at infinity - * IF local_viewer THEN - * _VP_inf_norm = unit vector from V to P // Precompute - * ELSE - * // eye at infinity - * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute - * ENDIF - * ENDIF - * - * Functions: - * Normalize( v ) = normalized vector v - * Magnitude( v ) = length of vector v - */ - - - -/* Calculate a new shine table. Doing this here saves a branch in - * lighting, and the cost of doing it early may be partially offset - * by keeping a MRU cache of shine tables for various shine values. - */ -static void -invalidate_shine_table( struct gl_context *ctx, GLuint side ) -{ - ASSERT(side < 2); - if (ctx->_ShineTable[side]) - ctx->_ShineTable[side]->refcount--; - ctx->_ShineTable[side] = NULL; -} - - -static void -validate_shine_table( struct gl_context *ctx, GLuint side, GLfloat shininess ) -{ - struct gl_shine_tab *list = ctx->_ShineTabList; - struct gl_shine_tab *s; - - ASSERT(side < 2); - - foreach(s, list) - if ( s->shininess == shininess ) - break; - - if (s == list) { - GLint j; - GLfloat *m; - - foreach(s, list) - if (s->refcount == 0) - break; - - m = s->tab; - m[0] = 0.0; - if (shininess == 0.0) { - for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) - m[j] = 1.0; - } - else { - for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { - GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); - if (x < 0.005) /* underflow check */ - x = 0.005; - t = pow(x, shininess); - if (t > 1e-20) - m[j] = (GLfloat) t; - else - m[j] = 0.0; - } - m[SHINE_TABLE_SIZE] = 1.0; - } - - s->shininess = shininess; - } - - if (ctx->_ShineTable[side]) - ctx->_ShineTable[side]->refcount--; - - ctx->_ShineTable[side] = s; - move_to_tail( list, s ); - s->refcount++; -} - - -void -_mesa_validate_all_lighting_tables( struct gl_context *ctx ) -{ - GLfloat shininess; - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; - if (!ctx->_ShineTable[0] || ctx->_ShineTable[0]->shininess != shininess) - validate_shine_table( ctx, 0, shininess ); - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; - if (!ctx->_ShineTable[1] || ctx->_ShineTable[1]->shininess != shininess) - validate_shine_table( ctx, 1, shininess ); -} - - /** * Examine current lighting parameters to determine if the optimized lighting * function can be used. @@ -1003,23 +880,25 @@ _mesa_validate_all_lighting_tables( struct gl_context *ctx ) void _mesa_update_lighting( struct gl_context *ctx ) { - struct gl_light *light; + GLbitfield flags = 0; ctx->Light._NeedEyeCoords = GL_FALSE; - ctx->Light._Flags = 0; if (!ctx->Light.Enabled) return; - foreach(light, &ctx->Light.EnabledList) { - ctx->Light._Flags |= light->_Flags; + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; + flags |= light->_Flags; } ctx->Light._NeedVertices = - ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || + ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || ctx->Light.Model.LocalViewer); - ctx->Light._NeedEyeCoords = ((ctx->Light._Flags & LIGHT_POSITIONAL) || + ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) || ctx->Light.Model.LocalViewer); /* XXX: This test is overkill & needs to be fixed both for software and @@ -1066,7 +945,6 @@ _mesa_update_lighting( struct gl_context *ctx ) static void compute_light_positions( struct gl_context *ctx ) { - struct gl_light *light; static const GLfloat eye_z[3] = { 0, 0, 1 }; if (!ctx->Light.Enabled) @@ -1079,10 +957,10 @@ compute_light_positions( struct gl_context *ctx ) TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m ); } - /* Make sure all the light tables are updated before the computation */ - _mesa_validate_all_lighting_tables(ctx); - - foreach (light, &ctx->Light.EnabledList) { + GLbitfield mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_light *light = &ctx->Light.Light[i]; if (ctx->_NeedEyeCoords) { /* _Position is in eye coordinate space */ @@ -1108,7 +986,7 @@ compute_light_positions( struct gl_context *ctx ) } else { /* positional light w/ homogeneous coordinate, divide by W */ - GLfloat wInv = (GLfloat)1.0 / light->_Position[3]; + GLfloat wInv = 1.0F / light->_Position[3]; light->_Position[0] *= wInv; light->_Position[1] *= wInv; light->_Position[2] *= wInv; @@ -1154,14 +1032,16 @@ static void update_modelview_scale( struct gl_context *ctx ) { ctx->_ModelViewInvScale = 1.0F; + ctx->_ModelViewInvScaleEyespace = 1.0F; if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) { const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv; GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; - if (f < 1e-12) f = 1.0; + if (f < 1e-12f) f = 1.0f; if (ctx->_NeedEyeCoords) - ctx->_ModelViewInvScale = (GLfloat) INV_SQRTF(f); + ctx->_ModelViewInvScale = 1.0f / sqrtf(f); else - ctx->_ModelViewInvScale = (GLfloat) SQRTF(f); + ctx->_ModelViewInvScale = sqrtf(f); + ctx->_ModelViewInvScaleEyespace = 1.0f / sqrtf(f); } } @@ -1243,8 +1123,6 @@ _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ) static void init_light( struct gl_light *l, GLuint n ) { - make_empty_list( l ); - ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 ); if (n==0) { ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 ); @@ -1314,10 +1192,10 @@ _mesa_init_lighting( struct gl_context *ctx ) GLuint i; /* Lighting group */ + ctx->Light._EnabledLights = 0; for (i = 0; i < MAX_LIGHTS; i++) { init_light( &ctx->Light.Light[i], i ); } - make_empty_list( &ctx->Light.EnabledList ); init_lightmodel( &ctx->Light.Model ); init_material( &ctx->Light.Material ); @@ -1326,44 +1204,19 @@ _mesa_init_lighting( struct gl_context *ctx ) ctx->Light.Enabled = GL_FALSE; ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK; ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE; - ctx->Light.ColorMaterialBitmask = _mesa_material_bitmask( ctx, + ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx, GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ~0, NULL ); ctx->Light.ColorMaterialEnabled = GL_FALSE; - ctx->Light.ClampVertexColor = GL_TRUE; - - /* Lighting miscellaneous */ - ctx->_ShineTabList = MALLOC_STRUCT( gl_shine_tab ); - make_empty_list( ctx->_ShineTabList ); - /* Allocate 10 (arbitrary) shininess lookup tables */ - for (i = 0 ; i < 10 ; i++) { - struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab ); - s->shininess = -1; - s->refcount = 0; - insert_at_tail( ctx->_ShineTabList, s ); - } + ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT; + ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT; /* Miscellaneous */ ctx->Light._NeedEyeCoords = GL_FALSE; ctx->_NeedEyeCoords = GL_FALSE; ctx->_ForceEyeCoords = GL_FALSE; ctx->_ModelViewInvScale = 1.0; -} - - -/** - * Deallocate malloc'd lighting state attached to given context. - */ -void -_mesa_free_lighting_data( struct gl_context *ctx ) -{ - struct gl_shine_tab *s, *tmps; - - /* Free lighting shininess exponentiation table */ - foreach_s( s, tmps, ctx->_ShineTabList ) { - free( s ); - } - free( ctx->_ShineTabList ); + ctx->_ModelViewInvScaleEyespace = 1.0; }