2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
29 _mesa_ShadeModel( GLenum mode
)
31 GET_CURRENT_CONTEXT(ctx
);
32 ASSERT_OUTSIDE_BEGIN_END(ctx
);
34 if (MESA_VERBOSE
& VERBOSE_API
)
35 _mesa_debug(ctx
, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode
));
37 if (mode
!= GL_FLAT
&& mode
!= GL_SMOOTH
) {
38 _mesa_error(ctx
, GL_INVALID_ENUM
, "glShadeModel");
42 if (ctx
->Light
.ShadeModel
== mode
)
45 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
46 ctx
->Light
.ShadeModel
= mode
;
48 ctx
->_TriangleCaps
|= DD_FLATSHADE
;
50 ctx
->_TriangleCaps
&= ~DD_FLATSHADE
;
52 if (ctx
->Driver
.ShadeModel
)
53 ctx
->Driver
.ShadeModel( ctx
, mode
);
57 * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
59 * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
60 * will have already been transformed by the modelview matrix!
61 * Also, all error checking should have already been done.
64 _mesa_light(struct gl_context
*ctx
, GLuint lnum
, GLenum pname
, const GLfloat
*params
)
66 struct gl_light
*light
;
68 ASSERT(lnum
< MAX_LIGHTS
);
69 light
= &ctx
->Light
.Light
[lnum
];
73 if (TEST_EQ_4V(light
->Ambient
, params
))
75 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
76 COPY_4V( light
->Ambient
, params
);
79 if (TEST_EQ_4V(light
->Diffuse
, params
))
81 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
82 COPY_4V( light
->Diffuse
, params
);
85 if (TEST_EQ_4V(light
->Specular
, params
))
87 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
88 COPY_4V( light
->Specular
, params
);
91 /* NOTE: position has already been transformed by ModelView! */
92 if (TEST_EQ_4V(light
->EyePosition
, params
))
94 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
95 COPY_4V(light
->EyePosition
, params
);
96 if (light
->EyePosition
[3] != 0.0F
)
97 light
->_Flags
|= LIGHT_POSITIONAL
;
99 light
->_Flags
&= ~LIGHT_POSITIONAL
;
101 case GL_SPOT_DIRECTION
:
102 /* NOTE: Direction already transformed by inverse ModelView! */
103 if (TEST_EQ_3V(light
->SpotDirection
, params
))
105 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
106 COPY_3V(light
->SpotDirection
, params
);
108 case GL_SPOT_EXPONENT
:
109 ASSERT(params
[0] >= 0.0);
110 ASSERT(params
[0] <= ctx
->Const
.MaxSpotExponent
);
111 if (light
->SpotExponent
== params
[0])
113 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
114 light
->SpotExponent
= params
[0];
115 _mesa_invalidate_spot_exp_table(light
);
118 ASSERT(params
[0] == 180.0 || (params
[0] >= 0.0 && params
[0] <= 90.0));
119 if (light
->SpotCutoff
== params
[0])
121 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
122 light
->SpotCutoff
= params
[0];
123 light
->_CosCutoffNeg
= (GLfloat
) (cos(light
->SpotCutoff
* DEG2RAD
));
124 if (light
->_CosCutoffNeg
< 0)
125 light
->_CosCutoff
= 0;
127 light
->_CosCutoff
= light
->_CosCutoffNeg
;
128 if (light
->SpotCutoff
!= 180.0F
)
129 light
->_Flags
|= LIGHT_SPOT
;
131 light
->_Flags
&= ~LIGHT_SPOT
;
133 case GL_CONSTANT_ATTENUATION
:
134 ASSERT(params
[0] >= 0.0);
135 if (light
->ConstantAttenuation
== params
[0])
137 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
138 light
->ConstantAttenuation
= params
[0];
140 case GL_LINEAR_ATTENUATION
:
141 ASSERT(params
[0] >= 0.0);
142 if (light
->LinearAttenuation
== params
[0])
144 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
145 light
->LinearAttenuation
= params
[0];
147 case GL_QUADRATIC_ATTENUATION
:
148 ASSERT(params
[0] >= 0.0);
149 if (light
->QuadraticAttenuation
== params
[0])
151 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
152 light
->QuadraticAttenuation
= params
[0];
155 _mesa_problem(ctx
, "Unexpected pname in _mesa_light()");
159 if (ctx
->Driver
.Lightfv
)
160 ctx
->Driver
.Lightfv( ctx
, GL_LIGHT0
+ lnum
, pname
, params
);
165 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
169 fparam
[1] = fparam
[2] = fparam
[3] = 0.0F
;
170 _mesa_Lightfv( light
, pname
, fparam
);
175 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
177 GET_CURRENT_CONTEXT(ctx
);
178 GLint i
= (GLint
) (light
- GL_LIGHT0
);
180 ASSERT_OUTSIDE_BEGIN_END(ctx
);
182 if (i
< 0 || i
>= (GLint
) ctx
->Const
.MaxLights
) {
183 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLight(light=0x%x)", light
);
187 /* do particular error checks, transformations */
195 /* transform position by ModelView matrix */
196 TRANSFORM_POINT(temp
, ctx
->ModelviewMatrixStack
.Top
->m
, params
);
199 case GL_SPOT_DIRECTION
:
200 /* transform direction by inverse modelview */
201 if (_math_matrix_is_dirty(ctx
->ModelviewMatrixStack
.Top
)) {
202 _math_matrix_analyse(ctx
->ModelviewMatrixStack
.Top
);
204 TRANSFORM_DIRECTION(temp
, params
, ctx
->ModelviewMatrixStack
.Top
->m
);
207 case GL_SPOT_EXPONENT
:
208 if (params
[0] < 0.0 || params
[0] > ctx
->Const
.MaxSpotExponent
) {
209 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
214 if ((params
[0] < 0.0 || params
[0] > 90.0) && params
[0] != 180.0) {
215 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
219 case GL_CONSTANT_ATTENUATION
:
220 if (params
[0] < 0.0) {
221 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
225 case GL_LINEAR_ATTENUATION
:
226 if (params
[0] < 0.0) {
227 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
231 case GL_QUADRATIC_ATTENUATION
:
232 if (params
[0] < 0.0) {
233 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
238 _mesa_error(ctx
, GL_INVALID_ENUM
, "glLight(pname=0x%x)", pname
);
242 _mesa_light(ctx
, i
, pname
, params
);
247 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
251 iparam
[1] = iparam
[2] = iparam
[3] = 0;
252 _mesa_Lightiv( light
, pname
, iparam
);
257 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
265 fparam
[0] = INT_TO_FLOAT( params
[0] );
266 fparam
[1] = INT_TO_FLOAT( params
[1] );
267 fparam
[2] = INT_TO_FLOAT( params
[2] );
268 fparam
[3] = INT_TO_FLOAT( params
[3] );
271 fparam
[0] = (GLfloat
) params
[0];
272 fparam
[1] = (GLfloat
) params
[1];
273 fparam
[2] = (GLfloat
) params
[2];
274 fparam
[3] = (GLfloat
) params
[3];
276 case GL_SPOT_DIRECTION
:
277 fparam
[0] = (GLfloat
) params
[0];
278 fparam
[1] = (GLfloat
) params
[1];
279 fparam
[2] = (GLfloat
) params
[2];
281 case GL_SPOT_EXPONENT
:
283 case GL_CONSTANT_ATTENUATION
:
284 case GL_LINEAR_ATTENUATION
:
285 case GL_QUADRATIC_ATTENUATION
:
286 fparam
[0] = (GLfloat
) params
[0];
289 /* error will be caught later in gl_Lightfv */
293 _mesa_Lightfv( light
, pname
, fparam
);
299 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
301 GET_CURRENT_CONTEXT(ctx
);
302 GLint l
= (GLint
) (light
- GL_LIGHT0
);
303 ASSERT_OUTSIDE_BEGIN_END(ctx
);
305 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
306 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
312 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
315 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
318 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
321 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
323 case GL_SPOT_DIRECTION
:
324 COPY_3V( params
, ctx
->Light
.Light
[l
].SpotDirection
);
326 case GL_SPOT_EXPONENT
:
327 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
330 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
332 case GL_CONSTANT_ATTENUATION
:
333 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
335 case GL_LINEAR_ATTENUATION
:
336 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
338 case GL_QUADRATIC_ATTENUATION
:
339 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
342 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
349 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
351 GET_CURRENT_CONTEXT(ctx
);
352 GLint l
= (GLint
) (light
- GL_LIGHT0
);
353 ASSERT_OUTSIDE_BEGIN_END(ctx
);
355 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
356 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
362 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
363 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
364 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
365 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
368 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
369 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
370 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
371 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
374 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
375 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
376 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
377 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
380 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
381 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
382 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
383 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
385 case GL_SPOT_DIRECTION
:
386 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[0];
387 params
[1] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[1];
388 params
[2] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[2];
390 case GL_SPOT_EXPONENT
:
391 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
394 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
396 case GL_CONSTANT_ATTENUATION
:
397 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
399 case GL_LINEAR_ATTENUATION
:
400 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
402 case GL_QUADRATIC_ATTENUATION
:
403 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
406 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
413 /**********************************************************************/
414 /*** Light Model ***/
415 /**********************************************************************/
419 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
422 GET_CURRENT_CONTEXT(ctx
);
423 ASSERT_OUTSIDE_BEGIN_END(ctx
);
426 case GL_LIGHT_MODEL_AMBIENT
:
427 if (TEST_EQ_4V( ctx
->Light
.Model
.Ambient
, params
))
429 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
430 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
432 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
433 newbool
= (params
[0]!=0.0);
434 if (ctx
->Light
.Model
.LocalViewer
== newbool
)
436 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
437 ctx
->Light
.Model
.LocalViewer
= newbool
;
439 case GL_LIGHT_MODEL_TWO_SIDE
:
440 newbool
= (params
[0]!=0.0);
441 if (ctx
->Light
.Model
.TwoSide
== newbool
)
443 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
444 ctx
->Light
.Model
.TwoSide
= newbool
;
445 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
)
446 ctx
->_TriangleCaps
|= DD_TRI_LIGHT_TWOSIDE
;
448 ctx
->_TriangleCaps
&= ~DD_TRI_LIGHT_TWOSIDE
;
451 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLightModel(pname=0x%x)", pname
);
455 if (ctx
->Driver
.LightModelfv
)
456 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
461 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
466 case GL_LIGHT_MODEL_AMBIENT
:
467 fparam
[0] = INT_TO_FLOAT( params
[0] );
468 fparam
[1] = INT_TO_FLOAT( params
[1] );
469 fparam
[2] = INT_TO_FLOAT( params
[2] );
470 fparam
[3] = INT_TO_FLOAT( params
[3] );
472 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
473 case GL_LIGHT_MODEL_TWO_SIDE
:
474 case GL_LIGHT_MODEL_COLOR_CONTROL
:
475 fparam
[0] = (GLfloat
) params
[0];
478 /* Error will be caught later in gl_LightModelfv */
479 ASSIGN_4V(fparam
, 0.0F
, 0.0F
, 0.0F
, 0.0F
);
481 _mesa_LightModelfv( pname
, fparam
);
486 _mesa_LightModeli( GLenum pname
, GLint param
)
490 iparam
[1] = iparam
[2] = iparam
[3] = 0;
491 _mesa_LightModeliv( pname
, iparam
);
496 _mesa_LightModelf( GLenum pname
, GLfloat param
)
500 fparam
[1] = fparam
[2] = fparam
[3] = 0.0F
;
501 _mesa_LightModelfv( pname
, fparam
);
506 /********** MATERIAL **********/
510 * Given a face and pname value (ala glColorMaterial), compute a bitmask
511 * of the targeted material values.
514 _mesa_material_bitmask( struct gl_context
*ctx
, GLenum face
, GLenum pname
,
515 GLuint legal
, const char *where
)
519 /* Make a bitmask indicating what material attribute(s) we're updating */
522 bitmask
|= MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
;
525 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
528 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
531 bitmask
|= MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
;
534 bitmask
|= MAT_BIT_FRONT_SHININESS
| MAT_BIT_BACK_SHININESS
;
536 case GL_AMBIENT_AND_DIFFUSE
:
537 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
538 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
540 case GL_COLOR_INDEXES
:
541 bitmask
|= MAT_BIT_FRONT_INDEXES
| MAT_BIT_BACK_INDEXES
;
544 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
548 if (face
==GL_FRONT
) {
549 bitmask
&= FRONT_MATERIAL_BITS
;
551 else if (face
==GL_BACK
) {
552 bitmask
&= BACK_MATERIAL_BITS
;
554 else if (face
!= GL_FRONT_AND_BACK
) {
555 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
559 if (bitmask
& ~legal
) {
560 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
569 /* Update derived values following a change in ctx->Light.Material
572 _mesa_update_material( struct gl_context
*ctx
, GLuint bitmask
)
574 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
575 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
577 if (MESA_VERBOSE
& VERBOSE_MATERIAL
)
578 _mesa_debug(ctx
, "_mesa_update_material, mask 0x%x\n", bitmask
);
583 /* update material ambience */
584 if (bitmask
& MAT_BIT_FRONT_AMBIENT
) {
585 foreach (light
, list
) {
586 SCALE_3V( light
->_MatAmbient
[0], light
->Ambient
,
587 mat
[MAT_ATTRIB_FRONT_AMBIENT
]);
591 if (bitmask
& MAT_BIT_BACK_AMBIENT
) {
592 foreach (light
, list
) {
593 SCALE_3V( light
->_MatAmbient
[1], light
->Ambient
,
594 mat
[MAT_ATTRIB_BACK_AMBIENT
]);
598 /* update BaseColor = emission + scene's ambience * material's ambience */
599 if (bitmask
& (MAT_BIT_FRONT_EMISSION
| MAT_BIT_FRONT_AMBIENT
)) {
600 COPY_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_EMISSION
] );
601 ACC_SCALE_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_AMBIENT
],
602 ctx
->Light
.Model
.Ambient
);
605 if (bitmask
& (MAT_BIT_BACK_EMISSION
| MAT_BIT_BACK_AMBIENT
)) {
606 COPY_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_EMISSION
] );
607 ACC_SCALE_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_AMBIENT
],
608 ctx
->Light
.Model
.Ambient
);
611 /* update material diffuse values */
612 if (bitmask
& MAT_BIT_FRONT_DIFFUSE
) {
613 foreach (light
, list
) {
614 SCALE_3V( light
->_MatDiffuse
[0], light
->Diffuse
,
615 mat
[MAT_ATTRIB_FRONT_DIFFUSE
] );
619 if (bitmask
& MAT_BIT_BACK_DIFFUSE
) {
620 foreach (light
, list
) {
621 SCALE_3V( light
->_MatDiffuse
[1], light
->Diffuse
,
622 mat
[MAT_ATTRIB_BACK_DIFFUSE
] );
626 /* update material specular values */
627 if (bitmask
& MAT_BIT_FRONT_SPECULAR
) {
628 foreach (light
, list
) {
629 SCALE_3V( light
->_MatSpecular
[0], light
->Specular
,
630 mat
[MAT_ATTRIB_FRONT_SPECULAR
]);
634 if (bitmask
& MAT_BIT_BACK_SPECULAR
) {
635 foreach (light
, list
) {
636 SCALE_3V( light
->_MatSpecular
[1], light
->Specular
,
637 mat
[MAT_ATTRIB_BACK_SPECULAR
]);
641 if (bitmask
& MAT_BIT_FRONT_SHININESS
) {
642 _mesa_invalidate_shine_table( ctx
, 0 );
645 if (bitmask
& MAT_BIT_BACK_SHININESS
) {
646 _mesa_invalidate_shine_table( ctx
, 1 );
652 * Update the current materials from the given rgba color
653 * according to the bitmask in ColorMaterialBitmask, which is
654 * set by glColorMaterial().
657 _mesa_update_color_material( struct gl_context
*ctx
, const GLfloat color
[4] )
659 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
660 struct gl_material
*mat
= &ctx
->Light
.Material
;
663 for (i
= 0 ; i
< MAT_ATTRIB_MAX
; i
++)
664 if (bitmask
& (1<<i
))
665 COPY_4FV( mat
->Attrib
[i
], color
);
667 _mesa_update_material( ctx
, bitmask
);
672 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
674 GET_CURRENT_CONTEXT(ctx
);
676 GLuint legal
= (MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
|
677 MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
|
678 MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
|
679 MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
);
680 ASSERT_OUTSIDE_BEGIN_END(ctx
);
682 if (MESA_VERBOSE
&VERBOSE_API
)
683 _mesa_debug(ctx
, "glColorMaterial %s %s\n",
684 _mesa_lookup_enum_by_nr(face
),
685 _mesa_lookup_enum_by_nr(mode
));
687 bitmask
= _mesa_material_bitmask(ctx
, face
, mode
, legal
, "glColorMaterial");
689 return; /* error was recorded */
691 if (ctx
->Light
.ColorMaterialBitmask
== bitmask
&&
692 ctx
->Light
.ColorMaterialFace
== face
&&
693 ctx
->Light
.ColorMaterialMode
== mode
)
696 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
697 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
698 ctx
->Light
.ColorMaterialFace
= face
;
699 ctx
->Light
.ColorMaterialMode
= mode
;
701 if (ctx
->Light
.ColorMaterialEnabled
) {
702 FLUSH_CURRENT( ctx
, 0 );
703 _mesa_update_color_material(ctx
,ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR
]);
706 if (ctx
->Driver
.ColorMaterial
)
707 ctx
->Driver
.ColorMaterial( ctx
, face
, mode
);
712 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
714 GET_CURRENT_CONTEXT(ctx
);
716 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
717 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
719 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
721 if (face
==GL_FRONT
) {
724 else if (face
==GL_BACK
) {
728 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
734 COPY_4FV( params
, mat
[MAT_ATTRIB_AMBIENT(f
)] );
737 COPY_4FV( params
, mat
[MAT_ATTRIB_DIFFUSE(f
)] );
740 COPY_4FV( params
, mat
[MAT_ATTRIB_SPECULAR(f
)] );
743 COPY_4FV( params
, mat
[MAT_ATTRIB_EMISSION(f
)] );
746 *params
= mat
[MAT_ATTRIB_SHININESS(f
)][0];
748 case GL_COLOR_INDEXES
:
749 params
[0] = mat
[MAT_ATTRIB_INDEXES(f
)][0];
750 params
[1] = mat
[MAT_ATTRIB_INDEXES(f
)][1];
751 params
[2] = mat
[MAT_ATTRIB_INDEXES(f
)][2];
754 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
760 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
762 GET_CURRENT_CONTEXT(ctx
);
764 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
765 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
767 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
769 if (face
==GL_FRONT
) {
772 else if (face
==GL_BACK
) {
776 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
781 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][0] );
782 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][1] );
783 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][2] );
784 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][3] );
787 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][0] );
788 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][1] );
789 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][2] );
790 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][3] );
793 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][0] );
794 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][1] );
795 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][2] );
796 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][3] );
799 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][0] );
800 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][1] );
801 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][2] );
802 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][3] );
805 *params
= IROUND( mat
[MAT_ATTRIB_SHININESS(f
)][0] );
807 case GL_COLOR_INDEXES
:
808 params
[0] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][0] );
809 params
[1] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][1] );
810 params
[2] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][2] );
813 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
819 /**********************************************************************/
820 /***** Lighting computation *****/
821 /**********************************************************************/
826 * When two-sided lighting is enabled we compute the color (or index)
827 * for both the front and back side of the primitive. Then, when the
828 * orientation of the facet is later learned, we can determine which
829 * color (or index) to use for rendering.
831 * KW: We now know orientation in advance and only shade for
832 * the side or sides which are actually required.
836 * V = vertex position
837 * P = light source position
842 * // light at infinity
843 * IF local_viewer THEN
844 * _VP_inf_norm = unit vector from V to P // Precompute
847 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
852 * Normalize( v ) = normalized vector v
853 * Magnitude( v ) = length of vector v
859 * Whenever the spotlight exponent for a light changes we must call
860 * this function to recompute the exponent lookup table.
863 _mesa_invalidate_spot_exp_table( struct gl_light
*l
)
865 l
->_SpotExpTable
[0][0] = -1;
870 validate_spot_exp_table( struct gl_light
*l
)
873 GLdouble exponent
= l
->SpotExponent
;
877 l
->_SpotExpTable
[0][0] = 0.0;
879 for (i
= EXP_TABLE_SIZE
- 1; i
> 0 ;i
--) {
881 tmp
= pow(i
/ (GLdouble
) (EXP_TABLE_SIZE
- 1), exponent
);
882 if (tmp
< FLT_MIN
* 100.0) {
887 l
->_SpotExpTable
[i
][0] = (GLfloat
) tmp
;
889 for (i
= 0; i
< EXP_TABLE_SIZE
- 1; i
++) {
890 l
->_SpotExpTable
[i
][1] = (l
->_SpotExpTable
[i
+1][0] -
891 l
->_SpotExpTable
[i
][0]);
893 l
->_SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
898 /* Calculate a new shine table. Doing this here saves a branch in
899 * lighting, and the cost of doing it early may be partially offset
900 * by keeping a MRU cache of shine tables for various shine values.
903 _mesa_invalidate_shine_table( struct gl_context
*ctx
, GLuint side
)
906 if (ctx
->_ShineTable
[side
])
907 ctx
->_ShineTable
[side
]->refcount
--;
908 ctx
->_ShineTable
[side
] = NULL
;
913 validate_shine_table( struct gl_context
*ctx
, GLuint side
, GLfloat shininess
)
915 struct gl_shine_tab
*list
= ctx
->_ShineTabList
;
916 struct gl_shine_tab
*s
;
921 if ( s
->shininess
== shininess
)
929 if (s
->refcount
== 0)
934 if (shininess
== 0.0) {
935 for (j
= 1 ; j
<= SHINE_TABLE_SIZE
; j
++)
939 for (j
= 1 ; j
< SHINE_TABLE_SIZE
; j
++) {
940 GLdouble t
, x
= j
/ (GLfloat
) (SHINE_TABLE_SIZE
- 1);
941 if (x
< 0.005) /* underflow check */
943 t
= pow(x
, shininess
);
949 m
[SHINE_TABLE_SIZE
] = 1.0;
952 s
->shininess
= shininess
;
955 if (ctx
->_ShineTable
[side
])
956 ctx
->_ShineTable
[side
]->refcount
--;
958 ctx
->_ShineTable
[side
] = s
;
959 move_to_tail( list
, s
);
965 _mesa_validate_all_lighting_tables( struct gl_context
*ctx
)
970 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_SHININESS
][0];
971 if (!ctx
->_ShineTable
[0] || ctx
->_ShineTable
[0]->shininess
!= shininess
)
972 validate_shine_table( ctx
, 0, shininess
);
974 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_BACK_SHININESS
][0];
975 if (!ctx
->_ShineTable
[1] || ctx
->_ShineTable
[1]->shininess
!= shininess
)
976 validate_shine_table( ctx
, 1, shininess
);
978 for (i
= 0; i
< ctx
->Const
.MaxLights
; i
++)
979 if (ctx
->Light
.Light
[i
]._SpotExpTable
[0][0] == -1)
980 validate_spot_exp_table( &ctx
->Light
.Light
[i
] );
985 * Examine current lighting parameters to determine if the optimized lighting
986 * function can be used.
987 * Also, precompute some lighting values such as the products of light
988 * source and material ambient, diffuse and specular coefficients.
991 _mesa_update_lighting( struct gl_context
*ctx
)
993 struct gl_light
*light
;
994 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
995 ctx
->Light
._Flags
= 0;
997 if (!ctx
->Light
.Enabled
)
1000 foreach(light
, &ctx
->Light
.EnabledList
) {
1001 ctx
->Light
._Flags
|= light
->_Flags
;
1004 ctx
->Light
._NeedVertices
=
1005 ((ctx
->Light
._Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1006 ctx
->Light
.Model
.LocalViewer
);
1008 ctx
->Light
._NeedEyeCoords
= ((ctx
->Light
._Flags
& LIGHT_POSITIONAL
) ||
1009 ctx
->Light
.Model
.LocalViewer
);
1011 /* XXX: This test is overkill & needs to be fixed both for software and
1012 * hardware t&l drivers. The above should be sufficient & should
1013 * be tested to verify this.
1015 if (ctx
->Light
._NeedVertices
)
1016 ctx
->Light
._NeedEyeCoords
= GL_TRUE
;
1018 /* Precompute some shading values. Although we reference
1019 * Light.Material here, we can get away without flushing
1020 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
1021 * are flushed, they will update the derived state at that time.
1023 if (ctx
->Light
.Model
.TwoSide
)
1024 _mesa_update_material(ctx
,
1025 MAT_BIT_FRONT_EMISSION
|
1026 MAT_BIT_FRONT_AMBIENT
|
1027 MAT_BIT_FRONT_DIFFUSE
|
1028 MAT_BIT_FRONT_SPECULAR
|
1029 MAT_BIT_BACK_EMISSION
|
1030 MAT_BIT_BACK_AMBIENT
|
1031 MAT_BIT_BACK_DIFFUSE
|
1032 MAT_BIT_BACK_SPECULAR
);
1034 _mesa_update_material(ctx
,
1035 MAT_BIT_FRONT_EMISSION
|
1036 MAT_BIT_FRONT_AMBIENT
|
1037 MAT_BIT_FRONT_DIFFUSE
|
1038 MAT_BIT_FRONT_SPECULAR
);
1043 * Update state derived from light position, spot direction.
1047 * _TNL_NEW_NEED_EYE_COORDS
1049 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
1050 * Also update on lighting space changes.
1053 compute_light_positions( struct gl_context
*ctx
)
1055 struct gl_light
*light
;
1056 static const GLfloat eye_z
[3] = { 0, 0, 1 };
1058 if (!ctx
->Light
.Enabled
)
1061 if (ctx
->_NeedEyeCoords
) {
1062 COPY_3V( ctx
->_EyeZDir
, eye_z
);
1065 TRANSFORM_NORMAL( ctx
->_EyeZDir
, eye_z
, ctx
->ModelviewMatrixStack
.Top
->m
);
1068 /* Make sure all the light tables are updated before the computation */
1069 _mesa_validate_all_lighting_tables(ctx
);
1071 foreach (light
, &ctx
->Light
.EnabledList
) {
1073 if (ctx
->_NeedEyeCoords
) {
1074 /* _Position is in eye coordinate space */
1075 COPY_4FV( light
->_Position
, light
->EyePosition
);
1078 /* _Position is in object coordinate space */
1079 TRANSFORM_POINT( light
->_Position
, ctx
->ModelviewMatrixStack
.Top
->inv
,
1080 light
->EyePosition
);
1083 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1084 /* VP (VP) = Normalize( Position ) */
1085 COPY_3V( light
->_VP_inf_norm
, light
->_Position
);
1086 NORMALIZE_3FV( light
->_VP_inf_norm
);
1088 if (!ctx
->Light
.Model
.LocalViewer
) {
1089 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1090 ADD_3V( light
->_h_inf_norm
, light
->_VP_inf_norm
, ctx
->_EyeZDir
);
1091 NORMALIZE_3FV( light
->_h_inf_norm
);
1093 light
->_VP_inf_spot_attenuation
= 1.0;
1096 /* positional light w/ homogeneous coordinate, divide by W */
1097 GLfloat wInv
= (GLfloat
)1.0 / light
->_Position
[3];
1098 light
->_Position
[0] *= wInv
;
1099 light
->_Position
[1] *= wInv
;
1100 light
->_Position
[2] *= wInv
;
1103 if (light
->_Flags
& LIGHT_SPOT
) {
1104 /* Note: we normalize the spot direction now */
1106 if (ctx
->_NeedEyeCoords
) {
1107 COPY_3V( light
->_NormSpotDirection
, light
->SpotDirection
);
1108 NORMALIZE_3FV( light
->_NormSpotDirection
);
1112 COPY_3V(spotDir
, light
->SpotDirection
);
1113 NORMALIZE_3FV(spotDir
);
1114 TRANSFORM_NORMAL( light
->_NormSpotDirection
,
1116 ctx
->ModelviewMatrixStack
.Top
->m
);
1119 NORMALIZE_3FV( light
->_NormSpotDirection
);
1121 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1122 GLfloat PV_dot_dir
= - DOT3(light
->_VP_inf_norm
,
1123 light
->_NormSpotDirection
);
1125 if (PV_dot_dir
> light
->_CosCutoff
) {
1126 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1128 light
->_VP_inf_spot_attenuation
=
1129 (GLfloat
) (light
->_SpotExpTable
[k
][0] +
1130 (x
-k
)*light
->_SpotExpTable
[k
][1]);
1133 light
->_VP_inf_spot_attenuation
= 0;
1143 update_modelview_scale( struct gl_context
*ctx
)
1145 ctx
->_ModelViewInvScale
= 1.0F
;
1146 if (!_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
)) {
1147 const GLfloat
*m
= ctx
->ModelviewMatrixStack
.Top
->inv
;
1148 GLfloat f
= m
[2] * m
[2] + m
[6] * m
[6] + m
[10] * m
[10];
1149 if (f
< 1e-12) f
= 1.0;
1150 if (ctx
->_NeedEyeCoords
)
1151 ctx
->_ModelViewInvScale
= (GLfloat
) INV_SQRTF(f
);
1153 ctx
->_ModelViewInvScale
= (GLfloat
) SQRTF(f
);
1159 * Bring up to date any state that relies on _NeedEyeCoords.
1162 _mesa_update_tnl_spaces( struct gl_context
*ctx
, GLuint new_state
)
1164 const GLuint oldneedeyecoords
= ctx
->_NeedEyeCoords
;
1167 ctx
->_NeedEyeCoords
= GL_FALSE
;
1169 if (ctx
->_ForceEyeCoords
||
1170 (ctx
->Texture
._GenFlags
& TEXGEN_NEED_EYE_COORD
) ||
1171 ctx
->Point
._Attenuated
||
1172 ctx
->Light
._NeedEyeCoords
)
1173 ctx
->_NeedEyeCoords
= GL_TRUE
;
1175 if (ctx
->Light
.Enabled
&&
1176 !_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
))
1177 ctx
->_NeedEyeCoords
= GL_TRUE
;
1179 /* Check if the truth-value interpretations of the bitfields have
1182 if (oldneedeyecoords
!= ctx
->_NeedEyeCoords
) {
1183 /* Recalculate all state that depends on _NeedEyeCoords.
1185 update_modelview_scale(ctx
);
1186 compute_light_positions( ctx
);
1188 if (ctx
->Driver
.LightingSpaceChange
)
1189 ctx
->Driver
.LightingSpaceChange( ctx
);
1192 GLuint new_state2
= ctx
->NewState
;
1194 /* Recalculate that same state only if it has been invalidated
1195 * by other statechanges.
1197 if (new_state2
& _NEW_MODELVIEW
)
1198 update_modelview_scale(ctx
);
1200 if (new_state2
& (_NEW_LIGHT
|_NEW_MODELVIEW
))
1201 compute_light_positions( ctx
);
1207 * Drivers may need this if the hardware tnl unit doesn't support the
1208 * light-in-modelspace optimization. It's also useful for debugging.
1211 _mesa_allow_light_in_model( struct gl_context
*ctx
, GLboolean flag
)
1213 ctx
->_ForceEyeCoords
= !flag
;
1214 ctx
->NewState
|= _NEW_POINT
; /* one of the bits from
1215 * _MESA_NEW_NEED_EYE_COORDS.
1221 /**********************************************************************/
1222 /***** Initialization *****/
1223 /**********************************************************************/
1226 * Initialize the n-th light data structure.
1228 * \param l pointer to the gl_light structure to be initialized.
1229 * \param n number of the light.
1230 * \note The defaults for light 0 are different than the other lights.
1233 init_light( struct gl_light
*l
, GLuint n
)
1235 make_empty_list( l
);
1237 ASSIGN_4V( l
->Ambient
, 0.0, 0.0, 0.0, 1.0 );
1239 ASSIGN_4V( l
->Diffuse
, 1.0, 1.0, 1.0, 1.0 );
1240 ASSIGN_4V( l
->Specular
, 1.0, 1.0, 1.0, 1.0 );
1243 ASSIGN_4V( l
->Diffuse
, 0.0, 0.0, 0.0, 1.0 );
1244 ASSIGN_4V( l
->Specular
, 0.0, 0.0, 0.0, 1.0 );
1246 ASSIGN_4V( l
->EyePosition
, 0.0, 0.0, 1.0, 0.0 );
1247 ASSIGN_3V( l
->SpotDirection
, 0.0, 0.0, -1.0 );
1248 l
->SpotExponent
= 0.0;
1249 _mesa_invalidate_spot_exp_table( l
);
1250 l
->SpotCutoff
= 180.0;
1251 l
->_CosCutoffNeg
= -1.0f
;
1252 l
->_CosCutoff
= 0.0; /* KW: -ve values not admitted */
1253 l
->ConstantAttenuation
= 1.0;
1254 l
->LinearAttenuation
= 0.0;
1255 l
->QuadraticAttenuation
= 0.0;
1256 l
->Enabled
= GL_FALSE
;
1261 * Initialize the light model data structure.
1263 * \param lm pointer to the gl_lightmodel structure to be initialized.
1266 init_lightmodel( struct gl_lightmodel
*lm
)
1268 ASSIGN_4V( lm
->Ambient
, 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1269 lm
->LocalViewer
= GL_FALSE
;
1270 lm
->TwoSide
= GL_FALSE
;
1275 * Initialize the material data structure.
1277 * \param m pointer to the gl_material structure to be initialized.
1280 init_material( struct gl_material
*m
)
1282 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1283 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1284 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1285 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1286 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1287 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1289 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1290 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1291 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1292 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1293 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1294 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1299 * Initialize all lighting state for the given context.
1302 _mesa_init_lighting( struct gl_context
*ctx
)
1306 /* Lighting group */
1307 for (i
= 0; i
< MAX_LIGHTS
; i
++) {
1308 init_light( &ctx
->Light
.Light
[i
], i
);
1310 make_empty_list( &ctx
->Light
.EnabledList
);
1312 init_lightmodel( &ctx
->Light
.Model
);
1313 init_material( &ctx
->Light
.Material
);
1314 ctx
->Light
.ShadeModel
= GL_SMOOTH
;
1315 ctx
->Light
.Enabled
= GL_FALSE
;
1316 ctx
->Light
.ColorMaterialFace
= GL_FRONT_AND_BACK
;
1317 ctx
->Light
.ColorMaterialMode
= GL_AMBIENT_AND_DIFFUSE
;
1318 ctx
->Light
.ColorMaterialBitmask
= _mesa_material_bitmask( ctx
,
1320 GL_AMBIENT_AND_DIFFUSE
, ~0,
1323 ctx
->Light
.ColorMaterialEnabled
= GL_FALSE
;
1325 /* Lighting miscellaneous */
1326 ctx
->_ShineTabList
= MALLOC_STRUCT( gl_shine_tab
);
1327 make_empty_list( ctx
->_ShineTabList
);
1328 /* Allocate 10 (arbitrary) shininess lookup tables */
1329 for (i
= 0 ; i
< 10 ; i
++) {
1330 struct gl_shine_tab
*s
= MALLOC_STRUCT( gl_shine_tab
);
1333 insert_at_tail( ctx
->_ShineTabList
, s
);
1337 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
1338 ctx
->_NeedEyeCoords
= GL_FALSE
;
1339 ctx
->_ForceEyeCoords
= GL_FALSE
;
1340 ctx
->_ModelViewInvScale
= 1.0;
1345 * Deallocate malloc'd lighting state attached to given context.
1348 _mesa_free_lighting_data( struct gl_context
*ctx
)
1350 struct gl_shine_tab
*s
, *tmps
;
1352 /* Free lighting shininess exponentiation table */
1353 foreach_s( s
, tmps
, ctx
->_ShineTabList
) {
1356 free( ctx
->_ShineTabList
);