1 /* $Id: light.c,v 1.9 1999/11/11 01:22:27 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 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"
48 _mesa_ShadeModel( GLenum mode
)
50 GET_CURRENT_CONTEXT(ctx
);
51 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glShadeModel");
53 if (MESA_VERBOSE
& VERBOSE_API
)
54 fprintf(stderr
, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode
));
56 if (mode
== GL_FLAT
|| mode
== GL_SMOOTH
) {
57 if (ctx
->Light
.ShadeModel
!=mode
) {
58 ctx
->Light
.ShadeModel
= mode
;
59 ctx
->TriangleCaps
^= DD_FLATSHADE
;
60 ctx
->NewState
|= NEW_RASTER_OPS
;
61 if (ctx
->Driver
.ShadeModel
)
62 (*ctx
->Driver
.ShadeModel
)( ctx
, mode
);
66 gl_error( ctx
, GL_INVALID_ENUM
, "glShadeModel" );
73 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
75 _mesa_Lightfv( light
, pname
, ¶m
);
80 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
82 GET_CURRENT_CONTEXT(ctx
);
86 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLight");
88 l
= (GLint
) (light
- GL_LIGHT0
);
90 if (l
< 0 || l
>= MAX_LIGHTS
) {
91 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
97 COPY_4V( ctx
->Light
.Light
[l
].Ambient
, params
);
101 COPY_4V( ctx
->Light
.Light
[l
].Diffuse
, params
);
105 COPY_4V( ctx
->Light
.Light
[l
].Specular
, params
);
109 /* transform position by ModelView matrix */
110 TRANSFORM_POINT( ctx
->Light
.Light
[l
].EyePosition
,
115 case GL_SPOT_DIRECTION
:
116 /* transform direction by inverse modelview */
117 if (ctx
->ModelView
.flags
& MAT_DIRTY_INVERSE
) {
118 gl_matrix_analyze( &ctx
->ModelView
);
120 TRANSFORM_NORMAL( ctx
->Light
.Light
[l
].EyeDirection
,
122 ctx
->ModelView
.inv
);
125 case GL_SPOT_EXPONENT
:
126 if (params
[0]<0.0 || params
[0]>128.0) {
127 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
130 if (ctx
->Light
.Light
[l
].SpotExponent
!= params
[0]) {
131 ctx
->Light
.Light
[l
].SpotExponent
= params
[0];
132 gl_compute_spot_exp_table( &ctx
->Light
.Light
[l
] );
137 if ((params
[0]<0.0 || params
[0]>90.0) && params
[0]!=180.0) {
138 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
141 ctx
->Light
.Light
[l
].SpotCutoff
= params
[0];
142 ctx
->Light
.Light
[l
].CosCutoff
= cos(params
[0]*DEG2RAD
);
143 if (ctx
->Light
.Light
[l
].CosCutoff
< 0)
144 ctx
->Light
.Light
[l
].CosCutoff
= 0;
147 case GL_CONSTANT_ATTENUATION
:
149 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
152 ctx
->Light
.Light
[l
].ConstantAttenuation
= params
[0];
155 case GL_LINEAR_ATTENUATION
:
157 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
160 ctx
->Light
.Light
[l
].LinearAttenuation
= params
[0];
163 case GL_QUADRATIC_ATTENUATION
:
165 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
168 ctx
->Light
.Light
[l
].QuadraticAttenuation
= params
[0];
172 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
176 if (ctx
->Driver
.Lightfv
)
177 ctx
->Driver
.Lightfv( ctx
, light
, pname
, params
, nParams
);
179 ctx
->NewState
|= NEW_LIGHTING
;
184 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
186 _mesa_Lightiv( light
, pname
, ¶m
);
191 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
199 fparam
[0] = INT_TO_FLOAT( params
[0] );
200 fparam
[1] = INT_TO_FLOAT( params
[1] );
201 fparam
[2] = INT_TO_FLOAT( params
[2] );
202 fparam
[3] = INT_TO_FLOAT( params
[3] );
205 fparam
[0] = (GLfloat
) params
[0];
206 fparam
[1] = (GLfloat
) params
[1];
207 fparam
[2] = (GLfloat
) params
[2];
208 fparam
[3] = (GLfloat
) params
[3];
210 case GL_SPOT_DIRECTION
:
211 fparam
[0] = (GLfloat
) params
[0];
212 fparam
[1] = (GLfloat
) params
[1];
213 fparam
[2] = (GLfloat
) params
[2];
215 case GL_SPOT_EXPONENT
:
217 case GL_CONSTANT_ATTENUATION
:
218 case GL_LINEAR_ATTENUATION
:
219 case GL_QUADRATIC_ATTENUATION
:
220 fparam
[0] = (GLfloat
) params
[0];
223 /* error will be caught later in gl_Lightfv */
227 _mesa_Lightfv( light
, pname
, fparam
);
233 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
235 GET_CURRENT_CONTEXT(ctx
);
236 GLint l
= (GLint
) (light
- GL_LIGHT0
);
238 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
240 if (l
<0 || l
>=MAX_LIGHTS
) {
241 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
247 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
250 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
253 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
256 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
258 case GL_SPOT_DIRECTION
:
259 COPY_3V( params
, ctx
->Light
.Light
[l
].EyeDirection
);
261 case GL_SPOT_EXPONENT
:
262 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
265 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
267 case GL_CONSTANT_ATTENUATION
:
268 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
270 case GL_LINEAR_ATTENUATION
:
271 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
273 case GL_QUADRATIC_ATTENUATION
:
274 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
277 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
285 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
287 GET_CURRENT_CONTEXT(ctx
);
288 GLint l
= (GLint
) (light
- GL_LIGHT0
);
290 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
292 if (l
<0 || l
>=MAX_LIGHTS
) {
293 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
299 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
300 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
301 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
302 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
305 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
306 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
307 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
308 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
311 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
312 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
313 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
314 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
317 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
318 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
319 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
320 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
322 case GL_SPOT_DIRECTION
:
323 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[0];
324 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[1];
325 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[2];
327 case GL_SPOT_EXPONENT
:
328 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
331 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
333 case GL_CONSTANT_ATTENUATION
:
334 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
336 case GL_LINEAR_ATTENUATION
:
337 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
339 case GL_QUADRATIC_ATTENUATION
:
340 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
343 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
350 /**********************************************************************/
351 /*** Light Model ***/
352 /**********************************************************************/
356 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
358 GET_CURRENT_CONTEXT(ctx
);
359 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModelfv");
362 case GL_LIGHT_MODEL_AMBIENT
:
363 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
365 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
367 ctx
->Light
.Model
.LocalViewer
= GL_FALSE
;
369 ctx
->Light
.Model
.LocalViewer
= GL_TRUE
;
371 case GL_LIGHT_MODEL_TWO_SIDE
:
373 ctx
->Light
.Model
.TwoSide
= GL_FALSE
;
375 ctx
->Light
.Model
.TwoSide
= GL_TRUE
;
377 case GL_LIGHT_MODEL_COLOR_CONTROL
:
378 if (params
[0] == (GLfloat
) GL_SINGLE_COLOR
) {
379 ctx
->Light
.Model
.ColorControl
= GL_SINGLE_COLOR
;
380 ctx
->TriangleCaps
&= ~DD_SEPERATE_SPECULAR
;
382 else if (params
[0] == (GLfloat
) GL_SEPARATE_SPECULAR_COLOR
) {
383 ctx
->Light
.Model
.ColorControl
= GL_SEPARATE_SPECULAR_COLOR
;
384 ctx
->TriangleCaps
|= DD_SEPERATE_SPECULAR
;
387 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel(param)" );
389 ctx
->NewState
|= NEW_RASTER_OPS
;
392 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel" );
396 if (ctx
->Driver
.LightModelfv
)
397 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
399 ctx
->NewState
|= NEW_LIGHTING
;
404 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
407 GET_CURRENT_CONTEXT(ctx
);
408 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModeliv");
411 case GL_LIGHT_MODEL_AMBIENT
:
412 fparam
[0] = INT_TO_FLOAT( params
[0] );
413 fparam
[1] = INT_TO_FLOAT( params
[1] );
414 fparam
[2] = INT_TO_FLOAT( params
[2] );
415 fparam
[3] = INT_TO_FLOAT( params
[3] );
417 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
418 case GL_LIGHT_MODEL_TWO_SIDE
:
419 case GL_LIGHT_MODEL_COLOR_CONTROL
:
420 fparam
[0] = (GLfloat
) params
[0];
423 /* Error will be caught later in gl_LightModelfv */
426 _mesa_LightModelfv( pname
, fparam
);
431 _mesa_LightModeli( GLenum pname
, GLint param
)
433 _mesa_LightModeliv( pname
, ¶m
);
438 _mesa_LightModelf( GLenum pname
, GLfloat param
)
440 _mesa_LightModelfv( pname
, ¶m
);
445 /********** MATERIAL **********/
449 * Given a face and pname value (ala glColorMaterial), compute a bitmask
450 * of the targeted material values.
452 GLuint
gl_material_bitmask( GLcontext
*ctx
, GLenum face
, GLenum pname
,
458 /* Make a bitmask indicating what material attribute(s) we're updating */
461 bitmask
|= FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
;
464 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
467 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
470 bitmask
|= FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
;
473 bitmask
|= FRONT_SHININESS_BIT
| BACK_SHININESS_BIT
;
475 case GL_AMBIENT_AND_DIFFUSE
:
476 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
477 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
479 case GL_COLOR_INDEXES
:
480 bitmask
|= FRONT_INDEXES_BIT
| BACK_INDEXES_BIT
;
483 gl_error( ctx
, GL_INVALID_ENUM
, where
);
487 if (face
==GL_FRONT
) {
488 bitmask
&= FRONT_MATERIAL_BITS
;
490 else if (face
==GL_BACK
) {
491 bitmask
&= BACK_MATERIAL_BITS
;
493 else if (face
!= GL_FRONT_AND_BACK
) {
494 gl_error( ctx
, GL_INVALID_ENUM
, where
);
498 if (bitmask
& ~legal
) {
499 gl_error( ctx
, GL_INVALID_ENUM
, where
);
512 * Check if the global material has to be updated with info that was
513 * associated with a vertex via glMaterial.
514 * This function is used when any material values get changed between
515 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
516 * when GL_COLOR_MATERIAL is enabled.
518 * KW: Added code here to keep the precomputed variables uptodate.
519 * This means we can use the faster shade functions when using
520 * GL_COLOR_MATERIAL, and we can also now use the precomputed
521 * values in the slower shading functions, which further offsets
522 * the cost of doing this here.
524 void gl_update_material( GLcontext
*ctx
,
525 struct gl_material
*src
,
528 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
531 if (ctx
->Light
.ColorMaterialEnabled
)
532 bitmask
&= ~ctx
->Light
.ColorMaterialBitmask
;
534 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
535 fprintf(stderr
, "gl_update_material, mask %x\n", bitmask
);
540 if (bitmask
& FRONT_AMBIENT_BIT
) {
541 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
542 SUB_3V( tmp
, src
[0].Ambient
, mat
->Ambient
);
543 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], ctx
->Light
.Model
.Ambient
, tmp
);
544 foreach (light
, list
) {
545 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], light
->Ambient
, tmp
);
547 COPY_4FV( mat
->Ambient
, src
[0].Ambient
);
549 if (bitmask
& BACK_AMBIENT_BIT
) {
550 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
551 SUB_3V( tmp
, src
[1].Ambient
, mat
->Ambient
);
552 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], ctx
->Light
.Model
.Ambient
, tmp
);
553 foreach (light
, list
) {
554 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], light
->Ambient
, tmp
);
556 COPY_4FV( mat
->Ambient
, src
[1].Ambient
);
558 if (bitmask
& FRONT_DIFFUSE_BIT
) {
559 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
560 SUB_3V( tmp
, src
[0].Diffuse
, mat
->Diffuse
);
561 foreach (light
, list
) {
562 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
564 COPY_4FV( mat
->Diffuse
, src
[0].Diffuse
);
565 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
567 if (bitmask
& BACK_DIFFUSE_BIT
) {
568 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
569 SUB_3V( tmp
, src
[1].Diffuse
, mat
->Diffuse
);
570 foreach (light
, list
) {
571 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
573 COPY_4FV( mat
->Diffuse
, src
[1].Diffuse
);
574 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
576 if (bitmask
& FRONT_SPECULAR_BIT
) {
577 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
578 SUB_3V( tmp
, src
[0].Specular
, mat
->Specular
);
579 foreach (light
, list
) {
580 if (light
->Flags
& LIGHT_SPECULAR
) {
581 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
582 light
->IsMatSpecular
[0] =
583 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
586 COPY_4FV( mat
->Specular
, src
[0].Specular
);
588 if (bitmask
& BACK_SPECULAR_BIT
) {
589 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
590 SUB_3V( tmp
, src
[1].Specular
, mat
->Specular
);
591 foreach (light
, list
) {
592 if (light
->Flags
& LIGHT_SPECULAR
) {
593 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
594 light
->IsMatSpecular
[1] =
595 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
598 COPY_4FV( mat
->Specular
, src
[1].Specular
);
600 if (bitmask
& FRONT_EMISSION_BIT
) {
601 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
602 SUB_3V( tmp
, src
[0].Emission
, mat
->Emission
);
603 ACC_3V( ctx
->Light
.BaseColor
[0], tmp
);
604 COPY_4FV( mat
->Emission
, src
[0].Emission
);
606 if (bitmask
& BACK_EMISSION_BIT
) {
607 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
608 SUB_3V( tmp
, src
[1].Emission
, mat
->Emission
);
609 ACC_3V( ctx
->Light
.BaseColor
[1], tmp
);
610 COPY_4FV( mat
->Emission
, src
[1].Emission
);
612 if (bitmask
& FRONT_SHININESS_BIT
) {
613 GLfloat shininess
= ctx
->Light
.Material
[0].Shininess
= src
[0].Shininess
;
614 gl_compute_shine_table( ctx
, 0, shininess
);
615 gl_compute_shine_table( ctx
, 2, shininess
* .5 );
617 if (bitmask
& BACK_SHININESS_BIT
) {
618 GLfloat shininess
= ctx
->Light
.Material
[1].Shininess
= src
[1].Shininess
;
619 gl_compute_shine_table( ctx
, 1, shininess
);
620 gl_compute_shine_table( ctx
, 3, shininess
* .5 );
622 if (bitmask
& FRONT_INDEXES_BIT
) {
623 ctx
->Light
.Material
[0].AmbientIndex
= src
[0].AmbientIndex
;
624 ctx
->Light
.Material
[0].DiffuseIndex
= src
[0].DiffuseIndex
;
625 ctx
->Light
.Material
[0].SpecularIndex
= src
[0].SpecularIndex
;
627 if (bitmask
& BACK_INDEXES_BIT
) {
628 ctx
->Light
.Material
[1].AmbientIndex
= src
[1].AmbientIndex
;
629 ctx
->Light
.Material
[1].DiffuseIndex
= src
[1].DiffuseIndex
;
630 ctx
->Light
.Material
[1].SpecularIndex
= src
[1].SpecularIndex
;
635 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
636 fprintf(stderr
, "update_mat emission : %f %f %f\n",
640 fprintf(stderr
, "update_mat specular : %f %f %f\n",
644 fprintf(stderr
, "update_mat diffuse : %f %f %f\n",
648 fprintf(stderr
, "update_mat ambient : %f %f %f\n",
660 void gl_update_color_material( GLcontext
*ctx
,
661 const GLubyte rgba
[4] )
663 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
664 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
665 GLfloat tmp
[4], color
[4];
667 UBYTE_RGBA_TO_FLOAT_RGBA( color
, rgba
);
669 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
670 fprintf(stderr
, "gl_update_color_material, mask %x\n", bitmask
);
673 if (bitmask
& FRONT_AMBIENT_BIT
) {
674 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
675 SUB_3V( tmp
, color
, mat
->Ambient
);
676 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], ctx
->Light
.Model
.Ambient
, tmp
);
677 foreach (light
, list
) {
678 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], light
->Ambient
, tmp
);
680 COPY_4FV( mat
->Ambient
, color
);
683 if (bitmask
& BACK_AMBIENT_BIT
) {
684 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
685 SUB_3V( tmp
, color
, mat
->Ambient
);
686 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], ctx
->Light
.Model
.Ambient
, tmp
);
687 foreach (light
, list
) {
688 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], light
->Ambient
, tmp
);
690 COPY_4FV( mat
->Ambient
, color
);
693 if (bitmask
& FRONT_DIFFUSE_BIT
) {
694 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
695 SUB_3V( tmp
, color
, mat
->Diffuse
);
696 foreach (light
, list
) {
697 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
699 COPY_4FV( mat
->Diffuse
, color
);
700 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
703 if (bitmask
& BACK_DIFFUSE_BIT
) {
704 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
705 SUB_3V( tmp
, color
, mat
->Diffuse
);
706 foreach (light
, list
) {
707 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
709 COPY_4FV( mat
->Diffuse
, color
);
710 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
713 if (bitmask
& FRONT_SPECULAR_BIT
) {
714 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
715 SUB_3V( tmp
, color
, mat
->Specular
);
716 foreach (light
, list
) {
717 if (light
->Flags
& LIGHT_SPECULAR
) {
718 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
719 light
->IsMatSpecular
[0] =
720 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
723 COPY_4FV( mat
->Specular
, color
);
725 if (bitmask
& BACK_SPECULAR_BIT
) {
726 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
727 SUB_3V( tmp
, color
, mat
->Specular
);
728 foreach (light
, list
) {
729 if (light
->Flags
& LIGHT_SPECULAR
) {
730 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
731 light
->IsMatSpecular
[1] =
732 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
735 COPY_4FV( mat
->Specular
, color
);
737 if (bitmask
& FRONT_EMISSION_BIT
) {
738 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
739 SUB_3V( tmp
, color
, mat
->Emission
);
740 ACC_3V( ctx
->Light
.BaseColor
[0], tmp
);
741 COPY_4FV( mat
->Emission
, color
);
743 if (bitmask
& BACK_EMISSION_BIT
) {
744 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
745 SUB_3V( tmp
, color
, mat
->Emission
);
746 ACC_3V( ctx
->Light
.BaseColor
[1], tmp
);
747 COPY_4FV( mat
->Emission
, color
);
752 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
753 fprintf(stderr
, "update_color_mat emission : %f %f %f\n",
757 fprintf(stderr
, "update_color_mat specular : %f %f %f\n",
761 fprintf(stderr
, "update_color_mat diffuse : %f %f %f\n",
765 fprintf(stderr
, "update_color_mat ambient : %f %f %f\n",
776 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
778 GET_CURRENT_CONTEXT(ctx
);
780 GLuint legal
= (FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
|
781 FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
|
782 FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
|
783 FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
);
785 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glColorMaterial");
787 if (MESA_VERBOSE
&VERBOSE_API
)
788 fprintf(stderr
, "glColorMaterial %s %s\n",
789 gl_lookup_enum_by_nr(face
),
790 gl_lookup_enum_by_nr(mode
));
792 bitmask
= gl_material_bitmask( ctx
, face
, mode
, legal
, "glColorMaterial" );
795 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
796 ctx
->Light
.ColorMaterialFace
= face
;
797 ctx
->Light
.ColorMaterialMode
= mode
;
800 if (ctx
->Light
.ColorMaterialEnabled
)
801 gl_update_color_material( ctx
, ctx
->Current
.ByteColor
);
808 _mesa_Materialf( GLenum face
, GLenum pname
, GLfloat param
)
810 _mesa_Materialfv( face
, pname
, ¶m
);
814 /* KW: This is now called directly (ie by name) from the glMaterial*
818 _mesa_Materialfv( GLenum face
, GLenum pname
, const GLfloat
*params
)
820 GET_CURRENT_CONTEXT(ctx
);
821 struct immediate
*IM
;
822 struct gl_material
*mat
;
826 bitmask
= gl_material_bitmask( ctx
, face
, pname
, ~0, "gl_Materialfv" );
835 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material
) *
837 IM
->MaterialMask
= (GLuint
*) MALLOC( sizeof(GLuint
) * VB_SIZE
);
841 if (!(IM
->Flag
[count
] & VERT_MATERIAL
)) {
842 IM
->Flag
[count
] |= VERT_MATERIAL
;
843 IM
->MaterialMask
[count
] = 0;
847 IM
->MaterialMask
[count
] |= bitmask
;
848 mat
= IM
->Material
[count
];
850 if (bitmask
& FRONT_AMBIENT_BIT
) {
851 COPY_4FV( mat
[0].Ambient
, params
);
853 if (bitmask
& BACK_AMBIENT_BIT
) {
854 COPY_4FV( mat
[1].Ambient
, params
);
856 if (bitmask
& FRONT_DIFFUSE_BIT
) {
857 COPY_4FV( mat
[0].Diffuse
, params
);
859 if (bitmask
& BACK_DIFFUSE_BIT
) {
860 COPY_4FV( mat
[1].Diffuse
, params
);
862 if (bitmask
& FRONT_SPECULAR_BIT
) {
863 COPY_4FV( mat
[0].Specular
, params
);
865 if (bitmask
& BACK_SPECULAR_BIT
) {
866 COPY_4FV( mat
[1].Specular
, params
);
868 if (bitmask
& FRONT_EMISSION_BIT
) {
869 COPY_4FV( mat
[0].Emission
, params
);
871 if (bitmask
& BACK_EMISSION_BIT
) {
872 COPY_4FV( mat
[1].Emission
, params
);
874 if (bitmask
& FRONT_SHININESS_BIT
) {
875 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
876 mat
[0].Shininess
= shininess
;
878 if (bitmask
& BACK_SHININESS_BIT
) {
879 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
880 mat
[1].Shininess
= shininess
;
882 if (bitmask
& FRONT_INDEXES_BIT
) {
883 mat
[0].AmbientIndex
= params
[0];
884 mat
[0].DiffuseIndex
= params
[1];
885 mat
[0].SpecularIndex
= params
[2];
887 if (bitmask
& BACK_INDEXES_BIT
) {
888 mat
[1].AmbientIndex
= params
[0];
889 mat
[1].DiffuseIndex
= params
[1];
890 mat
[1].SpecularIndex
= params
[2];
896 _mesa_Materiali(GLenum face
, GLenum pname
, GLint param
)
898 _mesa_Materialiv(face
, pname
, ¶m
);
903 _mesa_Materialiv(GLenum face
, GLenum pname
, const GLint
*params
)
911 case GL_AMBIENT_AND_DIFFUSE
:
912 fparam
[0] = INT_TO_FLOAT( params
[0] );
913 fparam
[1] = INT_TO_FLOAT( params
[1] );
914 fparam
[2] = INT_TO_FLOAT( params
[2] );
915 fparam
[3] = INT_TO_FLOAT( params
[3] );
918 fparam
[0] = (GLfloat
) params
[0];
920 case GL_COLOR_INDEXES
:
921 fparam
[0] = (GLfloat
) params
[0];
922 fparam
[1] = (GLfloat
) params
[1];
923 fparam
[2] = (GLfloat
) params
[2];
926 /* Error will be caught later in gl_Materialfv */
929 _mesa_Materialfv(face
, pname
, fparam
);
934 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
936 GET_CURRENT_CONTEXT(ctx
);
939 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialfv");
941 if (face
==GL_FRONT
) {
944 else if (face
==GL_BACK
) {
948 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
953 COPY_4FV( params
, ctx
->Light
.Material
[f
].Ambient
);
956 COPY_4FV( params
, ctx
->Light
.Material
[f
].Diffuse
);
959 COPY_4FV( params
, ctx
->Light
.Material
[f
].Specular
);
962 COPY_4FV( params
, ctx
->Light
.Material
[f
].Emission
);
965 *params
= ctx
->Light
.Material
[f
].Shininess
;
967 case GL_COLOR_INDEXES
:
968 params
[0] = ctx
->Light
.Material
[f
].AmbientIndex
;
969 params
[1] = ctx
->Light
.Material
[f
].DiffuseIndex
;
970 params
[2] = ctx
->Light
.Material
[f
].SpecularIndex
;
973 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
980 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
982 GET_CURRENT_CONTEXT(ctx
);
985 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialiv");
987 if (face
==GL_FRONT
) {
990 else if (face
==GL_BACK
) {
994 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
999 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[0] );
1000 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[1] );
1001 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[2] );
1002 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[3] );
1005 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[0] );
1006 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[1] );
1007 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[2] );
1008 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[3] );
1011 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[0] );
1012 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[1] );
1013 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[2] );
1014 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[3] );
1017 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[0] );
1018 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[1] );
1019 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[2] );
1020 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[3] );
1023 *params
= ROUNDF( ctx
->Light
.Material
[f
].Shininess
);
1025 case GL_COLOR_INDEXES
:
1026 params
[0] = ROUNDF( ctx
->Light
.Material
[f
].AmbientIndex
);
1027 params
[1] = ROUNDF( ctx
->Light
.Material
[f
].DiffuseIndex
);
1028 params
[2] = ROUNDF( ctx
->Light
.Material
[f
].SpecularIndex
);
1031 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
1038 /**********************************************************************/
1039 /***** Lighting computation *****/
1040 /**********************************************************************/
1045 * When two-sided lighting is enabled we compute the color (or index)
1046 * for both the front and back side of the primitive. Then, when the
1047 * orientation of the facet is later learned, we can determine which
1048 * color (or index) to use for rendering.
1050 * KW: We now know orientation in advance and only shade for
1051 * the side or sides which are actually required.
1055 * V = vertex position
1056 * P = light source position
1061 * // light at infinity
1062 * IF local_viewer THEN
1063 * VP_inf_norm = unit vector from V to P // Precompute
1065 * // eye at infinity
1066 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1071 * Normalize( v ) = normalized vector v
1072 * Magnitude( v ) = length of vector v
1078 * Whenever the spotlight exponent for a light changes we must call
1079 * this function to recompute the exponent lookup table.
1081 void gl_compute_spot_exp_table( struct gl_light
*l
)
1084 double exponent
= l
->SpotExponent
;
1088 l
->SpotExpTable
[0][0] = 0.0;
1090 for (i
=EXP_TABLE_SIZE
-1;i
>0;i
--) {
1092 tmp
= pow(i
/(double)(EXP_TABLE_SIZE
-1), exponent
);
1093 if (tmp
< FLT_MIN
*100.0) {
1098 l
->SpotExpTable
[i
][0] = tmp
;
1100 for (i
=0;i
<EXP_TABLE_SIZE
-1;i
++) {
1101 l
->SpotExpTable
[i
][1] = l
->SpotExpTable
[i
+1][0] - l
->SpotExpTable
[i
][0];
1103 l
->SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
1109 /* Calculate a new shine table. Doing this here saves a branch in
1110 * lighting, and the cost of doing it early may be partially offset
1111 * by keeping a MRU cache of shine tables for various shine values.
1113 static void compute_shine_table( struct gl_shine_tab
*tab
, GLfloat shininess
)
1116 GLfloat
*m
= tab
->tab
;
1119 if (shininess
== 0) {
1120 for (i
= 1 ; i
<= SHINE_TABLE_SIZE
; i
++)
1123 for (i
= 1 ; i
<= SHINE_TABLE_SIZE
; i
++) {
1124 double t
= pow( i
/(GLfloat
)SHINE_TABLE_SIZE
, shininess
);
1126 if (t
> 1e-20) m
[i
] = t
;
1130 tab
->shininess
= shininess
;
1133 #define DISTSQR(a,b) ((a-b)*(a-b))
1135 void gl_compute_shine_table( GLcontext
*ctx
, GLuint i
, GLfloat shininess
)
1137 struct gl_shine_tab
*list
= ctx
->ShineTabList
;
1138 struct gl_shine_tab
*s
;
1141 if ( DISTSQR(s
->shininess
, shininess
) < 1e-4 )
1147 if (s
->refcount
== 0) break;
1149 compute_shine_table( s
, shininess
);
1152 ctx
->ShineTable
[i
]->refcount
--;
1153 ctx
->ShineTable
[i
] = s
;
1154 move_to_tail( list
, s
);
1161 void gl_reinit_light_attrib( GLcontext
*ctx
, struct gl_light_attrib
*l
)
1165 if (ctx
->ShineTable
[0]->shininess
!= l
->Material
[0].Shininess
) {
1166 gl_compute_shine_table( ctx
, 0, l
->Material
[0].Shininess
);
1167 gl_compute_shine_table( ctx
, 2, l
->Material
[0].Shininess
* .5 );
1170 if (ctx
->ShineTable
[1]->shininess
!= l
->Material
[1].Shininess
) {
1171 gl_compute_shine_table( ctx
, 1, l
->Material
[1].Shininess
);
1172 gl_compute_shine_table( ctx
, 3, l
->Material
[1].Shininess
* .5 );
1175 make_empty_list( &l
->EnabledList
);
1176 for (i
= 0 ; i
< MAX_LIGHTS
; i
++) {
1177 if (l
->Light
[i
].Enabled
)
1178 insert_at_tail( &l
->EnabledList
, &l
->Light
[i
] );
1185 * Examine current lighting parameters to determine if the optimized lighting
1186 * function can be used.
1187 * Also, precompute some lighting values such as the products of light
1188 * source and material ambient, diffuse and specular coefficients.
1190 void gl_update_lighting( GLcontext
*ctx
)
1192 struct gl_light
*light
;
1194 ctx
->Light
.Flags
= 0;
1196 foreach(light
, &ctx
->Light
.EnabledList
) {
1200 if (light
->EyePosition
[3] != 0.0F
)
1201 light
->Flags
|= LIGHT_POSITIONAL
;
1203 if (LEN_SQUARED_3FV(light
->Specular
) > 1e-16)
1204 light
->Flags
|= LIGHT_SPECULAR
;
1206 if (light
->SpotCutoff
!= 180.0F
)
1207 light
->Flags
|= LIGHT_SPOT
;
1209 ctx
->Light
.Flags
|= light
->Flags
;
1212 ctx
->Light
.NeedVertices
=
1213 ((ctx
->Light
.Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1214 (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) ||
1215 (ctx
->Light
.Model
.LocalViewer
&& (ctx
->Light
.Flags
& LIGHT_SPECULAR
)));
1218 /* Precompute some shading values.
1220 if (ctx
->Visual
->RGBAflag
)
1222 GLuint sides
= ((ctx
->TriangleCaps
& DD_TRI_LIGHT_TWOSIDE
) ? 2 : 1);
1224 for (side
=0; side
< sides
; side
++) {
1225 struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1227 COPY_3V(ctx
->Light
.BaseColor
[side
], mat
->Emission
);
1228 ACC_SCALE_3V(ctx
->Light
.BaseColor
[side
],
1229 ctx
->Light
.Model
.Ambient
,
1232 FLOAT_COLOR_TO_UBYTE_COLOR(ctx
->Light
.BaseAlpha
[side
],
1233 ctx
->Light
.Material
[side
].Diffuse
[3] );
1236 foreach (light
, &ctx
->Light
.EnabledList
) {
1237 for (side
=0; side
< sides
; side
++) {
1238 struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1239 SCALE_3V( light
->MatDiffuse
[side
], light
->Diffuse
, mat
->Diffuse
);
1240 SCALE_3V( light
->MatAmbient
[side
], light
->Ambient
, mat
->Ambient
);
1241 ACC_3V( ctx
->Light
.BaseColor
[side
], light
->MatAmbient
[side
] );
1242 if (light
->Flags
& LIGHT_SPECULAR
)
1244 SCALE_3V( light
->MatSpecular
[side
], light
->Specular
,
1246 light
->IsMatSpecular
[side
] =
1247 (LEN_SQUARED_3FV(light
->MatSpecular
[side
]) > 1e-16);
1250 light
->IsMatSpecular
[side
] = 0;
1256 static GLfloat ci
[3] = { .30, .59, .11 };
1258 foreach(light
, &ctx
->Light
.EnabledList
) {
1259 light
->dli
= DOT3(ci
, light
->Diffuse
);
1260 light
->sli
= DOT3(ci
, light
->Specular
);
1265 /* Need to seriously restrict the circumstances under which these
1266 * calc's are performed.
1268 void gl_compute_light_positions( GLcontext
*ctx
)
1270 struct gl_light
*light
;
1272 if (ctx
->Light
.NeedVertices
&& !ctx
->Light
.Model
.LocalViewer
) {
1273 GLfloat eye_z
[3] = { 0, 0, 1 };
1274 if (!ctx
->NeedEyeCoords
) {
1275 TRANSFORM_NORMAL( ctx
->EyeZDir
, eye_z
, ctx
->ModelView
.m
);
1277 COPY_3V( ctx
->EyeZDir
, eye_z
);
1281 foreach (light
, &ctx
->Light
.EnabledList
) {
1283 if (!ctx
->NeedEyeCoords
) {
1284 TRANSFORM_POINT( light
->Position
, ctx
->ModelView
.inv
,
1285 light
->EyePosition
);
1287 COPY_4FV( light
->Position
, light
->EyePosition
);
1290 if (!(light
->Flags
& LIGHT_POSITIONAL
))
1292 /* VP (VP) = Normalize( Position ) */
1293 COPY_3V( light
->VP_inf_norm
, light
->Position
);
1294 NORMALIZE_3FV( light
->VP_inf_norm
);
1296 if (!ctx
->Light
.Model
.LocalViewer
)
1298 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1299 ADD_3V( light
->h_inf_norm
, light
->VP_inf_norm
, ctx
->EyeZDir
);
1300 NORMALIZE_3FV( light
->h_inf_norm
);
1303 light
->VP_inf_spot_attenuation
= 1.0;
1306 if (light
->Flags
& LIGHT_SPOT
)
1308 if (ctx
->NeedEyeNormals
) {
1309 COPY_3V( light
->NormDirection
, light
->EyeDirection
);
1311 TRANSFORM_NORMAL( light
->NormDirection
,
1312 light
->EyeDirection
,
1316 NORMALIZE_3FV( light
->NormDirection
);
1319 /* Unlikely occurrance?
1321 if (!(light
->Flags
& LIGHT_POSITIONAL
)) {
1322 GLfloat PV_dot_dir
= - DOT3(light
->VP_inf_norm
,
1323 light
->NormDirection
);
1325 if (PV_dot_dir
> light
->CosCutoff
) {
1326 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1328 light
->VP_inf_spot_attenuation
=
1329 (light
->SpotExpTable
[k
][0] +
1330 (x
-k
)*light
->SpotExpTable
[k
][1]);
1333 light
->VP_inf_spot_attenuation
= 0;
1343 void gl_update_normal_transform( GLcontext
*ctx
)
1345 GLuint new_flag
= 0;
1346 normal_func
*last
= ctx
->NormalTransform
;
1348 ctx
->vb_rescale_factor
= 1.0;
1350 if (ctx
->NeedEyeCoords
) {
1351 if (ctx
->NeedNormals
) {
1352 GLuint transform
= NORM_TRANSFORM_NO_ROT
;
1354 if (ctx
->ModelView
.flags
& (MAT_FLAG_GENERAL
|
1356 MAT_FLAG_GENERAL_3D
|
1357 MAT_FLAG_PERSPECTIVE
))
1358 transform
= NORM_TRANSFORM
;
1361 new_flag
= ctx
->NewState
& NEW_MODELVIEW
;
1362 ctx
->vb_rescale_factor
= ctx
->rescale_factor
;
1364 if (ctx
->Transform
.Normalize
)
1366 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_NORMALIZE
];
1368 else if (ctx
->Transform
.RescaleNormals
&&
1369 ctx
->rescale_factor
!= 1.0)
1371 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_RESCALE
];
1375 ctx
->NormalTransform
= gl_normal_tab
[transform
];
1378 ctx
->NormalTransform
= 0;
1382 if (ctx
->NeedNormals
) {
1383 ctx
->vb_rescale_factor
= 1.0/ctx
->rescale_factor
;
1385 if (ctx
->Transform
.Normalize
)
1387 ctx
->NormalTransform
= gl_normal_tab
[NORM_NORMALIZE
];
1389 else if (!ctx
->Transform
.RescaleNormals
&&
1390 ctx
->rescale_factor
!= 1.0)
1392 ctx
->NormalTransform
= gl_normal_tab
[NORM_RESCALE
];
1396 ctx
->NormalTransform
= 0;
1399 ctx
->NormalTransform
= 0;
1403 if (last
!= ctx
->NormalTransform
|| new_flag
)
1404 ctx
->NewState
|= NEW_NORMAL_TRANSFORM
;