1 /* $Id: light.c,v 1.19 2000/10/28 18:34:48 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 #include "simple_list.h"
46 /* XXX this is a bit of a hack needed for compilation within XFree86 */
53 _mesa_ShadeModel( GLenum mode
)
55 GET_CURRENT_CONTEXT(ctx
);
56 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glShadeModel");
58 if (MESA_VERBOSE
& VERBOSE_API
)
59 fprintf(stderr
, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode
));
61 if (mode
== GL_FLAT
|| mode
== GL_SMOOTH
) {
62 if (ctx
->Light
.ShadeModel
!= mode
) {
63 ctx
->Light
.ShadeModel
= mode
;
64 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
65 SET_BITS(ctx
->TriangleCaps
, DD_FLATSHADE
);
67 CLEAR_BITS(ctx
->TriangleCaps
, DD_FLATSHADE
);
68 ctx
->NewState
|= NEW_RASTER_OPS
;
69 if (ctx
->Driver
.ShadeModel
)
70 (*ctx
->Driver
.ShadeModel
)( ctx
, mode
);
74 gl_error( ctx
, GL_INVALID_ENUM
, "glShadeModel" );
81 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
83 _mesa_Lightfv( light
, pname
, ¶m
);
88 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
90 GET_CURRENT_CONTEXT(ctx
);
94 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLight");
96 l
= (GLint
) (light
- GL_LIGHT0
);
98 if (l
< 0 || l
>= MAX_LIGHTS
) {
99 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
105 COPY_4V( ctx
->Light
.Light
[l
].Ambient
, params
);
109 COPY_4V( ctx
->Light
.Light
[l
].Diffuse
, params
);
113 COPY_4V( ctx
->Light
.Light
[l
].Specular
, params
);
117 /* transform position by ModelView matrix */
118 TRANSFORM_POINT( ctx
->Light
.Light
[l
].EyePosition
,
123 case GL_SPOT_DIRECTION
:
124 /* transform direction by inverse modelview */
125 if (ctx
->ModelView
.flags
& MAT_DIRTY_INVERSE
) {
126 gl_matrix_analyze( &ctx
->ModelView
);
128 TRANSFORM_NORMAL( ctx
->Light
.Light
[l
].EyeDirection
,
130 ctx
->ModelView
.inv
);
133 case GL_SPOT_EXPONENT
:
134 if (params
[0]<0.0 || params
[0]>128.0) {
135 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
138 if (ctx
->Light
.Light
[l
].SpotExponent
!= params
[0]) {
139 ctx
->Light
.Light
[l
].SpotExponent
= params
[0];
140 gl_compute_spot_exp_table( &ctx
->Light
.Light
[l
] );
145 if ((params
[0]<0.0 || params
[0]>90.0) && params
[0]!=180.0) {
146 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
149 ctx
->Light
.Light
[l
].SpotCutoff
= params
[0];
150 ctx
->Light
.Light
[l
].CosCutoff
= cos(params
[0]*DEG2RAD
);
151 if (ctx
->Light
.Light
[l
].CosCutoff
< 0)
152 ctx
->Light
.Light
[l
].CosCutoff
= 0;
155 case GL_CONSTANT_ATTENUATION
:
157 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
160 ctx
->Light
.Light
[l
].ConstantAttenuation
= params
[0];
163 case GL_LINEAR_ATTENUATION
:
165 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
168 ctx
->Light
.Light
[l
].LinearAttenuation
= params
[0];
171 case GL_QUADRATIC_ATTENUATION
:
173 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
176 ctx
->Light
.Light
[l
].QuadraticAttenuation
= params
[0];
180 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
184 if (ctx
->Driver
.Lightfv
)
185 ctx
->Driver
.Lightfv( ctx
, light
, pname
, params
, nParams
);
187 ctx
->NewState
|= NEW_LIGHTING
;
192 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
194 _mesa_Lightiv( light
, pname
, ¶m
);
199 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
207 fparam
[0] = INT_TO_FLOAT( params
[0] );
208 fparam
[1] = INT_TO_FLOAT( params
[1] );
209 fparam
[2] = INT_TO_FLOAT( params
[2] );
210 fparam
[3] = INT_TO_FLOAT( params
[3] );
213 fparam
[0] = (GLfloat
) params
[0];
214 fparam
[1] = (GLfloat
) params
[1];
215 fparam
[2] = (GLfloat
) params
[2];
216 fparam
[3] = (GLfloat
) params
[3];
218 case GL_SPOT_DIRECTION
:
219 fparam
[0] = (GLfloat
) params
[0];
220 fparam
[1] = (GLfloat
) params
[1];
221 fparam
[2] = (GLfloat
) params
[2];
223 case GL_SPOT_EXPONENT
:
225 case GL_CONSTANT_ATTENUATION
:
226 case GL_LINEAR_ATTENUATION
:
227 case GL_QUADRATIC_ATTENUATION
:
228 fparam
[0] = (GLfloat
) params
[0];
231 /* error will be caught later in gl_Lightfv */
235 _mesa_Lightfv( light
, pname
, fparam
);
241 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
243 GET_CURRENT_CONTEXT(ctx
);
244 GLint l
= (GLint
) (light
- GL_LIGHT0
);
246 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
248 if (l
<0 || l
>=MAX_LIGHTS
) {
249 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
255 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
258 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
261 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
264 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
266 case GL_SPOT_DIRECTION
:
267 COPY_3V( params
, ctx
->Light
.Light
[l
].EyeDirection
);
269 case GL_SPOT_EXPONENT
:
270 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
273 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
275 case GL_CONSTANT_ATTENUATION
:
276 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
278 case GL_LINEAR_ATTENUATION
:
279 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
281 case GL_QUADRATIC_ATTENUATION
:
282 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
285 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
293 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
295 GET_CURRENT_CONTEXT(ctx
);
296 GLint l
= (GLint
) (light
- GL_LIGHT0
);
298 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
300 if (l
<0 || l
>=MAX_LIGHTS
) {
301 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
307 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
308 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
309 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
310 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
313 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
314 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
315 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
316 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
319 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
320 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
321 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
322 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
325 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
326 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
327 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
328 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
330 case GL_SPOT_DIRECTION
:
331 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[0];
332 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[1];
333 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[2];
335 case GL_SPOT_EXPONENT
:
336 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
339 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
341 case GL_CONSTANT_ATTENUATION
:
342 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
344 case GL_LINEAR_ATTENUATION
:
345 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
347 case GL_QUADRATIC_ATTENUATION
:
348 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
351 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
358 /**********************************************************************/
359 /*** Light Model ***/
360 /**********************************************************************/
364 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
366 GET_CURRENT_CONTEXT(ctx
);
367 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModelfv");
370 case GL_LIGHT_MODEL_AMBIENT
:
371 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
373 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
375 ctx
->Light
.Model
.LocalViewer
= GL_FALSE
;
377 ctx
->Light
.Model
.LocalViewer
= GL_TRUE
;
379 case GL_LIGHT_MODEL_TWO_SIDE
:
381 ctx
->Light
.Model
.TwoSide
= GL_FALSE
;
383 ctx
->Light
.Model
.TwoSide
= GL_TRUE
;
385 case GL_LIGHT_MODEL_COLOR_CONTROL
:
386 if (params
[0] == (GLfloat
) GL_SINGLE_COLOR
) {
387 ctx
->Light
.Model
.ColorControl
= GL_SINGLE_COLOR
;
388 if (!ctx
->Fog
.ColorSumEnabled
)
389 CLEAR_BITS(ctx
->TriangleCaps
, DD_SEPERATE_SPECULAR
);
391 else if (params
[0] == (GLfloat
) GL_SEPARATE_SPECULAR_COLOR
) {
392 ctx
->Light
.Model
.ColorControl
= GL_SEPARATE_SPECULAR_COLOR
;
393 SET_BITS(ctx
->TriangleCaps
, DD_SEPERATE_SPECULAR
);
396 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel(param)" );
398 ctx
->NewState
|= NEW_RASTER_OPS
;
401 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel" );
405 if (ctx
->Driver
.LightModelfv
)
406 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
408 ctx
->NewState
|= NEW_LIGHTING
;
413 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
416 GET_CURRENT_CONTEXT(ctx
);
417 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModeliv");
420 case GL_LIGHT_MODEL_AMBIENT
:
421 fparam
[0] = INT_TO_FLOAT( params
[0] );
422 fparam
[1] = INT_TO_FLOAT( params
[1] );
423 fparam
[2] = INT_TO_FLOAT( params
[2] );
424 fparam
[3] = INT_TO_FLOAT( params
[3] );
426 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
427 case GL_LIGHT_MODEL_TWO_SIDE
:
428 case GL_LIGHT_MODEL_COLOR_CONTROL
:
429 fparam
[0] = (GLfloat
) params
[0];
432 /* Error will be caught later in gl_LightModelfv */
435 _mesa_LightModelfv( pname
, fparam
);
440 _mesa_LightModeli( GLenum pname
, GLint param
)
442 _mesa_LightModeliv( pname
, ¶m
);
447 _mesa_LightModelf( GLenum pname
, GLfloat param
)
449 _mesa_LightModelfv( pname
, ¶m
);
454 /********** MATERIAL **********/
458 * Given a face and pname value (ala glColorMaterial), compute a bitmask
459 * of the targeted material values.
461 GLuint
gl_material_bitmask( GLcontext
*ctx
, GLenum face
, GLenum pname
,
467 /* Make a bitmask indicating what material attribute(s) we're updating */
470 bitmask
|= FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
;
473 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
476 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
479 bitmask
|= FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
;
482 bitmask
|= FRONT_SHININESS_BIT
| BACK_SHININESS_BIT
;
484 case GL_AMBIENT_AND_DIFFUSE
:
485 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
486 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
488 case GL_COLOR_INDEXES
:
489 bitmask
|= FRONT_INDEXES_BIT
| BACK_INDEXES_BIT
;
492 gl_error( ctx
, GL_INVALID_ENUM
, where
);
496 if (face
==GL_FRONT
) {
497 bitmask
&= FRONT_MATERIAL_BITS
;
499 else if (face
==GL_BACK
) {
500 bitmask
&= BACK_MATERIAL_BITS
;
502 else if (face
!= GL_FRONT_AND_BACK
) {
503 gl_error( ctx
, GL_INVALID_ENUM
, where
);
507 if (bitmask
& ~legal
) {
508 gl_error( ctx
, GL_INVALID_ENUM
, where
);
518 * Check if the global material has to be updated with info that was
519 * associated with a vertex via glMaterial.
520 * This function is used when any material values get changed between
521 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
522 * when GL_COLOR_MATERIAL is enabled.
524 * src[0] is front material, src[1] is back material
526 * KW: Added code here to keep the precomputed variables uptodate.
527 * This means we can use the faster shade functions when using
528 * GL_COLOR_MATERIAL, and we can also now use the precomputed
529 * values in the slower shading functions, which further offsets
530 * the cost of doing this here.
532 void gl_update_material( GLcontext
*ctx
,
533 const struct gl_material src
[2],
536 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
538 if (ctx
->Light
.ColorMaterialEnabled
)
539 bitmask
&= ~ctx
->Light
.ColorMaterialBitmask
;
541 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
542 fprintf(stderr
, "gl_update_material, mask 0x%x\n", bitmask
);
547 /* update material emission */
548 if (bitmask
& FRONT_EMISSION_BIT
) {
549 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
550 COPY_4FV( mat
->Emission
, src
[0].Emission
);
552 if (bitmask
& BACK_EMISSION_BIT
) {
553 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
554 COPY_4FV( mat
->Emission
, src
[1].Emission
);
557 /* update material ambience */
558 if (bitmask
& FRONT_AMBIENT_BIT
) {
559 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
560 COPY_4FV( mat
->Ambient
, src
[0].Ambient
);
561 foreach (light
, list
) {
562 SCALE_3V( light
->MatAmbient
[0], light
->Ambient
, src
[0].Ambient
);
565 if (bitmask
& BACK_AMBIENT_BIT
) {
566 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
567 COPY_4FV( mat
->Ambient
, src
[1].Ambient
);
568 foreach (light
, list
) {
569 SCALE_3V( light
->MatAmbient
[1], light
->Ambient
, src
[1].Ambient
);
573 /* update BaseColor = emission + scene's ambience * material's ambience */
574 if (bitmask
& (FRONT_EMISSION_BIT
| FRONT_AMBIENT_BIT
)) {
575 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
576 COPY_3V( ctx
->Light
.BaseColor
[0], mat
->Emission
);
577 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
579 if (bitmask
& (BACK_EMISSION_BIT
| BACK_AMBIENT_BIT
)) {
580 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
581 COPY_3V( ctx
->Light
.BaseColor
[1], mat
->Emission
);
582 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
585 /* update material diffuse values */
586 if (bitmask
& FRONT_DIFFUSE_BIT
) {
587 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
589 SUB_3V( tmp
, src
[0].Diffuse
, mat
->Diffuse
);
590 foreach (light
, list
) {
591 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
593 COPY_4FV( mat
->Diffuse
, src
[0].Diffuse
);
594 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
596 if (bitmask
& BACK_DIFFUSE_BIT
) {
597 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
599 SUB_3V( tmp
, src
[1].Diffuse
, mat
->Diffuse
);
600 foreach (light
, list
) {
601 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
603 COPY_4FV( mat
->Diffuse
, src
[1].Diffuse
);
604 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
607 /* update material specular values */
608 if (bitmask
& FRONT_SPECULAR_BIT
) {
609 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
611 SUB_3V( tmp
, src
[0].Specular
, mat
->Specular
);
612 foreach (light
, list
) {
613 if (light
->Flags
& LIGHT_SPECULAR
) {
614 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
615 light
->IsMatSpecular
[0] =
616 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
619 COPY_4FV( mat
->Specular
, src
[0].Specular
);
621 if (bitmask
& BACK_SPECULAR_BIT
) {
622 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
624 SUB_3V( tmp
, src
[1].Specular
, mat
->Specular
);
625 foreach (light
, list
) {
626 if (light
->Flags
& LIGHT_SPECULAR
) {
627 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
628 light
->IsMatSpecular
[1] =
629 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
632 COPY_4FV( mat
->Specular
, src
[1].Specular
);
635 if (bitmask
& FRONT_SHININESS_BIT
) {
636 GLfloat shininess
= ctx
->Light
.Material
[0].Shininess
= src
[0].Shininess
;
637 gl_compute_shine_table( ctx
, 0, shininess
);
638 gl_compute_shine_table( ctx
, 2, shininess
* .5 );
640 if (bitmask
& BACK_SHININESS_BIT
) {
641 GLfloat shininess
= ctx
->Light
.Material
[1].Shininess
= src
[1].Shininess
;
642 gl_compute_shine_table( ctx
, 1, shininess
);
643 gl_compute_shine_table( ctx
, 3, shininess
* .5 );
646 if (bitmask
& FRONT_INDEXES_BIT
) {
647 ctx
->Light
.Material
[0].AmbientIndex
= src
[0].AmbientIndex
;
648 ctx
->Light
.Material
[0].DiffuseIndex
= src
[0].DiffuseIndex
;
649 ctx
->Light
.Material
[0].SpecularIndex
= src
[0].SpecularIndex
;
651 if (bitmask
& BACK_INDEXES_BIT
) {
652 ctx
->Light
.Material
[1].AmbientIndex
= src
[1].AmbientIndex
;
653 ctx
->Light
.Material
[1].DiffuseIndex
= src
[1].DiffuseIndex
;
654 ctx
->Light
.Material
[1].SpecularIndex
= src
[1].SpecularIndex
;
659 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
660 fprintf(stderr
, "update_mat emission : %f %f %f\n",
664 fprintf(stderr
, "update_mat specular : %f %f %f\n",
668 fprintf(stderr
, "update_mat diffuse : %f %f %f\n",
672 fprintf(stderr
, "update_mat ambient : %f %f %f\n",
683 * Update the current materials from the given rgba color
684 * according to the bitmask in ColorMaterialBitmask, which is
685 * set by glColorMaterial().
687 void gl_update_color_material( GLcontext
*ctx
,
688 const GLchan rgba
[4] )
690 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
691 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
694 UBYTE_RGBA_TO_FLOAT_RGBA( color
, rgba
);
696 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
697 fprintf(stderr
, "gl_update_color_material, mask 0x%x\n", bitmask
);
699 /* update emissive colors */
700 if (bitmask
& FRONT_EMISSION_BIT
) {
701 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
702 COPY_4FV( mat
->Emission
, color
);
705 if (bitmask
& BACK_EMISSION_BIT
) {
706 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
707 COPY_4FV( mat
->Emission
, color
);
710 /* update light->MatAmbient = light's ambient * material's ambient */
711 if (bitmask
& FRONT_AMBIENT_BIT
) {
712 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
713 foreach (light
, list
) {
714 SCALE_3V( light
->MatAmbient
[0], light
->Ambient
, color
);
716 COPY_4FV( mat
->Ambient
, color
);
719 if (bitmask
& BACK_AMBIENT_BIT
) {
720 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
721 foreach (light
, list
) {
722 SCALE_3V( light
->MatAmbient
[1], light
->Ambient
, color
);
724 COPY_4FV( mat
->Ambient
, color
);
727 /* update BaseColor = emission + scene's ambience * material's ambience */
728 if (bitmask
& (FRONT_EMISSION_BIT
| FRONT_AMBIENT_BIT
)) {
729 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
730 COPY_3V( ctx
->Light
.BaseColor
[0], mat
->Emission
);
731 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
734 if (bitmask
& (BACK_EMISSION_BIT
| BACK_AMBIENT_BIT
)) {
735 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
736 COPY_3V( ctx
->Light
.BaseColor
[1], mat
->Emission
);
737 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
740 /* update light->MatDiffuse = light's diffuse * material's diffuse */
741 if (bitmask
& FRONT_DIFFUSE_BIT
) {
742 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
744 SUB_3V( tmp
, color
, mat
->Diffuse
);
745 foreach (light
, list
) {
746 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
748 COPY_4FV( mat
->Diffuse
, color
);
749 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
752 if (bitmask
& BACK_DIFFUSE_BIT
) {
753 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
755 SUB_3V( tmp
, color
, mat
->Diffuse
);
756 foreach (light
, list
) {
757 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
759 COPY_4FV( mat
->Diffuse
, color
);
760 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
763 /* update light->MatSpecular = light's specular * material's specular */
764 if (bitmask
& FRONT_SPECULAR_BIT
) {
765 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
767 SUB_3V( tmp
, color
, mat
->Specular
);
768 foreach (light
, list
) {
769 if (light
->Flags
& LIGHT_SPECULAR
) {
770 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
771 light
->IsMatSpecular
[0] =
772 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
775 COPY_4FV( mat
->Specular
, color
);
778 if (bitmask
& BACK_SPECULAR_BIT
) {
779 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
781 SUB_3V( tmp
, color
, mat
->Specular
);
782 foreach (light
, list
) {
783 if (light
->Flags
& LIGHT_SPECULAR
) {
784 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
785 light
->IsMatSpecular
[1] =
786 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
789 COPY_4FV( mat
->Specular
, color
);
794 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
795 fprintf(stderr
, "update_color_mat emission : %f %f %f\n",
799 fprintf(stderr
, "update_color_mat specular : %f %f %f\n",
803 fprintf(stderr
, "update_color_mat diffuse : %f %f %f\n",
807 fprintf(stderr
, "update_color_mat ambient : %f %f %f\n",
818 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
820 GET_CURRENT_CONTEXT(ctx
);
822 GLuint legal
= (FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
|
823 FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
|
824 FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
|
825 FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
);
827 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glColorMaterial");
829 if (MESA_VERBOSE
&VERBOSE_API
)
830 fprintf(stderr
, "glColorMaterial %s %s\n",
831 gl_lookup_enum_by_nr(face
),
832 gl_lookup_enum_by_nr(mode
));
834 bitmask
= gl_material_bitmask( ctx
, face
, mode
, legal
, "glColorMaterial" );
837 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
838 ctx
->Light
.ColorMaterialFace
= face
;
839 ctx
->Light
.ColorMaterialMode
= mode
;
842 if (ctx
->Light
.ColorMaterialEnabled
)
843 gl_update_color_material( ctx
, ctx
->Current
.ByteColor
);
850 _mesa_Materialf( GLenum face
, GLenum pname
, GLfloat param
)
852 _mesa_Materialfv( face
, pname
, ¶m
);
856 /* KW: This is now called directly (ie by name) from the glMaterial*
860 _mesa_Materialfv( GLenum face
, GLenum pname
, const GLfloat
*params
)
862 GET_CURRENT_CONTEXT(ctx
);
863 struct immediate
*IM
;
864 struct gl_material
*mat
;
868 bitmask
= gl_material_bitmask( ctx
, face
, pname
, ~0, "gl_Materialfv" );
877 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material
) *
879 IM
->MaterialMask
= (GLuint
*) MALLOC( sizeof(GLuint
) * VB_SIZE
);
883 if (!(IM
->Flag
[count
] & VERT_MATERIAL
)) {
884 IM
->Flag
[count
] |= VERT_MATERIAL
;
885 IM
->MaterialMask
[count
] = 0;
889 IM
->MaterialMask
[count
] |= bitmask
;
890 mat
= IM
->Material
[count
];
892 if (bitmask
& FRONT_AMBIENT_BIT
) {
893 COPY_4FV( mat
[0].Ambient
, params
);
895 if (bitmask
& BACK_AMBIENT_BIT
) {
896 COPY_4FV( mat
[1].Ambient
, params
);
898 if (bitmask
& FRONT_DIFFUSE_BIT
) {
899 COPY_4FV( mat
[0].Diffuse
, params
);
901 if (bitmask
& BACK_DIFFUSE_BIT
) {
902 COPY_4FV( mat
[1].Diffuse
, params
);
904 if (bitmask
& FRONT_SPECULAR_BIT
) {
905 COPY_4FV( mat
[0].Specular
, params
);
907 if (bitmask
& BACK_SPECULAR_BIT
) {
908 COPY_4FV( mat
[1].Specular
, params
);
910 if (bitmask
& FRONT_EMISSION_BIT
) {
911 COPY_4FV( mat
[0].Emission
, params
);
913 if (bitmask
& BACK_EMISSION_BIT
) {
914 COPY_4FV( mat
[1].Emission
, params
);
916 if (bitmask
& FRONT_SHININESS_BIT
) {
917 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
918 mat
[0].Shininess
= shininess
;
920 if (bitmask
& BACK_SHININESS_BIT
) {
921 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
922 mat
[1].Shininess
= shininess
;
924 if (bitmask
& FRONT_INDEXES_BIT
) {
925 mat
[0].AmbientIndex
= params
[0];
926 mat
[0].DiffuseIndex
= params
[1];
927 mat
[0].SpecularIndex
= params
[2];
929 if (bitmask
& BACK_INDEXES_BIT
) {
930 mat
[1].AmbientIndex
= params
[0];
931 mat
[1].DiffuseIndex
= params
[1];
932 mat
[1].SpecularIndex
= params
[2];
938 _mesa_Materiali(GLenum face
, GLenum pname
, GLint param
)
940 _mesa_Materialiv(face
, pname
, ¶m
);
945 _mesa_Materialiv(GLenum face
, GLenum pname
, const GLint
*params
)
953 case GL_AMBIENT_AND_DIFFUSE
:
954 fparam
[0] = INT_TO_FLOAT( params
[0] );
955 fparam
[1] = INT_TO_FLOAT( params
[1] );
956 fparam
[2] = INT_TO_FLOAT( params
[2] );
957 fparam
[3] = INT_TO_FLOAT( params
[3] );
960 fparam
[0] = (GLfloat
) params
[0];
962 case GL_COLOR_INDEXES
:
963 fparam
[0] = (GLfloat
) params
[0];
964 fparam
[1] = (GLfloat
) params
[1];
965 fparam
[2] = (GLfloat
) params
[2];
968 /* Error will be caught later in gl_Materialfv */
971 _mesa_Materialfv(face
, pname
, fparam
);
976 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
978 GET_CURRENT_CONTEXT(ctx
);
981 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialfv");
983 if (face
==GL_FRONT
) {
986 else if (face
==GL_BACK
) {
990 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
995 COPY_4FV( params
, ctx
->Light
.Material
[f
].Ambient
);
998 COPY_4FV( params
, ctx
->Light
.Material
[f
].Diffuse
);
1001 COPY_4FV( params
, ctx
->Light
.Material
[f
].Specular
);
1004 COPY_4FV( params
, ctx
->Light
.Material
[f
].Emission
);
1007 *params
= ctx
->Light
.Material
[f
].Shininess
;
1009 case GL_COLOR_INDEXES
:
1010 params
[0] = ctx
->Light
.Material
[f
].AmbientIndex
;
1011 params
[1] = ctx
->Light
.Material
[f
].DiffuseIndex
;
1012 params
[2] = ctx
->Light
.Material
[f
].SpecularIndex
;
1015 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
1022 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
1024 GET_CURRENT_CONTEXT(ctx
);
1027 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialiv");
1029 if (face
==GL_FRONT
) {
1032 else if (face
==GL_BACK
) {
1036 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
1041 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[0] );
1042 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[1] );
1043 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[2] );
1044 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[3] );
1047 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[0] );
1048 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[1] );
1049 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[2] );
1050 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[3] );
1053 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[0] );
1054 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[1] );
1055 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[2] );
1056 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[3] );
1059 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[0] );
1060 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[1] );
1061 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[2] );
1062 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[3] );
1065 *params
= ROUNDF( ctx
->Light
.Material
[f
].Shininess
);
1067 case GL_COLOR_INDEXES
:
1068 params
[0] = ROUNDF( ctx
->Light
.Material
[f
].AmbientIndex
);
1069 params
[1] = ROUNDF( ctx
->Light
.Material
[f
].DiffuseIndex
);
1070 params
[2] = ROUNDF( ctx
->Light
.Material
[f
].SpecularIndex
);
1073 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
1080 /**********************************************************************/
1081 /***** Lighting computation *****/
1082 /**********************************************************************/
1087 * When two-sided lighting is enabled we compute the color (or index)
1088 * for both the front and back side of the primitive. Then, when the
1089 * orientation of the facet is later learned, we can determine which
1090 * color (or index) to use for rendering.
1092 * KW: We now know orientation in advance and only shade for
1093 * the side or sides which are actually required.
1097 * V = vertex position
1098 * P = light source position
1103 * // light at infinity
1104 * IF local_viewer THEN
1105 * VP_inf_norm = unit vector from V to P // Precompute
1107 * // eye at infinity
1108 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1113 * Normalize( v ) = normalized vector v
1114 * Magnitude( v ) = length of vector v
1120 * Whenever the spotlight exponent for a light changes we must call
1121 * this function to recompute the exponent lookup table.
1124 gl_compute_spot_exp_table( struct gl_light
*l
)
1127 GLdouble exponent
= l
->SpotExponent
;
1131 l
->SpotExpTable
[0][0] = 0.0;
1133 for (i
= EXP_TABLE_SIZE
- 1; i
> 0 ;i
--) {
1135 tmp
= pow(i
/ (GLdouble
) (EXP_TABLE_SIZE
- 1), exponent
);
1136 if (tmp
< FLT_MIN
* 100.0) {
1141 l
->SpotExpTable
[i
][0] = tmp
;
1143 for (i
= 0; i
< EXP_TABLE_SIZE
- 1; i
++) {
1144 l
->SpotExpTable
[i
][1] = l
->SpotExpTable
[i
+1][0] - l
->SpotExpTable
[i
][0];
1146 l
->SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
1152 /* Calculate a new shine table. Doing this here saves a branch in
1153 * lighting, and the cost of doing it early may be partially offset
1154 * by keeping a MRU cache of shine tables for various shine values.
1157 compute_shine_table( struct gl_shine_tab
*tab
, GLfloat shininess
)
1160 GLfloat
*m
= tab
->tab
;
1163 if (shininess
== 0.0) {
1164 for (i
= 1 ; i
<= SHINE_TABLE_SIZE
; i
++)
1168 for (i
= 1 ; i
< SHINE_TABLE_SIZE
; i
++) {
1169 GLdouble t
= pow(i
/ (GLfloat
) (SHINE_TABLE_SIZE
- 1), shininess
);
1175 m
[SHINE_TABLE_SIZE
] = 1.0;
1178 tab
->shininess
= shininess
;
1183 gl_compute_shine_table( GLcontext
*ctx
, GLuint i
, GLfloat shininess
)
1185 #define DISTSQR(a,b) ((a-b)*(a-b))
1186 struct gl_shine_tab
*list
= ctx
->ShineTabList
;
1187 struct gl_shine_tab
*s
;
1190 if ( DISTSQR(s
->shininess
, shininess
) < 1e-4 )
1195 if (s
->refcount
== 0)
1198 compute_shine_table( s
, shininess
);
1201 ctx
->ShineTable
[i
]->refcount
--;
1202 ctx
->ShineTable
[i
] = s
;
1203 move_to_tail( list
, s
);
1212 gl_reinit_light_attrib( GLcontext
*ctx
, struct gl_light_attrib
*l
)
1216 if (ctx
->ShineTable
[0]->shininess
!= l
->Material
[0].Shininess
) {
1217 gl_compute_shine_table( ctx
, 0, l
->Material
[0].Shininess
);
1218 gl_compute_shine_table( ctx
, 2, l
->Material
[0].Shininess
* .5 );
1221 if (ctx
->ShineTable
[1]->shininess
!= l
->Material
[1].Shininess
) {
1222 gl_compute_shine_table( ctx
, 1, l
->Material
[1].Shininess
);
1223 gl_compute_shine_table( ctx
, 3, l
->Material
[1].Shininess
* .5 );
1226 make_empty_list( &l
->EnabledList
);
1227 for (i
= 0 ; i
< MAX_LIGHTS
; i
++) {
1228 if (l
->Light
[i
].Enabled
)
1229 insert_at_tail( &l
->EnabledList
, &l
->Light
[i
] );
1236 * Examine current lighting parameters to determine if the optimized lighting
1237 * function can be used.
1238 * Also, precompute some lighting values such as the products of light
1239 * source and material ambient, diffuse and specular coefficients.
1242 gl_update_lighting( GLcontext
*ctx
)
1244 struct gl_light
*light
;
1246 ctx
->Light
.Flags
= 0;
1248 foreach(light
, &ctx
->Light
.EnabledList
) {
1252 if (light
->EyePosition
[3] != 0.0F
)
1253 light
->Flags
|= LIGHT_POSITIONAL
;
1255 if (LEN_SQUARED_3FV(light
->Specular
) > 1e-16)
1256 light
->Flags
|= LIGHT_SPECULAR
;
1258 if (light
->SpotCutoff
!= 180.0F
)
1259 light
->Flags
|= LIGHT_SPOT
;
1261 ctx
->Light
.Flags
|= light
->Flags
;
1264 ctx
->Light
.NeedVertices
=
1265 ((ctx
->Light
.Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1266 (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) ||
1267 (ctx
->Light
.Model
.LocalViewer
&& (ctx
->Light
.Flags
& LIGHT_SPECULAR
)));
1270 /* Precompute some shading values.
1272 if (ctx
->Visual
.RGBAflag
) {
1273 GLuint sides
= ((ctx
->TriangleCaps
& DD_TRI_LIGHT_TWOSIDE
) ? 2 : 1);
1275 for (side
=0; side
< sides
; side
++) {
1276 struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1278 COPY_3V(ctx
->Light
.BaseColor
[side
], mat
->Emission
);
1279 ACC_SCALE_3V(ctx
->Light
.BaseColor
[side
],
1280 ctx
->Light
.Model
.Ambient
,
1283 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[side
],
1284 ctx
->Light
.Material
[side
].Diffuse
[3] );
1287 foreach (light
, &ctx
->Light
.EnabledList
) {
1288 for (side
=0; side
< sides
; side
++) {
1289 const struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1290 SCALE_3V( light
->MatDiffuse
[side
], light
->Diffuse
, mat
->Diffuse
);
1291 SCALE_3V( light
->MatAmbient
[side
], light
->Ambient
, mat
->Ambient
);
1292 if (light
->Flags
& LIGHT_SPECULAR
) {
1293 SCALE_3V( light
->MatSpecular
[side
], light
->Specular
,
1295 light
->IsMatSpecular
[side
] =
1296 (LEN_SQUARED_3FV(light
->MatSpecular
[side
]) > 1e-16);
1299 light
->IsMatSpecular
[side
] = 0;
1304 static const GLfloat ci
[3] = { .30, .59, .11 };
1305 foreach(light
, &ctx
->Light
.EnabledList
) {
1306 light
->dli
= DOT3(ci
, light
->Diffuse
);
1307 light
->sli
= DOT3(ci
, light
->Specular
);
1314 /* Need to seriously restrict the circumstances under which these
1315 * calc's are performed.
1318 gl_compute_light_positions( GLcontext
*ctx
)
1320 struct gl_light
*light
;
1322 if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) {
1323 static const GLfloat eye_z
[3] = { 0, 0, 1 };
1324 if (ctx
->NeedEyeCoords
) {
1325 COPY_3V( ctx
->EyeZDir
, eye_z
);
1328 TRANSFORM_NORMAL( ctx
->EyeZDir
, eye_z
, ctx
->ModelView
.m
);
1332 foreach (light
, &ctx
->Light
.EnabledList
) {
1334 if (ctx
->NeedEyeCoords
) {
1335 COPY_4FV( light
->Position
, light
->EyePosition
);
1338 TRANSFORM_POINT( light
->Position
, ctx
->ModelView
.inv
,
1339 light
->EyePosition
);
1342 if (!(light
->Flags
& LIGHT_POSITIONAL
)) {
1343 /* VP (VP) = Normalize( Position ) */
1344 COPY_3V( light
->VP_inf_norm
, light
->Position
);
1345 NORMALIZE_3FV( light
->VP_inf_norm
);
1347 if (!ctx
->Light
.Model
.LocalViewer
) {
1348 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1349 ADD_3V( light
->h_inf_norm
, light
->VP_inf_norm
, ctx
->EyeZDir
);
1350 NORMALIZE_3FV( light
->h_inf_norm
);
1352 light
->VP_inf_spot_attenuation
= 1.0;
1355 if (light
->Flags
& LIGHT_SPOT
) {
1356 if (ctx
->NeedEyeNormals
) {
1357 COPY_3V( light
->NormDirection
, light
->EyeDirection
);
1360 TRANSFORM_NORMAL( light
->NormDirection
,
1361 light
->EyeDirection
,
1365 NORMALIZE_3FV( light
->NormDirection
);
1368 /* Unlikely occurrance?
1370 if (!(light
->Flags
& LIGHT_POSITIONAL
)) {
1371 GLfloat PV_dot_dir
= - DOT3(light
->VP_inf_norm
,
1372 light
->NormDirection
);
1374 if (PV_dot_dir
> light
->CosCutoff
) {
1375 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1377 light
->VP_inf_spot_attenuation
=
1378 (light
->SpotExpTable
[k
][0] +
1379 (x
-k
)*light
->SpotExpTable
[k
][1]);
1382 light
->VP_inf_spot_attenuation
= 0;
1391 gl_update_normal_transform( GLcontext
*ctx
)
1393 GLuint new_flag
= 0;
1394 normal_func
*last
= ctx
->NormalTransform
;
1396 ctx
->vb_rescale_factor
= 1.0;
1398 if (ctx
->NeedEyeCoords
) {
1399 if (ctx
->NeedNormals
) {
1400 GLuint transform
= NORM_TRANSFORM_NO_ROT
;
1402 if (ctx
->ModelView
.flags
& (MAT_FLAG_GENERAL
|
1404 MAT_FLAG_GENERAL_3D
|
1405 MAT_FLAG_PERSPECTIVE
))
1406 transform
= NORM_TRANSFORM
;
1409 new_flag
= ctx
->NewState
& NEW_MODELVIEW
;
1410 ctx
->vb_rescale_factor
= ctx
->rescale_factor
;
1412 if (ctx
->Transform
.Normalize
) {
1413 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_NORMALIZE
];
1415 else if (ctx
->Transform
.RescaleNormals
&&
1416 ctx
->rescale_factor
!= 1.0) {
1417 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_RESCALE
];
1420 ctx
->NormalTransform
= gl_normal_tab
[transform
];
1424 ctx
->NormalTransform
= 0;
1428 if (ctx
->NeedNormals
) {
1429 ctx
->vb_rescale_factor
= 1.0/ctx
->rescale_factor
;
1431 if (ctx
->Transform
.Normalize
) {
1432 ctx
->NormalTransform
= gl_normal_tab
[NORM_NORMALIZE
];
1434 else if (!ctx
->Transform
.RescaleNormals
&&
1435 ctx
->rescale_factor
!= 1.0) {
1436 ctx
->NormalTransform
= gl_normal_tab
[NORM_RESCALE
];
1439 ctx
->NormalTransform
= 0;
1443 ctx
->NormalTransform
= 0;
1447 if (last
!= ctx
->NormalTransform
|| new_flag
)
1448 ctx
->NewState
|= NEW_NORMAL_TRANSFORM
;