• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Mesa 3-D graphics library
3   *
4   * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5   * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6   *
7   * Permission is hereby granted, free of charge, to any person obtaining a
8   * copy of this software and associated documentation files (the "Software"),
9   * to deal in the Software without restriction, including without limitation
10   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11   * and/or sell copies of the Software, and to permit persons to whom the
12   * Software is furnished to do so, subject to the following conditions:
13   *
14   * The above copyright notice and this permission notice shall be included
15   * in all copies or substantial portions of the Software.
16   *
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18   * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23   * OTHER DEALINGS IN THE SOFTWARE.
24   */
25  
26  
27  #include "c99_math.h"
28  #include "glheader.h"
29  #include "context.h"
30  #include "enums.h"
31  #include "light.h"
32  #include "macros.h"
33  #include "mtypes.h"
34  #include "math/m_matrix.h"
35  #include "util/bitscan.h"
36  
37  
38  void GLAPIENTRY
_mesa_ShadeModel(GLenum mode)39  _mesa_ShadeModel( GLenum mode )
40  {
41     GET_CURRENT_CONTEXT(ctx);
42  
43     if (MESA_VERBOSE & VERBOSE_API)
44        _mesa_debug(ctx, "glShadeModel %s\n", _mesa_enum_to_string(mode));
45  
46     if (ctx->Light.ShadeModel == mode)
47        return;
48  
49     if (mode != GL_FLAT && mode != GL_SMOOTH) {
50        _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel");
51        return;
52     }
53  
54     FLUSH_VERTICES(ctx, _NEW_LIGHT);
55     ctx->Light.ShadeModel = mode;
56  
57     if (ctx->Driver.ShadeModel)
58        ctx->Driver.ShadeModel( ctx, mode );
59  }
60  
61  
62  /**
63   * Set the provoking vertex (the vertex which specifies the prim's
64   * color when flat shading) to either the first or last vertex of the
65   * triangle or line.
66   */
67  void GLAPIENTRY
_mesa_ProvokingVertex(GLenum mode)68  _mesa_ProvokingVertex(GLenum mode)
69  {
70     GET_CURRENT_CONTEXT(ctx);
71  
72     if (MESA_VERBOSE&VERBOSE_API)
73        _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode);
74  
75     if (ctx->Light.ProvokingVertex == mode)
76        return;
77  
78     switch (mode) {
79     case GL_FIRST_VERTEX_CONVENTION_EXT:
80     case GL_LAST_VERTEX_CONVENTION_EXT:
81        break;
82     default:
83        _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode);
84        return;
85     }
86  
87     FLUSH_VERTICES(ctx, _NEW_LIGHT);
88     ctx->Light.ProvokingVertex = mode;
89  }
90  
91  
92  /**
93   * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
94   * per-light state.
95   * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
96   * will have already been transformed by the modelview matrix!
97   * Also, all error checking should have already been done.
98   */
99  void
_mesa_light(struct gl_context * ctx,GLuint lnum,GLenum pname,const GLfloat * params)100  _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
101  {
102     struct gl_light *light;
103  
104     assert(lnum < MAX_LIGHTS);
105     light = &ctx->Light.Light[lnum];
106  
107     switch (pname) {
108     case GL_AMBIENT:
109        if (TEST_EQ_4V(light->Ambient, params))
110  	 return;
111        FLUSH_VERTICES(ctx, _NEW_LIGHT);
112        COPY_4V( light->Ambient, params );
113        break;
114     case GL_DIFFUSE:
115        if (TEST_EQ_4V(light->Diffuse, params))
116  	 return;
117        FLUSH_VERTICES(ctx, _NEW_LIGHT);
118        COPY_4V( light->Diffuse, params );
119        break;
120     case GL_SPECULAR:
121        if (TEST_EQ_4V(light->Specular, params))
122  	 return;
123        FLUSH_VERTICES(ctx, _NEW_LIGHT);
124        COPY_4V( light->Specular, params );
125        break;
126     case GL_POSITION:
127        /* NOTE: position has already been transformed by ModelView! */
128        if (TEST_EQ_4V(light->EyePosition, params))
129  	 return;
130        FLUSH_VERTICES(ctx, _NEW_LIGHT);
131        COPY_4V(light->EyePosition, params);
132        if (light->EyePosition[3] != 0.0F)
133  	 light->_Flags |= LIGHT_POSITIONAL;
134        else
135  	 light->_Flags &= ~LIGHT_POSITIONAL;
136        break;
137     case GL_SPOT_DIRECTION:
138        /* NOTE: Direction already transformed by inverse ModelView! */
139        if (TEST_EQ_3V(light->SpotDirection, params))
140  	 return;
141        FLUSH_VERTICES(ctx, _NEW_LIGHT);
142        COPY_3V(light->SpotDirection, params);
143        break;
144     case GL_SPOT_EXPONENT:
145        assert(params[0] >= 0.0F);
146        assert(params[0] <= ctx->Const.MaxSpotExponent);
147        if (light->SpotExponent == params[0])
148  	 return;
149        FLUSH_VERTICES(ctx, _NEW_LIGHT);
150        light->SpotExponent = params[0];
151        break;
152     case GL_SPOT_CUTOFF:
153        assert(params[0] == 180.0F || (params[0] >= 0.0F && params[0] <= 90.0F));
154        if (light->SpotCutoff == params[0])
155           return;
156        FLUSH_VERTICES(ctx, _NEW_LIGHT);
157        light->SpotCutoff = params[0];
158        light->_CosCutoff = (cosf(light->SpotCutoff * M_PI / 180.0));
159        if (light->_CosCutoff < 0)
160           light->_CosCutoff = 0;
161        if (light->SpotCutoff != 180.0F)
162           light->_Flags |= LIGHT_SPOT;
163        else
164           light->_Flags &= ~LIGHT_SPOT;
165        break;
166     case GL_CONSTANT_ATTENUATION:
167        assert(params[0] >= 0.0F);
168        if (light->ConstantAttenuation == params[0])
169  	 return;
170        FLUSH_VERTICES(ctx, _NEW_LIGHT);
171        light->ConstantAttenuation = params[0];
172        break;
173     case GL_LINEAR_ATTENUATION:
174        assert(params[0] >= 0.0F);
175        if (light->LinearAttenuation == params[0])
176  	 return;
177        FLUSH_VERTICES(ctx, _NEW_LIGHT);
178        light->LinearAttenuation = params[0];
179        break;
180     case GL_QUADRATIC_ATTENUATION:
181        assert(params[0] >= 0.0F);
182        if (light->QuadraticAttenuation == params[0])
183  	 return;
184        FLUSH_VERTICES(ctx, _NEW_LIGHT);
185        light->QuadraticAttenuation = params[0];
186        break;
187     default:
188        unreachable("Unexpected pname in _mesa_light()");
189     }
190  
191     if (ctx->Driver.Lightfv)
192        ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params );
193  }
194  
195  
196  void GLAPIENTRY
_mesa_Lightf(GLenum light,GLenum pname,GLfloat param)197  _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
198  {
199     GLfloat fparam[4];
200     fparam[0] = param;
201     fparam[1] = fparam[2] = fparam[3] = 0.0F;
202     _mesa_Lightfv( light, pname, fparam );
203  }
204  
205  
206  void GLAPIENTRY
_mesa_Lightfv(GLenum light,GLenum pname,const GLfloat * params)207  _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
208  {
209     GET_CURRENT_CONTEXT(ctx);
210     GLint i = (GLint) (light - GL_LIGHT0);
211     GLfloat temp[4];
212  
213     if (i < 0 || i >= (GLint) ctx->Const.MaxLights) {
214        _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light );
215        return;
216     }
217  
218     /* do particular error checks, transformations */
219     switch (pname) {
220     case GL_AMBIENT:
221     case GL_DIFFUSE:
222     case GL_SPECULAR:
223        /* nothing */
224        break;
225     case GL_POSITION:
226        /* transform position by ModelView matrix */
227        TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params);
228        params = temp;
229        break;
230     case GL_SPOT_DIRECTION:
231        /* transform direction by inverse modelview */
232        if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
233  	 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
234        }
235        TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m);
236        params = temp;
237        break;
238     case GL_SPOT_EXPONENT:
239        if (params[0] < 0.0F || params[0] > ctx->Const.MaxSpotExponent) {
240  	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
241  	 return;
242        }
243        break;
244     case GL_SPOT_CUTOFF:
245        if ((params[0] < 0.0F || params[0] > 90.0F) && params[0] != 180.0F) {
246  	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
247  	 return;
248        }
249        break;
250     case GL_CONSTANT_ATTENUATION:
251     case GL_LINEAR_ATTENUATION:
252     case GL_QUADRATIC_ATTENUATION:
253        if (params[0] < 0.0F) {
254  	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
255  	 return;
256        }
257        break;
258     default:
259        _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname);
260        return;
261     }
262  
263     _mesa_light(ctx, i, pname, params);
264  }
265  
266  
267  void GLAPIENTRY
_mesa_Lighti(GLenum light,GLenum pname,GLint param)268  _mesa_Lighti( GLenum light, GLenum pname, GLint param )
269  {
270     GLint iparam[4];
271     iparam[0] = param;
272     iparam[1] = iparam[2] = iparam[3] = 0;
273     _mesa_Lightiv( light, pname, iparam );
274  }
275  
276  
277  void GLAPIENTRY
_mesa_Lightiv(GLenum light,GLenum pname,const GLint * params)278  _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
279  {
280     GLfloat fparam[4];
281  
282     switch (pname) {
283        case GL_AMBIENT:
284        case GL_DIFFUSE:
285        case GL_SPECULAR:
286           fparam[0] = INT_TO_FLOAT( params[0] );
287           fparam[1] = INT_TO_FLOAT( params[1] );
288           fparam[2] = INT_TO_FLOAT( params[2] );
289           fparam[3] = INT_TO_FLOAT( params[3] );
290           break;
291        case GL_POSITION:
292           fparam[0] = (GLfloat) params[0];
293           fparam[1] = (GLfloat) params[1];
294           fparam[2] = (GLfloat) params[2];
295           fparam[3] = (GLfloat) params[3];
296           break;
297        case GL_SPOT_DIRECTION:
298           fparam[0] = (GLfloat) params[0];
299           fparam[1] = (GLfloat) params[1];
300           fparam[2] = (GLfloat) params[2];
301           break;
302        case GL_SPOT_EXPONENT:
303        case GL_SPOT_CUTOFF:
304        case GL_CONSTANT_ATTENUATION:
305        case GL_LINEAR_ATTENUATION:
306        case GL_QUADRATIC_ATTENUATION:
307           fparam[0] = (GLfloat) params[0];
308           break;
309        default:
310           /* error will be caught later in gl_Lightfv */
311           ;
312     }
313  
314     _mesa_Lightfv( light, pname, fparam );
315  }
316  
317  
318  
319  void GLAPIENTRY
_mesa_GetLightfv(GLenum light,GLenum pname,GLfloat * params)320  _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
321  {
322     GET_CURRENT_CONTEXT(ctx);
323     GLint l = (GLint) (light - GL_LIGHT0);
324  
325     if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
326        _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
327        return;
328     }
329  
330     switch (pname) {
331        case GL_AMBIENT:
332           COPY_4V( params, ctx->Light.Light[l].Ambient );
333           break;
334        case GL_DIFFUSE:
335           COPY_4V( params, ctx->Light.Light[l].Diffuse );
336           break;
337        case GL_SPECULAR:
338           COPY_4V( params, ctx->Light.Light[l].Specular );
339           break;
340        case GL_POSITION:
341           COPY_4V( params, ctx->Light.Light[l].EyePosition );
342           break;
343        case GL_SPOT_DIRECTION:
344           COPY_3V( params, ctx->Light.Light[l].SpotDirection );
345           break;
346        case GL_SPOT_EXPONENT:
347           params[0] = ctx->Light.Light[l].SpotExponent;
348           break;
349        case GL_SPOT_CUTOFF:
350           params[0] = ctx->Light.Light[l].SpotCutoff;
351           break;
352        case GL_CONSTANT_ATTENUATION:
353           params[0] = ctx->Light.Light[l].ConstantAttenuation;
354           break;
355        case GL_LINEAR_ATTENUATION:
356           params[0] = ctx->Light.Light[l].LinearAttenuation;
357           break;
358        case GL_QUADRATIC_ATTENUATION:
359           params[0] = ctx->Light.Light[l].QuadraticAttenuation;
360           break;
361        default:
362           _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
363           break;
364     }
365  }
366  
367  
368  void GLAPIENTRY
_mesa_GetLightiv(GLenum light,GLenum pname,GLint * params)369  _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
370  {
371     GET_CURRENT_CONTEXT(ctx);
372     GLint l = (GLint) (light - GL_LIGHT0);
373  
374     if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
375        _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
376        return;
377     }
378  
379     switch (pname) {
380        case GL_AMBIENT:
381           params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
382           params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
383           params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
384           params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
385           break;
386        case GL_DIFFUSE:
387           params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
388           params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
389           params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
390           params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
391           break;
392        case GL_SPECULAR:
393           params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
394           params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
395           params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
396           params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
397           break;
398        case GL_POSITION:
399           params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
400           params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
401           params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
402           params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
403           break;
404        case GL_SPOT_DIRECTION:
405           params[0] = (GLint) ctx->Light.Light[l].SpotDirection[0];
406           params[1] = (GLint) ctx->Light.Light[l].SpotDirection[1];
407           params[2] = (GLint) ctx->Light.Light[l].SpotDirection[2];
408           break;
409        case GL_SPOT_EXPONENT:
410           params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
411           break;
412        case GL_SPOT_CUTOFF:
413           params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
414           break;
415        case GL_CONSTANT_ATTENUATION:
416           params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
417           break;
418        case GL_LINEAR_ATTENUATION:
419           params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
420           break;
421        case GL_QUADRATIC_ATTENUATION:
422           params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
423           break;
424        default:
425           _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
426           break;
427     }
428  }
429  
430  
431  
432  /**********************************************************************/
433  /***                        Light Model                             ***/
434  /**********************************************************************/
435  
436  
437  void GLAPIENTRY
_mesa_LightModelfv(GLenum pname,const GLfloat * params)438  _mesa_LightModelfv( GLenum pname, const GLfloat *params )
439  {
440     GLenum newenum;
441     GLboolean newbool;
442     GET_CURRENT_CONTEXT(ctx);
443  
444     switch (pname) {
445        case GL_LIGHT_MODEL_AMBIENT:
446           if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
447  	    return;
448  	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
449           COPY_4V( ctx->Light.Model.Ambient, params );
450           break;
451        case GL_LIGHT_MODEL_LOCAL_VIEWER:
452           if (ctx->API != API_OPENGL_COMPAT)
453              goto invalid_pname;
454           newbool = (params[0] != 0.0F);
455  	 if (ctx->Light.Model.LocalViewer == newbool)
456  	    return;
457  	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
458  	 ctx->Light.Model.LocalViewer = newbool;
459           break;
460        case GL_LIGHT_MODEL_TWO_SIDE:
461           newbool = (params[0] != 0.0F);
462  	 if (ctx->Light.Model.TwoSide == newbool)
463  	    return;
464  	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
465  	 ctx->Light.Model.TwoSide = newbool;
466           break;
467        case GL_LIGHT_MODEL_COLOR_CONTROL:
468           if (ctx->API != API_OPENGL_COMPAT)
469              goto invalid_pname;
470           if (params[0] == (GLfloat) GL_SINGLE_COLOR)
471  	    newenum = GL_SINGLE_COLOR;
472           else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
473  	    newenum = GL_SEPARATE_SPECULAR_COLOR;
474  	 else {
475              _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)",
476                           (GLint) params[0] );
477  	    return;
478           }
479  	 if (ctx->Light.Model.ColorControl == newenum)
480  	    return;
481  	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
482  	 ctx->Light.Model.ColorControl = newenum;
483           break;
484        default:
485           goto invalid_pname;
486     }
487  
488     if (ctx->Driver.LightModelfv)
489        ctx->Driver.LightModelfv( ctx, pname, params );
490  
491     return;
492  
493  invalid_pname:
494     _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );
495     return;
496  }
497  
498  
499  void GLAPIENTRY
_mesa_LightModeliv(GLenum pname,const GLint * params)500  _mesa_LightModeliv( GLenum pname, const GLint *params )
501  {
502     GLfloat fparam[4];
503  
504     switch (pname) {
505        case GL_LIGHT_MODEL_AMBIENT:
506           fparam[0] = INT_TO_FLOAT( params[0] );
507           fparam[1] = INT_TO_FLOAT( params[1] );
508           fparam[2] = INT_TO_FLOAT( params[2] );
509           fparam[3] = INT_TO_FLOAT( params[3] );
510           break;
511        case GL_LIGHT_MODEL_LOCAL_VIEWER:
512        case GL_LIGHT_MODEL_TWO_SIDE:
513        case GL_LIGHT_MODEL_COLOR_CONTROL:
514           fparam[0] = (GLfloat) params[0];
515           break;
516        default:
517           /* Error will be caught later in gl_LightModelfv */
518           ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
519     }
520     _mesa_LightModelfv( pname, fparam );
521  }
522  
523  
524  void GLAPIENTRY
_mesa_LightModeli(GLenum pname,GLint param)525  _mesa_LightModeli( GLenum pname, GLint param )
526  {
527     GLint iparam[4];
528     iparam[0] = param;
529     iparam[1] = iparam[2] = iparam[3] = 0;
530     _mesa_LightModeliv( pname, iparam );
531  }
532  
533  
534  void GLAPIENTRY
_mesa_LightModelf(GLenum pname,GLfloat param)535  _mesa_LightModelf( GLenum pname, GLfloat param )
536  {
537     GLfloat fparam[4];
538     fparam[0] = param;
539     fparam[1] = fparam[2] = fparam[3] = 0.0F;
540     _mesa_LightModelfv( pname, fparam );
541  }
542  
543  
544  
545  /********** MATERIAL **********/
546  
547  
548  /*
549   * Given a face and pname value (ala glColorMaterial), compute a bitmask
550   * of the targeted material values.
551   */
552  GLuint
_mesa_material_bitmask(struct gl_context * ctx,GLenum face,GLenum pname,GLuint legal,const char * where)553  _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname,
554                          GLuint legal, const char *where )
555  {
556     GLuint bitmask = 0;
557  
558     /* Make a bitmask indicating what material attribute(s) we're updating */
559     switch (pname) {
560        case GL_EMISSION:
561           bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;
562           break;
563        case GL_AMBIENT:
564           bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
565           break;
566        case GL_DIFFUSE:
567           bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
568           break;
569        case GL_SPECULAR:
570           bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;
571           break;
572        case GL_SHININESS:
573           bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;
574           break;
575        case GL_AMBIENT_AND_DIFFUSE:
576           bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
577           bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
578           break;
579        case GL_COLOR_INDEXES:
580           bitmask |= MAT_BIT_FRONT_INDEXES  | MAT_BIT_BACK_INDEXES;
581           break;
582        default:
583           _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
584           return 0;
585     }
586  
587     if (face==GL_FRONT) {
588        bitmask &= FRONT_MATERIAL_BITS;
589     }
590     else if (face==GL_BACK) {
591        bitmask &= BACK_MATERIAL_BITS;
592     }
593     else if (face != GL_FRONT_AND_BACK) {
594        _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
595        return 0;
596     }
597  
598     if (bitmask & ~legal) {
599        _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
600        return 0;
601     }
602  
603     return bitmask;
604  }
605  
606  
607  
608  /* Update derived values following a change in ctx->Light.Material
609   */
610  void
_mesa_update_material(struct gl_context * ctx,GLuint bitmask)611  _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
612  {
613     GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
614  
615     if (MESA_VERBOSE & VERBOSE_MATERIAL)
616        _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);
617  
618     if (!bitmask)
619        return;
620  
621     /* update material ambience */
622     if (bitmask & MAT_BIT_FRONT_AMBIENT) {
623        GLbitfield mask = ctx->Light._EnabledLights;
624        while (mask) {
625           const int i = u_bit_scan(&mask);
626           struct gl_light *light = &ctx->Light.Light[i];
627           SCALE_3V( light->_MatAmbient[0], light->Ambient,
628  		   mat[MAT_ATTRIB_FRONT_AMBIENT]);
629        }
630     }
631  
632     if (bitmask & MAT_BIT_BACK_AMBIENT) {
633        GLbitfield mask = ctx->Light._EnabledLights;
634        while (mask) {
635           const int i = u_bit_scan(&mask);
636           struct gl_light *light = &ctx->Light.Light[i];
637           SCALE_3V( light->_MatAmbient[1], light->Ambient,
638  		   mat[MAT_ATTRIB_BACK_AMBIENT]);
639        }
640     }
641  
642     /* update BaseColor = emission + scene's ambience * material's ambience */
643     if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {
644        COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );
645        ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],
646  		    ctx->Light.Model.Ambient );
647     }
648  
649     if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {
650        COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );
651        ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],
652  		    ctx->Light.Model.Ambient );
653     }
654  
655     /* update material diffuse values */
656     if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
657        GLbitfield mask = ctx->Light._EnabledLights;
658        while (mask) {
659           const int i = u_bit_scan(&mask);
660           struct gl_light *light = &ctx->Light.Light[i];
661  	 SCALE_3V( light->_MatDiffuse[0], light->Diffuse,
662  		   mat[MAT_ATTRIB_FRONT_DIFFUSE] );
663        }
664     }
665  
666     if (bitmask & MAT_BIT_BACK_DIFFUSE) {
667        GLbitfield mask = ctx->Light._EnabledLights;
668        while (mask) {
669           const int i = u_bit_scan(&mask);
670           struct gl_light *light = &ctx->Light.Light[i];
671  	 SCALE_3V( light->_MatDiffuse[1], light->Diffuse,
672  		   mat[MAT_ATTRIB_BACK_DIFFUSE] );
673        }
674     }
675  
676     /* update material specular values */
677     if (bitmask & MAT_BIT_FRONT_SPECULAR) {
678        GLbitfield mask = ctx->Light._EnabledLights;
679        while (mask) {
680           const int i = u_bit_scan(&mask);
681           struct gl_light *light = &ctx->Light.Light[i];
682  	 SCALE_3V( light->_MatSpecular[0], light->Specular,
683  		   mat[MAT_ATTRIB_FRONT_SPECULAR]);
684        }
685     }
686  
687     if (bitmask & MAT_BIT_BACK_SPECULAR) {
688        GLbitfield mask = ctx->Light._EnabledLights;
689        while (mask) {
690           const int i = u_bit_scan(&mask);
691           struct gl_light *light = &ctx->Light.Light[i];
692  	 SCALE_3V( light->_MatSpecular[1], light->Specular,
693  		   mat[MAT_ATTRIB_BACK_SPECULAR]);
694        }
695     }
696  }
697  
698  
699  /*
700   * Update the current materials from the given rgba color
701   * according to the bitmask in _ColorMaterialBitmask, which is
702   * set by glColorMaterial().
703   */
704  void
_mesa_update_color_material(struct gl_context * ctx,const GLfloat color[4])705  _mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] )
706  {
707     GLbitfield bitmask = ctx->Light._ColorMaterialBitmask;
708     struct gl_material *mat = &ctx->Light.Material;
709  
710     while (bitmask) {
711        const int i = u_bit_scan(&bitmask);
712  
713        COPY_4FV( mat->Attrib[i], color );
714     }
715  
716     _mesa_update_material( ctx, bitmask );
717  }
718  
719  
720  void GLAPIENTRY
_mesa_ColorMaterial(GLenum face,GLenum mode)721  _mesa_ColorMaterial( GLenum face, GLenum mode )
722  {
723     GET_CURRENT_CONTEXT(ctx);
724     GLuint bitmask;
725     GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |
726  		   MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |
727  		   MAT_BIT_FRONT_DIFFUSE  | MAT_BIT_BACK_DIFFUSE  |
728  		   MAT_BIT_FRONT_AMBIENT  | MAT_BIT_BACK_AMBIENT);
729  
730     if (MESA_VERBOSE&VERBOSE_API)
731        _mesa_debug(ctx, "glColorMaterial %s %s\n",
732                    _mesa_enum_to_string(face),
733                    _mesa_enum_to_string(mode));
734  
735     bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
736     if (bitmask == 0)
737        return; /* error was recorded */
738  
739     if (ctx->Light._ColorMaterialBitmask == bitmask &&
740         ctx->Light.ColorMaterialFace == face &&
741         ctx->Light.ColorMaterialMode == mode)
742        return;
743  
744     FLUSH_VERTICES(ctx, _NEW_LIGHT);
745     ctx->Light._ColorMaterialBitmask = bitmask;
746     ctx->Light.ColorMaterialFace = face;
747     ctx->Light.ColorMaterialMode = mode;
748  
749     if (ctx->Light.ColorMaterialEnabled) {
750        FLUSH_CURRENT( ctx, 0 );
751        _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
752     }
753  
754     if (ctx->Driver.ColorMaterial)
755        ctx->Driver.ColorMaterial( ctx, face, mode );
756  }
757  
758  
759  void GLAPIENTRY
_mesa_GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)760  _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
761  {
762     GET_CURRENT_CONTEXT(ctx);
763     GLuint f;
764     GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
765     FLUSH_VERTICES(ctx, 0); /* update materials */
766  
767     FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
768  
769     if (face==GL_FRONT) {
770        f = 0;
771     }
772     else if (face==GL_BACK) {
773        f = 1;
774     }
775     else {
776        _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
777        return;
778     }
779  
780     switch (pname) {
781        case GL_AMBIENT:
782           COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );
783           break;
784        case GL_DIFFUSE:
785           COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );
786  	 break;
787        case GL_SPECULAR:
788           COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );
789  	 break;
790        case GL_EMISSION:
791  	 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );
792  	 break;
793        case GL_SHININESS:
794  	 *params = mat[MAT_ATTRIB_SHININESS(f)][0];
795  	 break;
796        case GL_COLOR_INDEXES:
797           if (ctx->API != API_OPENGL_COMPAT) {
798              _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
799              return;
800           }
801  	 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];
802  	 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];
803  	 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];
804  	 break;
805        default:
806           _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
807     }
808  }
809  
810  
811  void GLAPIENTRY
_mesa_GetMaterialiv(GLenum face,GLenum pname,GLint * params)812  _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
813  {
814     GET_CURRENT_CONTEXT(ctx);
815     GLuint f;
816     GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
817  
818     assert(ctx->API == API_OPENGL_COMPAT);
819  
820     FLUSH_VERTICES(ctx, 0); /* update materials */
821     FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
822  
823     if (face==GL_FRONT) {
824        f = 0;
825     }
826     else if (face==GL_BACK) {
827        f = 1;
828     }
829     else {
830        _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
831        return;
832     }
833     switch (pname) {
834        case GL_AMBIENT:
835           params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );
836           params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );
837           params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );
838           params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );
839           break;
840        case GL_DIFFUSE:
841           params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );
842           params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );
843           params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );
844           params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );
845  	 break;
846        case GL_SPECULAR:
847           params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );
848           params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );
849           params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );
850           params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );
851  	 break;
852        case GL_EMISSION:
853           params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );
854           params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );
855           params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );
856           params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );
857  	 break;
858        case GL_SHININESS:
859           *params = lroundf( mat[MAT_ATTRIB_SHININESS(f)][0] );
860  	 break;
861        case GL_COLOR_INDEXES:
862  	 params[0] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][0] );
863  	 params[1] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][1] );
864  	 params[2] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][2] );
865  	 break;
866        default:
867           _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
868     }
869  }
870  
871  
872  
873  /**
874   * Examine current lighting parameters to determine if the optimized lighting
875   * function can be used.
876   * Also, precompute some lighting values such as the products of light
877   * source and material ambient, diffuse and specular coefficients.
878   */
879  void
_mesa_update_lighting(struct gl_context * ctx)880  _mesa_update_lighting( struct gl_context *ctx )
881  {
882     GLbitfield flags = 0;
883     ctx->Light._NeedEyeCoords = GL_FALSE;
884  
885     if (!ctx->Light.Enabled)
886        return;
887  
888     GLbitfield mask = ctx->Light._EnabledLights;
889     while (mask) {
890        const int i = u_bit_scan(&mask);
891        struct gl_light *light = &ctx->Light.Light[i];
892        flags |= light->_Flags;
893     }
894  
895     ctx->Light._NeedVertices =
896        ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
897         ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
898         ctx->Light.Model.LocalViewer);
899  
900     ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) ||
901  				ctx->Light.Model.LocalViewer);
902  
903     /* XXX: This test is overkill & needs to be fixed both for software and
904      * hardware t&l drivers.  The above should be sufficient & should
905      * be tested to verify this.
906      */
907     if (ctx->Light._NeedVertices)
908        ctx->Light._NeedEyeCoords = GL_TRUE;
909  
910     /* Precompute some shading values.  Although we reference
911      * Light.Material here, we can get away without flushing
912      * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
913      * are flushed, they will update the derived state at that time.
914      */
915     if (ctx->Light.Model.TwoSide)
916        _mesa_update_material(ctx,
917  			    MAT_BIT_FRONT_EMISSION |
918  			    MAT_BIT_FRONT_AMBIENT |
919  			    MAT_BIT_FRONT_DIFFUSE |
920  			    MAT_BIT_FRONT_SPECULAR |
921  			    MAT_BIT_BACK_EMISSION |
922  			    MAT_BIT_BACK_AMBIENT |
923  			    MAT_BIT_BACK_DIFFUSE |
924  			    MAT_BIT_BACK_SPECULAR);
925     else
926        _mesa_update_material(ctx,
927  			    MAT_BIT_FRONT_EMISSION |
928  			    MAT_BIT_FRONT_AMBIENT |
929  			    MAT_BIT_FRONT_DIFFUSE |
930  			    MAT_BIT_FRONT_SPECULAR);
931  }
932  
933  
934  /**
935   * Update state derived from light position, spot direction.
936   * Called upon:
937   *   _NEW_MODELVIEW
938   *   _NEW_LIGHT
939   *   _TNL_NEW_NEED_EYE_COORDS
940   *
941   * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
942   * Also update on lighting space changes.
943   */
944  static void
compute_light_positions(struct gl_context * ctx)945  compute_light_positions( struct gl_context *ctx )
946  {
947     static const GLfloat eye_z[3] = { 0, 0, 1 };
948  
949     if (!ctx->Light.Enabled)
950        return;
951  
952     if (ctx->_NeedEyeCoords) {
953        COPY_3V( ctx->_EyeZDir, eye_z );
954     }
955     else {
956        TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
957     }
958  
959     GLbitfield mask = ctx->Light._EnabledLights;
960     while (mask) {
961        const int i = u_bit_scan(&mask);
962        struct gl_light *light = &ctx->Light.Light[i];
963  
964        if (ctx->_NeedEyeCoords) {
965           /* _Position is in eye coordinate space */
966  	 COPY_4FV( light->_Position, light->EyePosition );
967        }
968        else {
969           /* _Position is in object coordinate space */
970  	 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
971  			  light->EyePosition );
972        }
973  
974        if (!(light->_Flags & LIGHT_POSITIONAL)) {
975  	 /* VP (VP) = Normalize( Position ) */
976  	 COPY_3V( light->_VP_inf_norm, light->_Position );
977  	 NORMALIZE_3FV( light->_VP_inf_norm );
978  
979  	 if (!ctx->Light.Model.LocalViewer) {
980  	    /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
981  	    ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
982  	    NORMALIZE_3FV( light->_h_inf_norm );
983  	 }
984  	 light->_VP_inf_spot_attenuation = 1.0;
985        }
986        else {
987           /* positional light w/ homogeneous coordinate, divide by W */
988           GLfloat wInv = 1.0F / light->_Position[3];
989           light->_Position[0] *= wInv;
990           light->_Position[1] *= wInv;
991           light->_Position[2] *= wInv;
992        }
993  
994        if (light->_Flags & LIGHT_SPOT) {
995           /* Note: we normalize the spot direction now */
996  
997  	 if (ctx->_NeedEyeCoords) {
998  	    COPY_3V( light->_NormSpotDirection, light->SpotDirection );
999              NORMALIZE_3FV( light->_NormSpotDirection );
1000  	 }
1001           else {
1002              GLfloat spotDir[3];
1003              COPY_3V(spotDir, light->SpotDirection);
1004              NORMALIZE_3FV(spotDir);
1005  	    TRANSFORM_NORMAL( light->_NormSpotDirection,
1006  			      spotDir,
1007  			      ctx->ModelviewMatrixStack.Top->m);
1008  	 }
1009  
1010  	 NORMALIZE_3FV( light->_NormSpotDirection );
1011  
1012  	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1013  	    GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
1014  					light->_NormSpotDirection);
1015  
1016  	    if (PV_dot_dir > light->_CosCutoff) {
1017  	       light->_VP_inf_spot_attenuation =
1018                    powf(PV_dot_dir, light->SpotExponent);
1019  	    }
1020  	    else {
1021  	       light->_VP_inf_spot_attenuation = 0;
1022              }
1023  	 }
1024        }
1025     }
1026  }
1027  
1028  
1029  
1030  static void
update_modelview_scale(struct gl_context * ctx)1031  update_modelview_scale( struct gl_context *ctx )
1032  {
1033     ctx->_ModelViewInvScale = 1.0F;
1034     ctx->_ModelViewInvScaleEyespace = 1.0F;
1035     if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
1036        const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
1037        GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
1038        if (f < 1e-12f) f = 1.0f;
1039        if (ctx->_NeedEyeCoords)
1040  	 ctx->_ModelViewInvScale = 1.0f / sqrtf(f);
1041        else
1042  	 ctx->_ModelViewInvScale = sqrtf(f);
1043        ctx->_ModelViewInvScaleEyespace = 1.0f / sqrtf(f);
1044     }
1045  }
1046  
1047  
1048  /**
1049   * Bring up to date any state that relies on _NeedEyeCoords.
1050   */
1051  void
_mesa_update_tnl_spaces(struct gl_context * ctx,GLuint new_state)1052  _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state )
1053  {
1054     const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
1055  
1056     (void) new_state;
1057     ctx->_NeedEyeCoords = GL_FALSE;
1058  
1059     if (ctx->_ForceEyeCoords ||
1060         (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) ||
1061         ctx->Point._Attenuated ||
1062         ctx->Light._NeedEyeCoords)
1063        ctx->_NeedEyeCoords = GL_TRUE;
1064  
1065     if (ctx->Light.Enabled &&
1066         !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top))
1067        ctx->_NeedEyeCoords = GL_TRUE;
1068  
1069     /* Check if the truth-value interpretations of the bitfields have
1070      * changed:
1071      */
1072     if (oldneedeyecoords != ctx->_NeedEyeCoords) {
1073        /* Recalculate all state that depends on _NeedEyeCoords.
1074         */
1075        update_modelview_scale(ctx);
1076        compute_light_positions( ctx );
1077  
1078        if (ctx->Driver.LightingSpaceChange)
1079  	 ctx->Driver.LightingSpaceChange( ctx );
1080     }
1081     else {
1082        GLuint new_state2 = ctx->NewState;
1083  
1084        /* Recalculate that same state only if it has been invalidated
1085         * by other statechanges.
1086         */
1087        if (new_state2 & _NEW_MODELVIEW)
1088  	 update_modelview_scale(ctx);
1089  
1090        if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
1091  	 compute_light_positions( ctx );
1092     }
1093  }
1094  
1095  
1096  /**
1097   * Drivers may need this if the hardware tnl unit doesn't support the
1098   * light-in-modelspace optimization.  It's also useful for debugging.
1099   */
1100  void
_mesa_allow_light_in_model(struct gl_context * ctx,GLboolean flag)1101  _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag )
1102  {
1103     ctx->_ForceEyeCoords = !flag;
1104     ctx->NewState |= _NEW_POINT;	/* one of the bits from
1105  				 * _MESA_NEW_NEED_EYE_COORDS.
1106  				 */
1107  }
1108  
1109  
1110  
1111  /**********************************************************************/
1112  /*****                      Initialization                        *****/
1113  /**********************************************************************/
1114  
1115  /**
1116   * Initialize the n-th light data structure.
1117   *
1118   * \param l pointer to the gl_light structure to be initialized.
1119   * \param n number of the light.
1120   * \note The defaults for light 0 are different than the other lights.
1121   */
1122  static void
init_light(struct gl_light * l,GLuint n)1123  init_light( struct gl_light *l, GLuint n )
1124  {
1125     ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
1126     if (n==0) {
1127        ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
1128        ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
1129     }
1130     else {
1131        ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
1132        ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
1133     }
1134     ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
1135     ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 );
1136     l->SpotExponent = 0.0;
1137     l->SpotCutoff = 180.0;
1138     l->_CosCutoff = 0.0;		/* KW: -ve values not admitted */
1139     l->ConstantAttenuation = 1.0;
1140     l->LinearAttenuation = 0.0;
1141     l->QuadraticAttenuation = 0.0;
1142     l->Enabled = GL_FALSE;
1143  }
1144  
1145  
1146  /**
1147   * Initialize the light model data structure.
1148   *
1149   * \param lm pointer to the gl_lightmodel structure to be initialized.
1150   */
1151  static void
init_lightmodel(struct gl_lightmodel * lm)1152  init_lightmodel( struct gl_lightmodel *lm )
1153  {
1154     ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F );
1155     lm->LocalViewer = GL_FALSE;
1156     lm->TwoSide = GL_FALSE;
1157     lm->ColorControl = GL_SINGLE_COLOR;
1158  }
1159  
1160  
1161  /**
1162   * Initialize the material data structure.
1163   *
1164   * \param m pointer to the gl_material structure to be initialized.
1165   */
1166  static void
init_material(struct gl_material * m)1167  init_material( struct gl_material *m )
1168  {
1169     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1170     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1171     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1172     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1173     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1174     ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1175  
1176     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1177     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1178     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1179     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1180     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1181     ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1182  }
1183  
1184  
1185  /**
1186   * Initialize all lighting state for the given context.
1187   */
1188  void
_mesa_init_lighting(struct gl_context * ctx)1189  _mesa_init_lighting( struct gl_context *ctx )
1190  {
1191     GLuint i;
1192  
1193     /* Lighting group */
1194     ctx->Light._EnabledLights = 0;
1195     for (i = 0; i < MAX_LIGHTS; i++) {
1196        init_light( &ctx->Light.Light[i], i );
1197     }
1198  
1199     init_lightmodel( &ctx->Light.Model );
1200     init_material( &ctx->Light.Material );
1201     ctx->Light.ShadeModel = GL_SMOOTH;
1202     ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1203     ctx->Light.Enabled = GL_FALSE;
1204     ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
1205     ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
1206     ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx,
1207                                                 GL_FRONT_AND_BACK,
1208                                                 GL_AMBIENT_AND_DIFFUSE, ~0,
1209                                                 NULL );
1210  
1211     ctx->Light.ColorMaterialEnabled = GL_FALSE;
1212     ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
1213     ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
1214  
1215     /* Miscellaneous */
1216     ctx->Light._NeedEyeCoords = GL_FALSE;
1217     ctx->_NeedEyeCoords = GL_FALSE;
1218     ctx->_ForceEyeCoords = GL_FALSE;
1219     ctx->_ModelViewInvScale = 1.0;
1220     ctx->_ModelViewInvScaleEyespace = 1.0;
1221  }
1222