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