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.
33 #include "simple_list.h"
35 #include "math/m_matrix.h"
39 _mesa_ShadeModel( GLenum mode
)
41 GET_CURRENT_CONTEXT(ctx
);
42 ASSERT_OUTSIDE_BEGIN_END(ctx
);
44 if (MESA_VERBOSE
& VERBOSE_API
)
45 _mesa_debug(ctx
, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode
));
47 if (mode
!= GL_FLAT
&& mode
!= GL_SMOOTH
) {
48 _mesa_error(ctx
, GL_INVALID_ENUM
, "glShadeModel");
52 if (ctx
->Light
.ShadeModel
== mode
)
55 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
56 ctx
->Light
.ShadeModel
= mode
;
58 ctx
->_TriangleCaps
|= DD_FLATSHADE
;
60 ctx
->_TriangleCaps
&= ~DD_FLATSHADE
;
62 if (ctx
->Driver
.ShadeModel
)
63 ctx
->Driver
.ShadeModel( ctx
, mode
);
68 * Set the provoking vertex (the vertex which specifies the prim's
69 * color when flat shading) to either the first or last vertex of the
73 _mesa_ProvokingVertexEXT(GLenum mode
)
75 GET_CURRENT_CONTEXT(ctx
);
76 ASSERT_OUTSIDE_BEGIN_END(ctx
);
78 if (MESA_VERBOSE
&VERBOSE_API
)
79 _mesa_debug(ctx
, "glProvokingVertexEXT 0x%x\n", mode
);
82 case GL_FIRST_VERTEX_CONVENTION_EXT
:
83 case GL_LAST_VERTEX_CONVENTION_EXT
:
86 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProvokingVertexEXT(0x%x)", mode
);
90 if (ctx
->Light
.ProvokingVertex
== mode
)
93 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
94 ctx
->Light
.ProvokingVertex
= mode
;
99 * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
101 * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
102 * will have already been transformed by the modelview matrix!
103 * Also, all error checking should have already been done.
106 _mesa_light(GLcontext
*ctx
, GLuint lnum
, GLenum pname
, const GLfloat
*params
)
108 struct gl_light
*light
;
110 ASSERT(lnum
< MAX_LIGHTS
);
111 light
= &ctx
->Light
.Light
[lnum
];
115 if (TEST_EQ_4V(light
->Ambient
, params
))
117 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
118 COPY_4V( light
->Ambient
, params
);
121 if (TEST_EQ_4V(light
->Diffuse
, params
))
123 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
124 COPY_4V( light
->Diffuse
, params
);
127 if (TEST_EQ_4V(light
->Specular
, params
))
129 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
130 COPY_4V( light
->Specular
, params
);
133 /* NOTE: position has already been transformed by ModelView! */
134 if (TEST_EQ_4V(light
->EyePosition
, params
))
136 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
137 COPY_4V(light
->EyePosition
, params
);
138 if (light
->EyePosition
[3] != 0.0F
)
139 light
->_Flags
|= LIGHT_POSITIONAL
;
141 light
->_Flags
&= ~LIGHT_POSITIONAL
;
143 case GL_SPOT_DIRECTION
:
144 /* NOTE: Direction already transformed by inverse ModelView! */
145 if (TEST_EQ_3V(light
->SpotDirection
, params
))
147 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
148 COPY_3V(light
->SpotDirection
, params
);
150 case GL_SPOT_EXPONENT
:
151 ASSERT(params
[0] >= 0.0);
152 ASSERT(params
[0] <= ctx
->Const
.MaxSpotExponent
);
153 if (light
->SpotExponent
== params
[0])
155 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
156 light
->SpotExponent
= params
[0];
157 _mesa_invalidate_spot_exp_table(light
);
160 ASSERT(params
[0] == 180.0 || (params
[0] >= 0.0 && params
[0] <= 90.0));
161 if (light
->SpotCutoff
== params
[0])
163 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
164 light
->SpotCutoff
= params
[0];
165 light
->_CosCutoffNeg
= (GLfloat
) (cos(light
->SpotCutoff
* DEG2RAD
));
166 if (light
->_CosCutoffNeg
< 0)
167 light
->_CosCutoff
= 0;
169 light
->_CosCutoff
= light
->_CosCutoffNeg
;
170 if (light
->SpotCutoff
!= 180.0F
)
171 light
->_Flags
|= LIGHT_SPOT
;
173 light
->_Flags
&= ~LIGHT_SPOT
;
175 case GL_CONSTANT_ATTENUATION
:
176 ASSERT(params
[0] >= 0.0);
177 if (light
->ConstantAttenuation
== params
[0])
179 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
180 light
->ConstantAttenuation
= params
[0];
182 case GL_LINEAR_ATTENUATION
:
183 ASSERT(params
[0] >= 0.0);
184 if (light
->LinearAttenuation
== params
[0])
186 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
187 light
->LinearAttenuation
= params
[0];
189 case GL_QUADRATIC_ATTENUATION
:
190 ASSERT(params
[0] >= 0.0);
191 if (light
->QuadraticAttenuation
== params
[0])
193 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
194 light
->QuadraticAttenuation
= params
[0];
197 _mesa_problem(ctx
, "Unexpected pname in _mesa_light()");
201 if (ctx
->Driver
.Lightfv
)
202 ctx
->Driver
.Lightfv( ctx
, GL_LIGHT0
+ lnum
, pname
, params
);
207 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
211 fparam
[1] = fparam
[2] = fparam
[3] = 0.0F
;
212 _mesa_Lightfv( light
, pname
, fparam
);
217 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
219 GET_CURRENT_CONTEXT(ctx
);
220 GLint i
= (GLint
) (light
- GL_LIGHT0
);
222 ASSERT_OUTSIDE_BEGIN_END(ctx
);
224 if (i
< 0 || i
>= (GLint
) ctx
->Const
.MaxLights
) {
225 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLight(light=0x%x)", light
);
229 /* do particular error checks, transformations */
237 /* transform position by ModelView matrix */
238 TRANSFORM_POINT(temp
, ctx
->ModelviewMatrixStack
.Top
->m
, params
);
241 case GL_SPOT_DIRECTION
:
242 /* transform direction by inverse modelview */
243 if (_math_matrix_is_dirty(ctx
->ModelviewMatrixStack
.Top
)) {
244 _math_matrix_analyse(ctx
->ModelviewMatrixStack
.Top
);
246 TRANSFORM_DIRECTION(temp
, params
, ctx
->ModelviewMatrixStack
.Top
->m
);
249 case GL_SPOT_EXPONENT
:
250 if (params
[0] < 0.0 || params
[0] > ctx
->Const
.MaxSpotExponent
) {
251 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
256 if ((params
[0] < 0.0 || params
[0] > 90.0) && params
[0] != 180.0) {
257 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
261 case GL_CONSTANT_ATTENUATION
:
262 if (params
[0] < 0.0) {
263 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
267 case GL_LINEAR_ATTENUATION
:
268 if (params
[0] < 0.0) {
269 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
273 case GL_QUADRATIC_ATTENUATION
:
274 if (params
[0] < 0.0) {
275 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLight");
280 _mesa_error(ctx
, GL_INVALID_ENUM
, "glLight(pname=0x%x)", pname
);
284 _mesa_light(ctx
, i
, pname
, params
);
289 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
293 iparam
[1] = iparam
[2] = iparam
[3] = 0;
294 _mesa_Lightiv( light
, pname
, iparam
);
299 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
307 fparam
[0] = INT_TO_FLOAT( params
[0] );
308 fparam
[1] = INT_TO_FLOAT( params
[1] );
309 fparam
[2] = INT_TO_FLOAT( params
[2] );
310 fparam
[3] = INT_TO_FLOAT( params
[3] );
313 fparam
[0] = (GLfloat
) params
[0];
314 fparam
[1] = (GLfloat
) params
[1];
315 fparam
[2] = (GLfloat
) params
[2];
316 fparam
[3] = (GLfloat
) params
[3];
318 case GL_SPOT_DIRECTION
:
319 fparam
[0] = (GLfloat
) params
[0];
320 fparam
[1] = (GLfloat
) params
[1];
321 fparam
[2] = (GLfloat
) params
[2];
323 case GL_SPOT_EXPONENT
:
325 case GL_CONSTANT_ATTENUATION
:
326 case GL_LINEAR_ATTENUATION
:
327 case GL_QUADRATIC_ATTENUATION
:
328 fparam
[0] = (GLfloat
) params
[0];
331 /* error will be caught later in gl_Lightfv */
335 _mesa_Lightfv( light
, pname
, fparam
);
341 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
343 GET_CURRENT_CONTEXT(ctx
);
344 GLint l
= (GLint
) (light
- GL_LIGHT0
);
345 ASSERT_OUTSIDE_BEGIN_END(ctx
);
347 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
348 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
354 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
357 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
360 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
363 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
365 case GL_SPOT_DIRECTION
:
366 COPY_3V( params
, ctx
->Light
.Light
[l
].SpotDirection
);
368 case GL_SPOT_EXPONENT
:
369 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
372 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
374 case GL_CONSTANT_ATTENUATION
:
375 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
377 case GL_LINEAR_ATTENUATION
:
378 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
380 case GL_QUADRATIC_ATTENUATION
:
381 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
384 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
391 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
393 GET_CURRENT_CONTEXT(ctx
);
394 GLint l
= (GLint
) (light
- GL_LIGHT0
);
395 ASSERT_OUTSIDE_BEGIN_END(ctx
);
397 if (l
< 0 || l
>= (GLint
) ctx
->Const
.MaxLights
) {
398 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
404 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
405 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
406 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
407 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
410 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
411 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
412 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
413 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
416 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
417 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
418 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
419 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
422 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
423 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
424 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
425 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
427 case GL_SPOT_DIRECTION
:
428 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[0];
429 params
[1] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[1];
430 params
[2] = (GLint
) ctx
->Light
.Light
[l
].SpotDirection
[2];
432 case GL_SPOT_EXPONENT
:
433 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
436 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
438 case GL_CONSTANT_ATTENUATION
:
439 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
441 case GL_LINEAR_ATTENUATION
:
442 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
444 case GL_QUADRATIC_ATTENUATION
:
445 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
448 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
455 /**********************************************************************/
456 /*** Light Model ***/
457 /**********************************************************************/
461 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
465 GET_CURRENT_CONTEXT(ctx
);
466 ASSERT_OUTSIDE_BEGIN_END(ctx
);
469 case GL_LIGHT_MODEL_AMBIENT
:
470 if (TEST_EQ_4V( ctx
->Light
.Model
.Ambient
, params
))
472 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
473 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
475 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
476 newbool
= (params
[0]!=0.0);
477 if (ctx
->Light
.Model
.LocalViewer
== newbool
)
479 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
480 ctx
->Light
.Model
.LocalViewer
= newbool
;
482 case GL_LIGHT_MODEL_TWO_SIDE
:
483 newbool
= (params
[0]!=0.0);
484 if (ctx
->Light
.Model
.TwoSide
== newbool
)
486 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
487 ctx
->Light
.Model
.TwoSide
= newbool
;
488 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
)
489 ctx
->_TriangleCaps
|= DD_TRI_LIGHT_TWOSIDE
;
491 ctx
->_TriangleCaps
&= ~DD_TRI_LIGHT_TWOSIDE
;
493 case GL_LIGHT_MODEL_COLOR_CONTROL
:
494 if (params
[0] == (GLfloat
) GL_SINGLE_COLOR
)
495 newenum
= GL_SINGLE_COLOR
;
496 else if (params
[0] == (GLfloat
) GL_SEPARATE_SPECULAR_COLOR
)
497 newenum
= GL_SEPARATE_SPECULAR_COLOR
;
499 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLightModel(param=0x0%x)",
503 if (ctx
->Light
.Model
.ColorControl
== newenum
)
505 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
506 ctx
->Light
.Model
.ColorControl
= newenum
;
509 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLightModel(pname=0x%x)", pname
);
513 if (ctx
->Driver
.LightModelfv
)
514 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
519 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
524 case GL_LIGHT_MODEL_AMBIENT
:
525 fparam
[0] = INT_TO_FLOAT( params
[0] );
526 fparam
[1] = INT_TO_FLOAT( params
[1] );
527 fparam
[2] = INT_TO_FLOAT( params
[2] );
528 fparam
[3] = INT_TO_FLOAT( params
[3] );
530 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
531 case GL_LIGHT_MODEL_TWO_SIDE
:
532 case GL_LIGHT_MODEL_COLOR_CONTROL
:
533 fparam
[0] = (GLfloat
) params
[0];
536 /* Error will be caught later in gl_LightModelfv */
537 ASSIGN_4V(fparam
, 0.0F
, 0.0F
, 0.0F
, 0.0F
);
539 _mesa_LightModelfv( pname
, fparam
);
544 _mesa_LightModeli( GLenum pname
, GLint param
)
548 iparam
[1] = iparam
[2] = iparam
[3] = 0;
549 _mesa_LightModeliv( pname
, iparam
);
554 _mesa_LightModelf( GLenum pname
, GLfloat param
)
558 fparam
[1] = fparam
[2] = fparam
[3] = 0.0F
;
559 _mesa_LightModelfv( pname
, fparam
);
564 /********** MATERIAL **********/
568 * Given a face and pname value (ala glColorMaterial), compute a bitmask
569 * of the targeted material values.
572 _mesa_material_bitmask( GLcontext
*ctx
, GLenum face
, GLenum pname
,
573 GLuint legal
, const char *where
)
577 /* Make a bitmask indicating what material attribute(s) we're updating */
580 bitmask
|= MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
;
583 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
586 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
589 bitmask
|= MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
;
592 bitmask
|= MAT_BIT_FRONT_SHININESS
| MAT_BIT_BACK_SHININESS
;
594 case GL_AMBIENT_AND_DIFFUSE
:
595 bitmask
|= MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
;
596 bitmask
|= MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
;
598 case GL_COLOR_INDEXES
:
599 bitmask
|= MAT_BIT_FRONT_INDEXES
| MAT_BIT_BACK_INDEXES
;
602 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
606 if (face
==GL_FRONT
) {
607 bitmask
&= FRONT_MATERIAL_BITS
;
609 else if (face
==GL_BACK
) {
610 bitmask
&= BACK_MATERIAL_BITS
;
612 else if (face
!= GL_FRONT_AND_BACK
) {
613 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
617 if (bitmask
& ~legal
) {
618 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s", where
);
627 /* Perform a straight copy between materials.
630 _mesa_copy_materials( struct gl_material
*dst
,
631 const struct gl_material
*src
,
636 for (i
= 0 ; i
< MAT_ATTRIB_MAX
; i
++)
637 if (bitmask
& (1<<i
))
638 COPY_4FV( dst
->Attrib
[i
], src
->Attrib
[i
] );
643 /* Update derived values following a change in ctx->Light.Material
646 _mesa_update_material( GLcontext
*ctx
, GLuint bitmask
)
648 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
649 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
651 if (MESA_VERBOSE
& VERBOSE_MATERIAL
)
652 _mesa_debug(ctx
, "_mesa_update_material, mask 0x%x\n", bitmask
);
657 /* update material ambience */
658 if (bitmask
& MAT_BIT_FRONT_AMBIENT
) {
659 foreach (light
, list
) {
660 SCALE_3V( light
->_MatAmbient
[0], light
->Ambient
,
661 mat
[MAT_ATTRIB_FRONT_AMBIENT
]);
665 if (bitmask
& MAT_BIT_BACK_AMBIENT
) {
666 foreach (light
, list
) {
667 SCALE_3V( light
->_MatAmbient
[1], light
->Ambient
,
668 mat
[MAT_ATTRIB_BACK_AMBIENT
]);
672 /* update BaseColor = emission + scene's ambience * material's ambience */
673 if (bitmask
& (MAT_BIT_FRONT_EMISSION
| MAT_BIT_FRONT_AMBIENT
)) {
674 COPY_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_EMISSION
] );
675 ACC_SCALE_3V( ctx
->Light
._BaseColor
[0], mat
[MAT_ATTRIB_FRONT_AMBIENT
],
676 ctx
->Light
.Model
.Ambient
);
679 if (bitmask
& (MAT_BIT_BACK_EMISSION
| MAT_BIT_BACK_AMBIENT
)) {
680 COPY_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_EMISSION
] );
681 ACC_SCALE_3V( ctx
->Light
._BaseColor
[1], mat
[MAT_ATTRIB_BACK_AMBIENT
],
682 ctx
->Light
.Model
.Ambient
);
685 /* update material diffuse values */
686 if (bitmask
& MAT_BIT_FRONT_DIFFUSE
) {
687 foreach (light
, list
) {
688 SCALE_3V( light
->_MatDiffuse
[0], light
->Diffuse
,
689 mat
[MAT_ATTRIB_FRONT_DIFFUSE
] );
693 if (bitmask
& MAT_BIT_BACK_DIFFUSE
) {
694 foreach (light
, list
) {
695 SCALE_3V( light
->_MatDiffuse
[1], light
->Diffuse
,
696 mat
[MAT_ATTRIB_BACK_DIFFUSE
] );
700 /* update material specular values */
701 if (bitmask
& MAT_BIT_FRONT_SPECULAR
) {
702 foreach (light
, list
) {
703 SCALE_3V( light
->_MatSpecular
[0], light
->Specular
,
704 mat
[MAT_ATTRIB_FRONT_SPECULAR
]);
708 if (bitmask
& MAT_BIT_BACK_SPECULAR
) {
709 foreach (light
, list
) {
710 SCALE_3V( light
->_MatSpecular
[1], light
->Specular
,
711 mat
[MAT_ATTRIB_BACK_SPECULAR
]);
715 if (bitmask
& MAT_BIT_FRONT_SHININESS
) {
716 _mesa_invalidate_shine_table( ctx
, 0 );
719 if (bitmask
& MAT_BIT_BACK_SHININESS
) {
720 _mesa_invalidate_shine_table( ctx
, 1 );
726 * Update the current materials from the given rgba color
727 * according to the bitmask in ColorMaterialBitmask, which is
728 * set by glColorMaterial().
731 _mesa_update_color_material( GLcontext
*ctx
, const GLfloat color
[4] )
733 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
734 struct gl_material
*mat
= &ctx
->Light
.Material
;
737 for (i
= 0 ; i
< MAT_ATTRIB_MAX
; i
++)
738 if (bitmask
& (1<<i
))
739 COPY_4FV( mat
->Attrib
[i
], color
);
741 _mesa_update_material( ctx
, bitmask
);
746 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
748 GET_CURRENT_CONTEXT(ctx
);
750 GLuint legal
= (MAT_BIT_FRONT_EMISSION
| MAT_BIT_BACK_EMISSION
|
751 MAT_BIT_FRONT_SPECULAR
| MAT_BIT_BACK_SPECULAR
|
752 MAT_BIT_FRONT_DIFFUSE
| MAT_BIT_BACK_DIFFUSE
|
753 MAT_BIT_FRONT_AMBIENT
| MAT_BIT_BACK_AMBIENT
);
754 ASSERT_OUTSIDE_BEGIN_END(ctx
);
756 if (MESA_VERBOSE
&VERBOSE_API
)
757 _mesa_debug(ctx
, "glColorMaterial %s %s\n",
758 _mesa_lookup_enum_by_nr(face
),
759 _mesa_lookup_enum_by_nr(mode
));
761 bitmask
= _mesa_material_bitmask(ctx
, face
, mode
, legal
, "glColorMaterial");
763 if (ctx
->Light
.ColorMaterialBitmask
== bitmask
&&
764 ctx
->Light
.ColorMaterialFace
== face
&&
765 ctx
->Light
.ColorMaterialMode
== mode
)
768 FLUSH_VERTICES(ctx
, _NEW_LIGHT
);
769 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
770 ctx
->Light
.ColorMaterialFace
= face
;
771 ctx
->Light
.ColorMaterialMode
= mode
;
773 if (ctx
->Light
.ColorMaterialEnabled
) {
774 FLUSH_CURRENT( ctx
, 0 );
775 _mesa_update_color_material(ctx
,ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
]);
778 if (ctx
->Driver
.ColorMaterial
)
779 ctx
->Driver
.ColorMaterial( ctx
, face
, mode
);
784 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
786 GET_CURRENT_CONTEXT(ctx
);
788 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
789 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
791 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
793 if (face
==GL_FRONT
) {
796 else if (face
==GL_BACK
) {
800 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
806 COPY_4FV( params
, mat
[MAT_ATTRIB_AMBIENT(f
)] );
809 COPY_4FV( params
, mat
[MAT_ATTRIB_DIFFUSE(f
)] );
812 COPY_4FV( params
, mat
[MAT_ATTRIB_SPECULAR(f
)] );
815 COPY_4FV( params
, mat
[MAT_ATTRIB_EMISSION(f
)] );
818 *params
= mat
[MAT_ATTRIB_SHININESS(f
)][0];
820 case GL_COLOR_INDEXES
:
821 params
[0] = mat
[MAT_ATTRIB_INDEXES(f
)][0];
822 params
[1] = mat
[MAT_ATTRIB_INDEXES(f
)][1];
823 params
[2] = mat
[MAT_ATTRIB_INDEXES(f
)][2];
826 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
832 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
834 GET_CURRENT_CONTEXT(ctx
);
836 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
837 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* update materials */
839 FLUSH_CURRENT(ctx
, 0); /* update ctx->Light.Material from vertex buffer */
841 if (face
==GL_FRONT
) {
844 else if (face
==GL_BACK
) {
848 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
853 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][0] );
854 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][1] );
855 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][2] );
856 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_AMBIENT(f
)][3] );
859 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][0] );
860 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][1] );
861 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][2] );
862 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_DIFFUSE(f
)][3] );
865 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][0] );
866 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][1] );
867 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][2] );
868 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_SPECULAR(f
)][3] );
871 params
[0] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][0] );
872 params
[1] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][1] );
873 params
[2] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][2] );
874 params
[3] = FLOAT_TO_INT( mat
[MAT_ATTRIB_EMISSION(f
)][3] );
877 *params
= IROUND( mat
[MAT_ATTRIB_SHININESS(f
)][0] );
879 case GL_COLOR_INDEXES
:
880 params
[0] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][0] );
881 params
[1] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][1] );
882 params
[2] = IROUND( mat
[MAT_ATTRIB_INDEXES(f
)][2] );
885 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
891 /**********************************************************************/
892 /***** Lighting computation *****/
893 /**********************************************************************/
898 * When two-sided lighting is enabled we compute the color (or index)
899 * for both the front and back side of the primitive. Then, when the
900 * orientation of the facet is later learned, we can determine which
901 * color (or index) to use for rendering.
903 * KW: We now know orientation in advance and only shade for
904 * the side or sides which are actually required.
908 * V = vertex position
909 * P = light source position
914 * // light at infinity
915 * IF local_viewer THEN
916 * _VP_inf_norm = unit vector from V to P // Precompute
919 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
924 * Normalize( v ) = normalized vector v
925 * Magnitude( v ) = length of vector v
931 * Whenever the spotlight exponent for a light changes we must call
932 * this function to recompute the exponent lookup table.
935 _mesa_invalidate_spot_exp_table( struct gl_light
*l
)
937 l
->_SpotExpTable
[0][0] = -1;
942 validate_spot_exp_table( struct gl_light
*l
)
945 GLdouble exponent
= l
->SpotExponent
;
949 l
->_SpotExpTable
[0][0] = 0.0;
951 for (i
= EXP_TABLE_SIZE
- 1; i
> 0 ;i
--) {
953 tmp
= pow(i
/ (GLdouble
) (EXP_TABLE_SIZE
- 1), exponent
);
954 if (tmp
< FLT_MIN
* 100.0) {
959 l
->_SpotExpTable
[i
][0] = (GLfloat
) tmp
;
961 for (i
= 0; i
< EXP_TABLE_SIZE
- 1; i
++) {
962 l
->_SpotExpTable
[i
][1] = (l
->_SpotExpTable
[i
+1][0] -
963 l
->_SpotExpTable
[i
][0]);
965 l
->_SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
970 /* Calculate a new shine table. Doing this here saves a branch in
971 * lighting, and the cost of doing it early may be partially offset
972 * by keeping a MRU cache of shine tables for various shine values.
975 _mesa_invalidate_shine_table( GLcontext
*ctx
, GLuint side
)
978 if (ctx
->_ShineTable
[side
])
979 ctx
->_ShineTable
[side
]->refcount
--;
980 ctx
->_ShineTable
[side
] = NULL
;
985 validate_shine_table( GLcontext
*ctx
, GLuint side
, GLfloat shininess
)
987 struct gl_shine_tab
*list
= ctx
->_ShineTabList
;
988 struct gl_shine_tab
*s
;
993 if ( s
->shininess
== shininess
)
1001 if (s
->refcount
== 0)
1006 if (shininess
== 0.0) {
1007 for (j
= 1 ; j
<= SHINE_TABLE_SIZE
; j
++)
1011 for (j
= 1 ; j
< SHINE_TABLE_SIZE
; j
++) {
1012 GLdouble t
, x
= j
/ (GLfloat
) (SHINE_TABLE_SIZE
- 1);
1013 if (x
< 0.005) /* underflow check */
1015 t
= pow(x
, shininess
);
1021 m
[SHINE_TABLE_SIZE
] = 1.0;
1024 s
->shininess
= shininess
;
1027 if (ctx
->_ShineTable
[side
])
1028 ctx
->_ShineTable
[side
]->refcount
--;
1030 ctx
->_ShineTable
[side
] = s
;
1031 move_to_tail( list
, s
);
1037 _mesa_validate_all_lighting_tables( GLcontext
*ctx
)
1042 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_SHININESS
][0];
1043 if (!ctx
->_ShineTable
[0] || ctx
->_ShineTable
[0]->shininess
!= shininess
)
1044 validate_shine_table( ctx
, 0, shininess
);
1046 shininess
= ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_BACK_SHININESS
][0];
1047 if (!ctx
->_ShineTable
[1] || ctx
->_ShineTable
[1]->shininess
!= shininess
)
1048 validate_shine_table( ctx
, 1, shininess
);
1050 for (i
= 0; i
< ctx
->Const
.MaxLights
; i
++)
1051 if (ctx
->Light
.Light
[i
]._SpotExpTable
[0][0] == -1)
1052 validate_spot_exp_table( &ctx
->Light
.Light
[i
] );
1057 * Examine current lighting parameters to determine if the optimized lighting
1058 * function can be used.
1059 * Also, precompute some lighting values such as the products of light
1060 * source and material ambient, diffuse and specular coefficients.
1063 _mesa_update_lighting( GLcontext
*ctx
)
1065 struct gl_light
*light
;
1066 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
1067 ctx
->Light
._Flags
= 0;
1069 if (!ctx
->Light
.Enabled
)
1072 foreach(light
, &ctx
->Light
.EnabledList
) {
1073 ctx
->Light
._Flags
|= light
->_Flags
;
1076 ctx
->Light
._NeedVertices
=
1077 ((ctx
->Light
._Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1078 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
||
1079 ctx
->Light
.Model
.LocalViewer
);
1081 ctx
->Light
._NeedEyeCoords
= ((ctx
->Light
._Flags
& LIGHT_POSITIONAL
) ||
1082 ctx
->Light
.Model
.LocalViewer
);
1084 /* XXX: This test is overkill & needs to be fixed both for software and
1085 * hardware t&l drivers. The above should be sufficient & should
1086 * be tested to verify this.
1088 if (ctx
->Light
._NeedVertices
)
1089 ctx
->Light
._NeedEyeCoords
= GL_TRUE
;
1091 /* Precompute some shading values. Although we reference
1092 * Light.Material here, we can get away without flushing
1093 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
1094 * are flushed, they will update the derived state at that time.
1096 if (ctx
->Light
.Model
.TwoSide
)
1097 _mesa_update_material(ctx
,
1098 MAT_BIT_FRONT_EMISSION
|
1099 MAT_BIT_FRONT_AMBIENT
|
1100 MAT_BIT_FRONT_DIFFUSE
|
1101 MAT_BIT_FRONT_SPECULAR
|
1102 MAT_BIT_BACK_EMISSION
|
1103 MAT_BIT_BACK_AMBIENT
|
1104 MAT_BIT_BACK_DIFFUSE
|
1105 MAT_BIT_BACK_SPECULAR
);
1107 _mesa_update_material(ctx
,
1108 MAT_BIT_FRONT_EMISSION
|
1109 MAT_BIT_FRONT_AMBIENT
|
1110 MAT_BIT_FRONT_DIFFUSE
|
1111 MAT_BIT_FRONT_SPECULAR
);
1116 * Update state derived from light position, spot direction.
1120 * _TNL_NEW_NEED_EYE_COORDS
1122 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
1123 * Also update on lighting space changes.
1126 compute_light_positions( GLcontext
*ctx
)
1128 struct gl_light
*light
;
1129 static const GLfloat eye_z
[3] = { 0, 0, 1 };
1131 if (!ctx
->Light
.Enabled
)
1134 if (ctx
->_NeedEyeCoords
) {
1135 COPY_3V( ctx
->_EyeZDir
, eye_z
);
1138 TRANSFORM_NORMAL( ctx
->_EyeZDir
, eye_z
, ctx
->ModelviewMatrixStack
.Top
->m
);
1141 foreach (light
, &ctx
->Light
.EnabledList
) {
1143 if (ctx
->_NeedEyeCoords
) {
1144 /* _Position is in eye coordinate space */
1145 COPY_4FV( light
->_Position
, light
->EyePosition
);
1148 /* _Position is in object coordinate space */
1149 TRANSFORM_POINT( light
->_Position
, ctx
->ModelviewMatrixStack
.Top
->inv
,
1150 light
->EyePosition
);
1153 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1154 /* VP (VP) = Normalize( Position ) */
1155 COPY_3V( light
->_VP_inf_norm
, light
->_Position
);
1156 NORMALIZE_3FV( light
->_VP_inf_norm
);
1158 if (!ctx
->Light
.Model
.LocalViewer
) {
1159 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1160 ADD_3V( light
->_h_inf_norm
, light
->_VP_inf_norm
, ctx
->_EyeZDir
);
1161 NORMALIZE_3FV( light
->_h_inf_norm
);
1163 light
->_VP_inf_spot_attenuation
= 1.0;
1166 /* positional light w/ homogeneous coordinate, divide by W */
1167 GLfloat wInv
= (GLfloat
)1.0 / light
->_Position
[3];
1168 light
->_Position
[0] *= wInv
;
1169 light
->_Position
[1] *= wInv
;
1170 light
->_Position
[2] *= wInv
;
1173 if (light
->_Flags
& LIGHT_SPOT
) {
1174 /* Note: we normalize the spot direction now */
1176 if (ctx
->_NeedEyeCoords
) {
1177 COPY_3V( light
->_NormSpotDirection
, light
->SpotDirection
);
1178 NORMALIZE_3FV( light
->_NormSpotDirection
);
1182 COPY_3V(spotDir
, light
->SpotDirection
);
1183 NORMALIZE_3FV(spotDir
);
1184 TRANSFORM_NORMAL( light
->_NormSpotDirection
,
1186 ctx
->ModelviewMatrixStack
.Top
->m
);
1189 NORMALIZE_3FV( light
->_NormSpotDirection
);
1191 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
1192 GLfloat PV_dot_dir
= - DOT3(light
->_VP_inf_norm
,
1193 light
->_NormSpotDirection
);
1195 if (PV_dot_dir
> light
->_CosCutoff
) {
1196 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1198 light
->_VP_inf_spot_attenuation
=
1199 (GLfloat
) (light
->_SpotExpTable
[k
][0] +
1200 (x
-k
)*light
->_SpotExpTable
[k
][1]);
1203 light
->_VP_inf_spot_attenuation
= 0;
1213 update_modelview_scale( GLcontext
*ctx
)
1215 ctx
->_ModelViewInvScale
= 1.0F
;
1216 if (!_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
)) {
1217 const GLfloat
*m
= ctx
->ModelviewMatrixStack
.Top
->inv
;
1218 GLfloat f
= m
[2] * m
[2] + m
[6] * m
[6] + m
[10] * m
[10];
1219 if (f
< 1e-12) f
= 1.0;
1220 if (ctx
->_NeedEyeCoords
)
1221 ctx
->_ModelViewInvScale
= (GLfloat
) INV_SQRTF(f
);
1223 ctx
->_ModelViewInvScale
= (GLfloat
) SQRTF(f
);
1229 * Bring up to date any state that relies on _NeedEyeCoords.
1232 _mesa_update_tnl_spaces( GLcontext
*ctx
, GLuint new_state
)
1234 const GLuint oldneedeyecoords
= ctx
->_NeedEyeCoords
;
1237 ctx
->_NeedEyeCoords
= GL_FALSE
;
1239 if (ctx
->_ForceEyeCoords
||
1240 (ctx
->Texture
._GenFlags
& TEXGEN_NEED_EYE_COORD
) ||
1241 ctx
->Point
._Attenuated
||
1242 ctx
->Light
._NeedEyeCoords
)
1243 ctx
->_NeedEyeCoords
= GL_TRUE
;
1245 if (ctx
->Light
.Enabled
&&
1246 !_math_matrix_is_length_preserving(ctx
->ModelviewMatrixStack
.Top
))
1247 ctx
->_NeedEyeCoords
= GL_TRUE
;
1249 /* Check if the truth-value interpretations of the bitfields have
1252 if (oldneedeyecoords
!= ctx
->_NeedEyeCoords
) {
1253 /* Recalculate all state that depends on _NeedEyeCoords.
1255 update_modelview_scale(ctx
);
1256 compute_light_positions( ctx
);
1258 if (ctx
->Driver
.LightingSpaceChange
)
1259 ctx
->Driver
.LightingSpaceChange( ctx
);
1262 GLuint new_state2
= ctx
->NewState
;
1264 /* Recalculate that same state only if it has been invalidated
1265 * by other statechanges.
1267 if (new_state2
& _NEW_MODELVIEW
)
1268 update_modelview_scale(ctx
);
1270 if (new_state2
& (_NEW_LIGHT
|_NEW_MODELVIEW
))
1271 compute_light_positions( ctx
);
1277 * Drivers may need this if the hardware tnl unit doesn't support the
1278 * light-in-modelspace optimization. It's also useful for debugging.
1281 _mesa_allow_light_in_model( GLcontext
*ctx
, GLboolean flag
)
1283 ctx
->_ForceEyeCoords
= !flag
;
1284 ctx
->NewState
|= _NEW_POINT
; /* one of the bits from
1285 * _MESA_NEW_NEED_EYE_COORDS.
1291 /**********************************************************************/
1292 /***** Initialization *****/
1293 /**********************************************************************/
1296 * Initialize the n-th light data structure.
1298 * \param l pointer to the gl_light structure to be initialized.
1299 * \param n number of the light.
1300 * \note The defaults for light 0 are different than the other lights.
1303 init_light( struct gl_light
*l
, GLuint n
)
1305 make_empty_list( l
);
1307 ASSIGN_4V( l
->Ambient
, 0.0, 0.0, 0.0, 1.0 );
1309 ASSIGN_4V( l
->Diffuse
, 1.0, 1.0, 1.0, 1.0 );
1310 ASSIGN_4V( l
->Specular
, 1.0, 1.0, 1.0, 1.0 );
1313 ASSIGN_4V( l
->Diffuse
, 0.0, 0.0, 0.0, 1.0 );
1314 ASSIGN_4V( l
->Specular
, 0.0, 0.0, 0.0, 1.0 );
1316 ASSIGN_4V( l
->EyePosition
, 0.0, 0.0, 1.0, 0.0 );
1317 ASSIGN_3V( l
->SpotDirection
, 0.0, 0.0, -1.0 );
1318 l
->SpotExponent
= 0.0;
1319 _mesa_invalidate_spot_exp_table( l
);
1320 l
->SpotCutoff
= 180.0;
1321 l
->_CosCutoffNeg
= -1.0f
;
1322 l
->_CosCutoff
= 0.0; /* KW: -ve values not admitted */
1323 l
->ConstantAttenuation
= 1.0;
1324 l
->LinearAttenuation
= 0.0;
1325 l
->QuadraticAttenuation
= 0.0;
1326 l
->Enabled
= GL_FALSE
;
1331 * Initialize the light model data structure.
1333 * \param lm pointer to the gl_lightmodel structure to be initialized.
1336 init_lightmodel( struct gl_lightmodel
*lm
)
1338 ASSIGN_4V( lm
->Ambient
, 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1339 lm
->LocalViewer
= GL_FALSE
;
1340 lm
->TwoSide
= GL_FALSE
;
1341 lm
->ColorControl
= GL_SINGLE_COLOR
;
1346 * Initialize the material data structure.
1348 * \param m pointer to the gl_material structure to be initialized.
1351 init_material( struct gl_material
*m
)
1353 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1354 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1355 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1356 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1357 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1358 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_FRONT_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1360 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_AMBIENT
], 0.2F
, 0.2F
, 0.2F
, 1.0F
);
1361 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_DIFFUSE
], 0.8F
, 0.8F
, 0.8F
, 1.0F
);
1362 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SPECULAR
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1363 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_EMISSION
], 0.0F
, 0.0F
, 0.0F
, 1.0F
);
1364 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_SHININESS
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
1365 ASSIGN_4V( m
->Attrib
[MAT_ATTRIB_BACK_INDEXES
], 0.0F
, 1.0F
, 1.0F
, 0.0F
);
1370 * Initialize all lighting state for the given context.
1373 _mesa_init_lighting( GLcontext
*ctx
)
1377 /* Lighting group */
1378 for (i
= 0; i
< MAX_LIGHTS
; i
++) {
1379 init_light( &ctx
->Light
.Light
[i
], i
);
1381 make_empty_list( &ctx
->Light
.EnabledList
);
1383 init_lightmodel( &ctx
->Light
.Model
);
1384 init_material( &ctx
->Light
.Material
);
1385 ctx
->Light
.ShadeModel
= GL_SMOOTH
;
1386 ctx
->Light
.ProvokingVertex
= GL_LAST_VERTEX_CONVENTION_EXT
;
1387 ctx
->Light
.Enabled
= GL_FALSE
;
1388 ctx
->Light
.ColorMaterialFace
= GL_FRONT_AND_BACK
;
1389 ctx
->Light
.ColorMaterialMode
= GL_AMBIENT_AND_DIFFUSE
;
1390 ctx
->Light
.ColorMaterialBitmask
= _mesa_material_bitmask( ctx
,
1392 GL_AMBIENT_AND_DIFFUSE
, ~0,
1395 ctx
->Light
.ColorMaterialEnabled
= GL_FALSE
;
1396 ctx
->Light
.ClampVertexColor
= GL_TRUE
;
1398 /* Lighting miscellaneous */
1399 ctx
->_ShineTabList
= MALLOC_STRUCT( gl_shine_tab
);
1400 make_empty_list( ctx
->_ShineTabList
);
1401 /* Allocate 10 (arbitrary) shininess lookup tables */
1402 for (i
= 0 ; i
< 10 ; i
++) {
1403 struct gl_shine_tab
*s
= MALLOC_STRUCT( gl_shine_tab
);
1406 insert_at_tail( ctx
->_ShineTabList
, s
);
1410 ctx
->Light
._NeedEyeCoords
= GL_FALSE
;
1411 ctx
->_NeedEyeCoords
= GL_FALSE
;
1412 ctx
->_ForceEyeCoords
= GL_FALSE
;
1413 ctx
->_ModelViewInvScale
= 1.0;
1418 * Deallocate malloc'd lighting state attached to given context.
1421 _mesa_free_lighting_data( GLcontext
*ctx
)
1423 struct gl_shine_tab
*s
, *tmps
;
1425 /* Free lighting shininess exponentiation table */
1426 foreach_s( s
, tmps
, ctx
->_ShineTabList
) {
1429 free( ctx
->_ShineTabList
);