2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include "simple_list.h"
34 #include "math/m_matrix.h"
38 _mesa_ShadeModel( GLenum mode
)
40 GET_CURRENT_CONTEXT(ctx
);
41 ASSERT_OUTSIDE_BEGIN_END(ctx
);
43 if (MESA_VERBOSE
& VERBOSE_API
)
44 _mesa_debug(ctx
, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode
));
46 if (mode
!= GL_FLAT
&& mode
!= GL_SMOOTH
) {
47 _mesa_error(ctx
, GL_INVALID_ENUM
, "glShadeModel");
51 if (ctx
->Light
.ShadeModel
== mode
)
54 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
55 ctx
->Light
.ShadeModel
= mode
;
56 if (ctx
->Driver
.ShadeModel
)
57 ctx
->Driver
.ShadeModel( ctx
, mode
);
62 * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
64 * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
65 * will have already been transformed by the modelview matrix!
66 * Also, all error checking should have already been done.
69 _mesa_light(GLcontext
*ctx
, GLuint lnum
, GLenum pname
, const GLfloat
*params
)
71 struct gl_light
*light
;
73 ASSERT(lnum
< MAX_LIGHTS
);
74 light
= &ctx
->Light
.Light
[lnum
];
78 if (TEST_EQ_4V(light
->Ambient
, params
))
80 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
81 COPY_4V( light
->Ambient
, params
);
84 if (TEST_EQ_4V(light
->Diffuse
, params
))
86 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
87 COPY_4V( light
->Diffuse
, params
);
90 if (TEST_EQ_4V(light
->Specular
, params
))
92 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
93 COPY_4V( light
->Specular
, params
);
96 /* NOTE: position has already been transformed by ModelView! */
97 if (TEST_EQ_4V(light
->EyePosition
, params
))
99 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
100 COPY_4V(light
->EyePosition
, params
);
101 if (light
->EyePosition
[3] != 0.0F
)
102 light
->_Flags
|= LIGHT_POSITIONAL
;
104 light
->_Flags
&= ~LIGHT_POSITIONAL
;
106 case GL_SPOT_DIRECTION
:
107 /* NOTE: Direction already transformed by inverse ModelView! */
108 if (TEST_EQ_3V(light
->EyeDirection
, params
))
110 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
111 COPY_3V(light
->EyeDirection
, params
);
113 case GL_SPOT_EXPONENT
:
114 ASSERT(params
[0] >= 0.0);
115 ASSERT(params
[0] <= ctx
->Const
.MaxSpotExponent
);
116 if (light
->SpotExponent
== params
[0])
118 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
119 light
->SpotExponent
= params
[0];
120 _mesa_invalidate_spot_exp_table(light
);
123 ASSERT(params
[0] == 180.0 || (params
[0] >= 0.0 && params
[0] <= 90.0));
124 if (light
->SpotCutoff
== params
[0])
126 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
127 light
->SpotCutoff
= params
[0];
128 light
->_CosCutoffNeg
= (GLfloat
) (_mesa_cos(light
->SpotCutoff
* DEG2RAD
));
129 if (light
->_CosCutoffNeg
< 0)
130 light
->_CosCutoff
= 0;
132 light
->_CosCutoff
= light
->_CosCutoffNeg
;
133 if (light
->SpotCutoff
!= 180.0F
)
134 light
->_Flags
|= LIGHT_SPOT
;
136 light
->_Flags
&= ~LIGHT_SPOT
;
138 case GL_CONSTANT_ATTENUATION
:
139 ASSERT(params
[0] >= 0.0);
140 if (light
->ConstantAttenuation
== params
[0])
142 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
143 light
->ConstantAttenuation
= params
[0];
145 case GL_LINEAR_ATTENUATION
:
146 ASSERT(params
[0] >= 0.0);
147 if (light
->LinearAttenuation
== params
[0])
149 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
150 light
->LinearAttenuation
= params
[0];
152 case GL_QUADRATIC_ATTENUATION
:
153 ASSERT(params
[0] >= 0.0);
154 if (light
->QuadraticAttenuation
== params
[0])
156 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
157 light
->QuadraticAttenuation
= params
[0];
160 _mesa_problem(ctx
, "Unexpected pname in _mesa_light()");
164 if (ctx
->Driver
.Lightfv
)
165 ctx
->Driver
.Lightfv( ctx
, GL_LIGHT0
+ lnum
, pname
, params
);
170 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
172 _mesa_Lightfv( light
, pname
, ¶m
);
177 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
179 GET_CURRENT_CONTEXT(ctx
);
180 GLint i
= (GLint
) (light
- GL_LIGHT0
);
183 if (i
< 0 || i
>= (GLint
) ctx
->Const
.MaxLights
) {
184 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLight(light=0x%x)", light
);
188 /* do particular error checks, transformations */
196 /* transform position by ModelView matrix */
197 TRANSFORM_POINT(temp
, ctx
->ModelviewMatrixStack
.Top
->m
, params
);
200 case GL_SPOT_DIRECTION
:
201 /* transform direction by inverse modelview */
202 if (_math_matrix_is_dirty(ctx
->ModelviewMatrixStack
.Top
)) {
203 _math_matrix_analyse(ctx
->ModelviewMatrixStack
.Top
);
205 TRANSFORM_NORMAL(temp
, params
, ctx
->ModelviewMatrixStack
.Top
->inv
);
208 case GL_SPOT_EXPONENT
:
209 if (params
[0] < 0.0 || params
[0] > ctx
->Const
.MaxSpotExponent
) {
210 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
215 if ((params
[0] < 0.0 || params
[0] > 90.0) && params
[0] != 180.0) {
216 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
220 case GL_CONSTANT_ATTENUATION
:
221 if (params
[0] < 0.0) {
222 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
226 case GL_LINEAR_ATTENUATION
:
227 if (params
[0] < 0.0) {
228 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
232 case GL_QUADRATIC_ATTENUATION
:
233 if (params
[0] < 0.0) {
234 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
239 _mesa_error(ctx
, GL_INVALID_ENUM
, "glLight(pname=0x%x)", pname
);
243 _mesa_light(ctx
, i
, pname
, params
);
248 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
250 _mesa_Lightiv( light
, pname
, ¶m
);
255 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
263 fparam
[0] = INT_TO_FLOAT( params
[0] );
264 fparam
[1] = INT_TO_FLOAT( params
[1] );
265 fparam
[2] = INT_TO_FLOAT( params
[2] );
266 fparam
[3] = INT_TO_FLOAT( params
[3] );
269 fparam
[0] = (GLfloat
) params
[0];
270 fparam
[1] = (GLfloat
) params
[1];
271 fparam
[2] = (GLfloat
) params
[2];
272 fparam
[3] = (GLfloat
) params
[3];
274 case GL_SPOT_DIRECTION
:
275 fparam
[0] = (GLfloat
) params
[0];
276 fparam
[1] = (GLfloat
) params
[1];
277 fparam
[2] = (GLfloat
) params
[2];
279 case GL_SPOT_EXPONENT
:
281 case GL_CONSTANT_ATTENUATION
:
282 case GL_LINEAR_ATTENUATION
:
283 case GL_QUADRATIC_ATTENUATION
:
284 fparam
[0] = (GLfloat
) params
[0];
287 /* error will be caught later in gl_Lightfv */
291 _mesa_Lightfv( light
, pname
, fparam
);
297 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
299 GET_CURRENT_CONTEXT(ctx
);
300 GLint l
= (GLint
) (light
- GL_LIGHT0
);
301 ASSERT_OUTSIDE_BEGIN_END(ctx
);
303 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
304 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
310 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
313 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
316 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
319 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
321 case GL_SPOT_DIRECTION
:
322 COPY_3V( params
, ctx
->Light
.Light
[l
].EyeDirection
);
324 case GL_SPOT_EXPONENT
:
325 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
328 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
330 case GL_CONSTANT_ATTENUATION
:
331 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
333 case GL_LINEAR_ATTENUATION
:
334 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
336 case GL_QUADRATIC_ATTENUATION
:
337 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
340 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
347 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
349 GET_CURRENT_CONTEXT(ctx
);
350 GLint l
= (GLint
) (light
- GL_LIGHT0
);
351 ASSERT_OUTSIDE_BEGIN_END(ctx
);
353 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
354 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
360 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
361 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
362 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
363 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
366 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
367 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
368 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
369 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
372 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
373 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
374 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
375 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
378 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
379 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
380 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
381 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
383 case GL_SPOT_DIRECTION
:
384 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[0];
385 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[1];
386 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[2];
388 case GL_SPOT_EXPONENT
:
389 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
392 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
394 case GL_CONSTANT_ATTENUATION
:
395 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
397 case GL_LINEAR_ATTENUATION
:
398 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
400 case GL_QUADRATIC_ATTENUATION
:
401 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
404 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
411 /**********************************************************************/
412 /*** Light Model ***/
413 /**********************************************************************/
417 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
421 GET_CURRENT_CONTEXT(ctx
);
422 ASSERT_OUTSIDE_BEGIN_END(ctx
);
425 case GL_LIGHT_MODEL_AMBIENT
:
426 if (TEST_EQ_4V( ctx
->Light
.Model
.Ambient
, params
))
428 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
429 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
431 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
432 newbool
= (params
[0]!=0.0);
433 if (ctx
->Light
.Model
.LocalViewer
== newbool
)
435 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
436 ctx
->Light
.Model
.LocalViewer
= newbool
;
438 case GL_LIGHT_MODEL_TWO_SIDE
:
439 newbool
= (params
[0]!=0.0);
440 if (ctx
->Light
.Model
.TwoSide
== newbool
)
442 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
443 ctx
->Light
.Model
.TwoSide
= newbool
;
445 case GL_LIGHT_MODEL_COLOR_CONTROL
:
446 if (params
[0] == (GLfloat
) GL_SINGLE_COLOR
)
447 newenum
= GL_SINGLE_COLOR
;
448 else if (params
[0] == (GLfloat
) GL_SEPARATE_SPECULAR_COLOR
)
449 newenum
= GL_SEPARATE_SPECULAR_COLOR
;
451 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLightModel(param=0x0%x)",
455 if (ctx
->Light
.Model
.ColorControl
== newenum
)
457 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
458 ctx
->Light
.Model
.ColorControl
= newenum
;
461 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLightModel(pname=0x%x)", pname
);
465 if (ctx
->Driver
.LightModelfv
)
466 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
471 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
476 case GL_LIGHT_MODEL_AMBIENT
:
477 fparam
[0] = INT_TO_FLOAT( params
[0] );
478 fparam
[1] = INT_TO_FLOAT( params
[1] );
479 fparam
[2] = INT_TO_FLOAT( params
[2] );
480 fparam
[3] = INT_TO_FLOAT( params
[3] );
482 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
483 case GL_LIGHT_MODEL_TWO_SIDE
:
484 case GL_LIGHT_MODEL_COLOR_CONTROL
:
485 fparam
[0] = (GLfloat
) params
[0];
488 /* Error will be caught later in gl_LightModelfv */
491 _mesa_LightModelfv( pname
, fparam
);
496 _mesa_LightModeli( GLenum pname
, GLint param
)
498 _mesa_LightModeliv( pname
, ¶m
);
503 _mesa_LightModelf( GLenum pname
, GLfloat param
)
505 _mesa_LightModelfv( pname
, ¶m
);
510 /********** MATERIAL **********/
514 * Given a face and pname value (ala glColorMaterial), compute a bitmask
515 * of the targeted material values.
518 _mesa_material_bitmask( GLcontext
*ctx
, GLenum face
, GLenum pname
,
519 GLuint legal
, const char *where
)
523 /* Make a bitmask indicating what material attribute(s) we're updating */
526 bitmask
|= MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
;
529 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
532 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
535 bitmask
|= MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
;
538 bitmask
|= MAT_BIT_FRONT_SHININESS
| MAT_BIT_BACK_SHININESS
;
540 case GL_AMBIENT_AND_DIFFUSE
:
541 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
542 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
544 case GL_COLOR_INDEXES
:
545 bitmask
|= MAT_BIT_FRONT_INDEXES
| MAT_BIT_BACK_INDEXES
;
548 _mesa_error( ctx
, GL_INVALID_ENUM
, where
);
552 if (face
==GL_FRONT
) {
553 bitmask
&= FRONT_MATERIAL_BITS
;
555 else if (face
==GL_BACK
) {
556 bitmask
&= BACK_MATERIAL_BITS
;
558 else if (face
!= GL_FRONT_AND_BACK
) {
559 _mesa_error( ctx
, GL_INVALID_ENUM
, where
);
563 if (bitmask
& ~legal
) {
564 _mesa_error( ctx
, GL_INVALID_ENUM
, where
);
573 /* Perform a straight copy between materials.
576 _mesa_copy_materials( struct gl_material
*dst
,
577 const struct gl_material
*src
,
582 for (i
= 0 ; i
< MAT_ATTRIB_MAX
; i
++)
583 if (bitmask
& (1<<i
))
584 COPY_4FV( dst
->Attrib
[i
], src
->Attrib
[i
] );
589 /* Update derived values following a change in ctx->Light.Material
592 _mesa_update_material( GLcontext
*ctx
, GLuint bitmask
)
594 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
595 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
597 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
598 _mesa_debug(ctx
, "_mesa_update_material, mask 0x%x\n", bitmask
);
603 /* update material ambience */
604 if (bitmask
& MAT_BIT_FRONT_AMBIENT
) {
605 foreach (light
, list
) {
606 SCALE_3V( light
->_MatAmbient
[0], light
->Ambient
,
607 mat
[MAT_ATTRIB_FRONT_AMBIENT
]);
611 if (bitmask
& MAT_BIT_BACK_AMBIENT
) {
612 foreach (light
, list
) {
613 SCALE_3V( light
->_MatAmbient
[1], light
->Ambient
,
614 mat
[MAT_ATTRIB_BACK_AMBIENT
]);
618 /* update BaseColor = emission + scene's ambience * material's ambience */
619 if (bitmask
& (MAT_BIT_FRONT_EMISSION
| MAT_BIT_FRONT_AMBIENT
)) {
620 COPY_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_EMISSION
] );
621 ACC_SCALE_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_AMBIENT
],
622 ctx
->Light
.Model
.Ambient
);
625 if (bitmask
& (MAT_BIT_BACK_EMISSION
| MAT_BIT_BACK_AMBIENT
)) {
626 COPY_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_EMISSION
] );
627 ACC_SCALE_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_AMBIENT
],
628 ctx
->Light
.Model
.Ambient
);
631 /* update material diffuse values */
632 if (bitmask
& MAT_BIT_FRONT_DIFFUSE
) {
633 foreach (light
, list
) {
634 SCALE_3V( light
->_MatDiffuse
[0], light
->Diffuse
,
635 mat
[MAT_ATTRIB_FRONT_DIFFUSE
] );
639 if (bitmask
& MAT_BIT_BACK_DIFFUSE
) {
640 foreach (light
, list
) {
641 SCALE_3V( light
->_MatDiffuse
[1], light
->Diffuse
,
642 mat
[MAT_ATTRIB_BACK_DIFFUSE
] );
646 /* update material specular values */
647 if (bitmask
& MAT_BIT_FRONT_SPECULAR
) {
648 foreach (light
, list
) {
649 SCALE_3V( light
->_MatSpecular
[0], light
->Specular
,
650 mat
[MAT_ATTRIB_FRONT_SPECULAR
]);
654 if (bitmask
& MAT_BIT_BACK_SPECULAR
) {
655 foreach (light
, list
) {
656 SCALE_3V( light
->_MatSpecular
[1], light
->Specular
,
657 mat
[MAT_ATTRIB_BACK_SPECULAR
]);
661 if (bitmask
& MAT_BIT_FRONT_SHININESS
) {
662 _mesa_invalidate_shine_table( ctx
, 0 );
665 if (bitmask
& MAT_BIT_BACK_SHININESS
) {
666 _mesa_invalidate_shine_table( ctx
, 1 );
672 * Update the current materials from the given rgba color
673 * according to the bitmask in ColorMaterialBitmask, which is
674 * set by glColorMaterial().
677 _mesa_update_color_material( GLcontext
*ctx
, const GLfloat color
[4] )
679 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
680 struct gl_material
*mat
= &ctx
->Light
.Material
;
683 for (i
= 0 ; i
< MAT_ATTRIB_MAX
; i
++)
684 if (bitmask
& (1<<i
))
685 COPY_4FV( mat
->Attrib
[i
], color
);
687 _mesa_update_material( ctx
, bitmask
);
692 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
694 GET_CURRENT_CONTEXT(ctx
);
696 GLuint legal
= (MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
|
697 MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
|
698 MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
|
699 MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
);
700 ASSERT_OUTSIDE_BEGIN_END(ctx
);
702 if (MESA_VERBOSE
&VERBOSE_API
)
703 _mesa_debug(ctx
, "glColorMaterial %s %s\n",
704 _mesa_lookup_enum_by_nr(face
),
705 _mesa_lookup_enum_by_nr(mode
));
707 bitmask
= _mesa_material_bitmask(ctx
, face
, mode
, legal
, "glColorMaterial");
709 if (ctx
->Light
.ColorMaterialBitmask
== bitmask
&&
710 ctx
->Light
.ColorMaterialFace
== face
&&
711 ctx
->Light
.ColorMaterialMode
== mode
)
714 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
715 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
716 ctx
->Light
.ColorMaterialFace
= face
;
717 ctx
->Light
.ColorMaterialMode
= mode
;
719 if (ctx
->Light
.ColorMaterialEnabled
) {
720 FLUSH_CURRENT( ctx
, 0 );
721 _mesa_update_color_material(ctx
,ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
]);
724 if (ctx
->Driver
.ColorMaterial
)
725 ctx
->Driver
.ColorMaterial( ctx
, face
, mode
);
730 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
732 GET_CURRENT_CONTEXT(ctx
);
734 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
735 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
737 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
739 if (face
==GL_FRONT
) {
742 else if (face
==GL_BACK
) {
746 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
752 COPY_4FV( params
, mat
[MAT_ATTRIB_AMBIENT(f
)] );
755 COPY_4FV( params
, mat
[MAT_ATTRIB_DIFFUSE(f
)] );
758 COPY_4FV( params
, mat
[MAT_ATTRIB_SPECULAR(f
)] );
761 COPY_4FV( params
, mat
[MAT_ATTRIB_EMISSION(f
)] );
764 *params
= mat
[MAT_ATTRIB_SHININESS(f
)][0];
766 case GL_COLOR_INDEXES
:
767 params
[0] = mat
[MAT_ATTRIB_INDEXES(f
)][0];
768 params
[1] = mat
[MAT_ATTRIB_INDEXES(f
)][1];
769 params
[2] = mat
[MAT_ATTRIB_INDEXES(f
)][2];
772 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
778 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
780 GET_CURRENT_CONTEXT(ctx
);
782 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
783 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
785 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
787 if (face
==GL_FRONT
) {
790 else if (face
==GL_BACK
) {
794 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
799 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][0] );
800 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][1] );
801 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][2] );
802 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][3] );
805 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][0] );
806 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][1] );
807 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][2] );
808 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][3] );
811 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][0] );
812 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][1] );
813 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][2] );
814 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][3] );
817 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][0] );
818 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][1] );
819 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][2] );
820 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][3] );
823 *params
= IROUND( mat
[MAT_ATTRIB_SHININESS(f
)][0] );
825 case GL_COLOR_INDEXES
:
826 params
[0] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][0] );
827 params
[1] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][1] );
828 params
[2] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][2] );
831 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
837 /**********************************************************************/
838 /***** Lighting computation *****/
839 /**********************************************************************/
844 * When two-sided lighting is enabled we compute the color (or index)
845 * for both the front and back side of the primitive. Then, when the
846 * orientation of the facet is later learned, we can determine which
847 * color (or index) to use for rendering.
849 * KW: We now know orientation in advance and only shade for
850 * the side or sides which are actually required.
854 * V = vertex position
855 * P = light source position
860 * // light at infinity
861 * IF local_viewer THEN
862 * _VP_inf_norm = unit vector from V to P // Precompute
865 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
870 * Normalize( v ) = normalized vector v
871 * Magnitude( v ) = length of vector v
877 * Whenever the spotlight exponent for a light changes we must call
878 * this function to recompute the exponent lookup table.
881 _mesa_invalidate_spot_exp_table( struct gl_light
*l
)
883 l
->_SpotExpTable
[0][0] = -1;
888 validate_spot_exp_table( struct gl_light
*l
)
891 GLdouble exponent
= l
->SpotExponent
;
895 l
->_SpotExpTable
[0][0] = 0.0;
897 for (i
= EXP_TABLE_SIZE
- 1; i
> 0 ;i
--) {
899 tmp
= _mesa_pow(i
/ (GLdouble
) (EXP_TABLE_SIZE
- 1), exponent
);
900 if (tmp
< FLT_MIN
* 100.0) {
905 l
->_SpotExpTable
[i
][0] = (GLfloat
) tmp
;
907 for (i
= 0; i
< EXP_TABLE_SIZE
- 1; i
++) {
908 l
->_SpotExpTable
[i
][1] = (l
->_SpotExpTable
[i
+1][0] -
909 l
->_SpotExpTable
[i
][0]);
911 l
->_SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
916 /* Calculate a new shine table. Doing this here saves a branch in
917 * lighting, and the cost of doing it early may be partially offset
918 * by keeping a MRU cache of shine tables for various shine values.
921 _mesa_invalidate_shine_table( GLcontext
*ctx
, GLuint side
)
924 if (ctx
->_ShineTable
[side
])
925 ctx
->_ShineTable
[side
]->refcount
--;
926 ctx
->_ShineTable
[side
] = NULL
;
931 validate_shine_table( GLcontext
*ctx
, GLuint side
, GLfloat shininess
)
933 struct gl_shine_tab
*list
= ctx
->_ShineTabList
;
934 struct gl_shine_tab
*s
;
939 if ( s
->shininess
== shininess
)
947 if (s
->refcount
== 0)
952 if (shininess
== 0.0) {
953 for (j
= 1 ; j
<= SHINE_TABLE_SIZE
; j
++)
957 for (j
= 1 ; j
< SHINE_TABLE_SIZE
; j
++) {
958 GLdouble t
, x
= j
/ (GLfloat
) (SHINE_TABLE_SIZE
- 1);
959 if (x
< 0.005) /* underflow check */
961 t
= _mesa_pow(x
, shininess
);
967 m
[SHINE_TABLE_SIZE
] = 1.0;
970 s
->shininess
= shininess
;
973 if (ctx
->_ShineTable
[side
])
974 ctx
->_ShineTable
[side
]->refcount
--;
976 ctx
->_ShineTable
[side
] = s
;
977 move_to_tail( list
, s
);
983 _mesa_validate_all_lighting_tables( GLcontext
*ctx
)
988 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_SHININESS
][0];
989 if (!ctx
->_ShineTable
[0] || ctx
->_ShineTable
[0]->shininess
!= shininess
)
990 validate_shine_table( ctx
, 0, shininess
);
992 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_BACK_SHININESS
][0];
993 if (!ctx
->_ShineTable
[1] || ctx
->_ShineTable
[1]->shininess
!= shininess
)
994 validate_shine_table( ctx
, 1, shininess
);
996 for (i
= 0; i
< ctx
->Const
.MaxLights
; i
++)
997 if (ctx
->Light
.Light
[i
]._SpotExpTable
[0][0] == -1)
998 validate_spot_exp_table( &ctx
->Light
.Light
[i
] );
1003 * Examine current lighting parameters to determine if the optimized lighting
1004 * function can be used.
1005 * Also, precompute some lighting values such as the products of light
1006 * source and material ambient, diffuse and specular coefficients.
1009 _mesa_update_lighting( GLcontext
*ctx
)
1011 struct gl_light
*light
;
1012 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
1013 ctx
->Light
._Flags
= 0;
1015 if (!ctx
->Light
.Enabled
)
1018 foreach(light
, &ctx
->Light
.EnabledList
) {
1019 ctx
->Light
._Flags
|= light
->_Flags
;
1022 ctx
->Light
._NeedVertices
=
1023 ((ctx
->Light
._Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1024 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
||
1025 ctx
->Light
.Model
.LocalViewer
);
1027 ctx
->Light
._NeedEyeCoords
= ((ctx
->Light
._Flags
& LIGHT_POSITIONAL
) ||
1028 ctx
->Light
.Model
.LocalViewer
);
1030 /* XXX: This test is overkill & needs to be fixed both for software and
1031 * hardware t&l drivers. The above should be sufficient & should
1032 * be tested to verify this.
1034 if (ctx
->Light
._NeedVertices
)
1035 ctx
->Light
._NeedEyeCoords
= GL_TRUE
;
1037 /* Precompute some shading values. Although we reference
1038 * Light.Material here, we can get away without flushing
1039 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
1040 * are flushed, they will update the derived state at that time.
1042 if (ctx
->Visual
.rgbMode
) {
1043 if (ctx
->Light
.Model
.TwoSide
)
1044 _mesa_update_material( ctx
,
1045 MAT_BIT_FRONT_EMISSION
|
1046 MAT_BIT_FRONT_AMBIENT
|
1047 MAT_BIT_FRONT_DIFFUSE
|
1048 MAT_BIT_FRONT_SPECULAR
|
1049 MAT_BIT_BACK_EMISSION
|
1050 MAT_BIT_BACK_AMBIENT
|
1051 MAT_BIT_BACK_DIFFUSE
|
1052 MAT_BIT_BACK_SPECULAR
);
1054 _mesa_update_material( ctx
,
1055 MAT_BIT_FRONT_EMISSION
|
1056 MAT_BIT_FRONT_AMBIENT
|
1057 MAT_BIT_FRONT_DIFFUSE
|
1058 MAT_BIT_FRONT_SPECULAR
);
1061 static const GLfloat ci
[3] = { .30F
, .59F
, .11F
};
1062 foreach(light
, &ctx
->Light
.EnabledList
) {
1063 light
->_dli
= DOT3(ci
, light
->Diffuse
);
1064 light
->_sli
= DOT3(ci
, light
->Specular
);
1071 * Update state derived from light position, spot direction.
1075 * _TNL_NEW_NEED_EYE_COORDS
1077 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
1078 * Also update on lighting space changes.
1081 compute_light_positions( GLcontext
*ctx
)
1083 struct gl_light
*light
;
1084 static const GLfloat eye_z
[3] = { 0, 0, 1 };
1086 if (!ctx
->Light
.Enabled
)
1089 if (ctx
->_NeedEyeCoords
) {
1090 COPY_3V( ctx
->_EyeZDir
, eye_z
);
1093 TRANSFORM_NORMAL( ctx
->_EyeZDir
, eye_z
, ctx
->ModelviewMatrixStack
.Top
->m
);
1096 foreach (light
, &ctx
->Light
.EnabledList
) {
1098 if (ctx
->_NeedEyeCoords
) {
1099 /* _Position is in eye coordinate space */
1100 COPY_4FV( light
->_Position
, light
->EyePosition
);
1103 /* _Position is in object coordinate space */
1104 TRANSFORM_POINT( light
->_Position
, ctx
->ModelviewMatrixStack
.Top
->inv
,
1105 light
->EyePosition
);
1108 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1109 /* VP (VP) = Normalize( Position ) */
1110 COPY_3V( light
->_VP_inf_norm
, light
->_Position
);
1111 NORMALIZE_3FV( light
->_VP_inf_norm
);
1113 if (!ctx
->Light
.Model
.LocalViewer
) {
1114 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1115 ADD_3V( light
->_h_inf_norm
, light
->_VP_inf_norm
, ctx
->_EyeZDir
);
1116 NORMALIZE_3FV( light
->_h_inf_norm
);
1118 light
->_VP_inf_spot_attenuation
= 1.0;
1121 /* positional light w/ homogeneous coordinate, divide by W */
1122 GLfloat wInv
= 1.0 / light
->_Position
[3];
1123 light
->_Position
[0] *= wInv
;
1124 light
->_Position
[1] *= wInv
;
1125 light
->_Position
[2] *= wInv
;
1128 if (light
->_Flags
& LIGHT_SPOT
) {
1129 if (ctx
->_NeedEyeCoords
) {
1130 COPY_3V( light
->_NormDirection
, light
->EyeDirection
);
1133 TRANSFORM_NORMAL( light
->_NormDirection
,
1134 light
->EyeDirection
,
1135 ctx
->ModelviewMatrixStack
.Top
->m
);
1138 NORMALIZE_3FV( light
->_NormDirection
);
1140 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1141 GLfloat PV_dot_dir
= - DOT3(light
->_VP_inf_norm
,
1142 light
->_NormDirection
);
1144 if (PV_dot_dir
> light
->_CosCutoff
) {
1145 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1147 light
->_VP_inf_spot_attenuation
=
1148 (GLfloat
) (light
->_SpotExpTable
[k
][0] +
1149 (x
-k
)*light
->_SpotExpTable
[k
][1]);
1152 light
->_VP_inf_spot_attenuation
= 0;
1162 update_modelview_scale( GLcontext
*ctx
)
1164 ctx
->_ModelViewInvScale
= 1.0F
;
1165 if (!_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
)) {
1166 const GLfloat
*m
= ctx
->ModelviewMatrixStack
.Top
->inv
;
1167 GLfloat f
= m
[2] * m
[2] + m
[6] * m
[6] + m
[10] * m
[10];
1168 if (f
< 1e-12) f
= 1.0;
1169 if (ctx
->_NeedEyeCoords
)
1170 ctx
->_ModelViewInvScale
= (GLfloat
) INV_SQRTF(f
);
1172 ctx
->_ModelViewInvScale
= (GLfloat
) SQRTF(f
);
1178 * Bring up to date any state that relies on _NeedEyeCoords.
1181 _mesa_update_tnl_spaces( GLcontext
*ctx
, GLuint new_state
)
1183 const GLuint oldneedeyecoords
= ctx
->_NeedEyeCoords
;
1186 ctx
->_NeedEyeCoords
= GL_FALSE
;
1188 if (ctx
->_ForceEyeCoords
||
1189 (ctx
->Texture
._GenFlags
& TEXGEN_NEED_EYE_COORD
) ||
1190 ctx
->Point
._Attenuated
||
1191 ctx
->Light
._NeedEyeCoords
)
1192 ctx
->_NeedEyeCoords
= GL_TRUE
;
1194 if (ctx
->Light
.Enabled
&&
1195 !_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
))
1196 ctx
->_NeedEyeCoords
= GL_TRUE
;
1198 /* Check if the truth-value interpretations of the bitfields have
1201 if (oldneedeyecoords
!= ctx
->_NeedEyeCoords
) {
1202 /* Recalculate all state that depends on _NeedEyeCoords.
1204 update_modelview_scale(ctx
);
1205 compute_light_positions( ctx
);
1207 if (ctx
->Driver
.LightingSpaceChange
)
1208 ctx
->Driver
.LightingSpaceChange( ctx
);
1211 GLuint new_state
= ctx
->NewState
;
1213 /* Recalculate that same state only if it has been invalidated
1214 * by other statechanges.
1216 if (new_state
& _NEW_MODELVIEW
)
1217 update_modelview_scale(ctx
);
1219 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
))
1220 compute_light_positions( ctx
);
1226 * Drivers may need this if the hardware tnl unit doesn't support the
1227 * light-in-modelspace optimization. It's also useful for debugging.
1230 _mesa_allow_light_in_model( GLcontext
*ctx
, GLboolean flag
)
1232 ctx
->_ForceEyeCoords
= !flag
;
1233 ctx
->NewState
|= _NEW_POINT
; /* one of the bits from
1234 * _MESA_NEW_NEED_EYE_COORDS.
1240 /**********************************************************************/
1241 /***** Initialization *****/
1242 /**********************************************************************/
1245 * Initialize the n-th light data structure.
1247 * \param l pointer to the gl_light structure to be initialized.
1248 * \param n number of the light.
1249 * \note The defaults for light 0 are different than the other lights.
1252 init_light( struct gl_light
*l
, GLuint n
)
1254 make_empty_list( l
);
1256 ASSIGN_4V( l
->Ambient
, 0.0, 0.0, 0.0, 1.0 );
1258 ASSIGN_4V( l
->Diffuse
, 1.0, 1.0, 1.0, 1.0 );
1259 ASSIGN_4V( l
->Specular
, 1.0, 1.0, 1.0, 1.0 );
1262 ASSIGN_4V( l
->Diffuse
, 0.0, 0.0, 0.0, 1.0 );
1263 ASSIGN_4V( l
->Specular
, 0.0, 0.0, 0.0, 1.0 );
1265 ASSIGN_4V( l
->EyePosition
, 0.0, 0.0, 1.0, 0.0 );
1266 ASSIGN_3V( l
->EyeDirection
, 0.0, 0.0, -1.0 );
1267 l
->SpotExponent
= 0.0;
1268 _mesa_invalidate_spot_exp_table( l
);
1269 l
->SpotCutoff
= 180.0;
1270 l
->_CosCutoffNeg
= -1.0f
;
1271 l
->_CosCutoff
= 0.0; /* KW: -ve values not admitted */
1272 l
->ConstantAttenuation
= 1.0;
1273 l
->LinearAttenuation
= 0.0;
1274 l
->QuadraticAttenuation
= 0.0;
1275 l
->Enabled
= GL_FALSE
;
1280 * Initialize the light model data structure.
1282 * \param lm pointer to the gl_lightmodel structure to be initialized.
1285 init_lightmodel( struct gl_lightmodel
*lm
)
1287 ASSIGN_4V( lm
->Ambient
, 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1288 lm
->LocalViewer
= GL_FALSE
;
1289 lm
->TwoSide
= GL_FALSE
;
1290 lm
->ColorControl
= GL_SINGLE_COLOR
;
1295 * Initialize the material data structure.
1297 * \param m pointer to the gl_material structure to be initialized.
1300 init_material( struct gl_material
*m
)
1302 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1303 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1304 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1305 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1306 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1307 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1309 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1310 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1311 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1312 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1313 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1314 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1319 * Initialize all lighting state for the given context.
1322 _mesa_init_lighting( GLcontext
*ctx
)
1326 /* Lighting group */
1327 for (i
= 0; i
< MAX_LIGHTS
; i
++) {
1328 init_light( &ctx
->Light
.Light
[i
], i
);
1330 make_empty_list( &ctx
->Light
.EnabledList
);
1332 init_lightmodel( &ctx
->Light
.Model
);
1333 init_material( &ctx
->Light
.Material
);
1334 ctx
->Light
.ShadeModel
= GL_SMOOTH
;
1335 ctx
->Light
.Enabled
= GL_FALSE
;
1336 ctx
->Light
.ColorMaterialFace
= GL_FRONT_AND_BACK
;
1337 ctx
->Light
.ColorMaterialMode
= GL_AMBIENT_AND_DIFFUSE
;
1338 ctx
->Light
.ColorMaterialBitmask
= _mesa_material_bitmask( ctx
,
1340 GL_AMBIENT_AND_DIFFUSE
, ~0,
1343 ctx
->Light
.ColorMaterialEnabled
= GL_FALSE
;
1344 ctx
->Light
.ClampVertexColor
= GL_TRUE
;
1346 /* Lighting miscellaneous */
1347 ctx
->_ShineTabList
= MALLOC_STRUCT( gl_shine_tab
);
1348 make_empty_list( ctx
->_ShineTabList
);
1349 /* Allocate 10 (arbitrary) shininess lookup tables */
1350 for (i
= 0 ; i
< 10 ; i
++) {
1351 struct gl_shine_tab
*s
= MALLOC_STRUCT( gl_shine_tab
);
1354 insert_at_tail( ctx
->_ShineTabList
, s
);
1358 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
1359 ctx
->_NeedEyeCoords
= GL_FALSE
;
1360 ctx
->_ModelViewInvScale
= 1.0;
1365 * Deallocate malloc'd lighting state attached to given context.
1368 _mesa_free_lighting_data( GLcontext
*ctx
)
1370 struct gl_shine_tab
*s
, *tmps
;
1372 /* Free lighting shininess exponentiation table */
1373 foreach_s( s
, tmps
, ctx
->_ShineTabList
) {
1376 _mesa_free( ctx
->_ShineTabList
);