1 /* $Id: light.c,v 1.22 2000/10/30 13:32:00 keithw 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.
40 #include "simple_list.h"
47 /* XXX this is a bit of a hack needed for compilation within XFree86 */
54 _mesa_ShadeModel( GLenum mode
)
56 GET_CURRENT_CONTEXT(ctx
);
57 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glShadeModel");
59 if (MESA_VERBOSE
& VERBOSE_API
)
60 fprintf(stderr
, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode
));
62 if (mode
== GL_FLAT
|| mode
== GL_SMOOTH
) {
63 if (ctx
->Light
.ShadeModel
!= mode
) {
64 ctx
->Light
.ShadeModel
= mode
;
65 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
66 SET_BITS(ctx
->TriangleCaps
, DD_FLATSHADE
);
68 CLEAR_BITS(ctx
->TriangleCaps
, DD_FLATSHADE
);
70 ctx
->NewState
|= _NEW_LIGHT
;
72 if (ctx
->Driver
.ShadeModel
)
73 (*ctx
->Driver
.ShadeModel
)( ctx
, mode
);
77 gl_error( ctx
, GL_INVALID_ENUM
, "glShadeModel" );
84 _mesa_Lightf( GLenum light
, GLenum pname
, GLfloat param
)
86 _mesa_Lightfv( light
, pname
, ¶m
);
91 _mesa_Lightfv( GLenum light
, GLenum pname
, const GLfloat
*params
)
93 GET_CURRENT_CONTEXT(ctx
);
97 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLight");
99 l
= (GLint
) (light
- GL_LIGHT0
);
101 if (l
< 0 || l
>= MAX_LIGHTS
) {
102 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
108 COPY_4V( ctx
->Light
.Light
[l
].Ambient
, params
);
112 COPY_4V( ctx
->Light
.Light
[l
].Diffuse
, params
);
116 COPY_4V( ctx
->Light
.Light
[l
].Specular
, params
);
120 /* transform position by ModelView matrix */
121 TRANSFORM_POINT( ctx
->Light
.Light
[l
].EyePosition
,
126 case GL_SPOT_DIRECTION
:
127 /* transform direction by inverse modelview */
128 if (ctx
->ModelView
.flags
& MAT_DIRTY_INVERSE
) {
129 gl_matrix_analyze( &ctx
->ModelView
);
131 TRANSFORM_NORMAL( ctx
->Light
.Light
[l
].EyeDirection
,
133 ctx
->ModelView
.inv
);
136 case GL_SPOT_EXPONENT
:
137 if (params
[0]<0.0 || params
[0]>128.0) {
138 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
141 if (ctx
->Light
.Light
[l
].SpotExponent
!= params
[0]) {
142 ctx
->Light
.Light
[l
].SpotExponent
= params
[0];
143 gl_compute_spot_exp_table( &ctx
->Light
.Light
[l
] );
148 if ((params
[0]<0.0 || params
[0]>90.0) && params
[0]!=180.0) {
149 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
152 ctx
->Light
.Light
[l
].SpotCutoff
= params
[0];
153 ctx
->Light
.Light
[l
].CosCutoff
= cos(params
[0]*DEG2RAD
);
154 if (ctx
->Light
.Light
[l
].CosCutoff
< 0)
155 ctx
->Light
.Light
[l
].CosCutoff
= 0;
158 case GL_CONSTANT_ATTENUATION
:
160 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
163 ctx
->Light
.Light
[l
].ConstantAttenuation
= params
[0];
166 case GL_LINEAR_ATTENUATION
:
168 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
171 ctx
->Light
.Light
[l
].LinearAttenuation
= params
[0];
174 case GL_QUADRATIC_ATTENUATION
:
176 gl_error( ctx
, GL_INVALID_VALUE
, "glLight" );
179 ctx
->Light
.Light
[l
].QuadraticAttenuation
= params
[0];
183 gl_error( ctx
, GL_INVALID_ENUM
, "glLight" );
187 if (ctx
->Driver
.Lightfv
)
188 ctx
->Driver
.Lightfv( ctx
, light
, pname
, params
, nParams
);
190 ctx
->NewState
|= _NEW_LIGHT
;
195 _mesa_Lighti( GLenum light
, GLenum pname
, GLint param
)
197 _mesa_Lightiv( light
, pname
, ¶m
);
202 _mesa_Lightiv( GLenum light
, GLenum pname
, const GLint
*params
)
210 fparam
[0] = INT_TO_FLOAT( params
[0] );
211 fparam
[1] = INT_TO_FLOAT( params
[1] );
212 fparam
[2] = INT_TO_FLOAT( params
[2] );
213 fparam
[3] = INT_TO_FLOAT( params
[3] );
216 fparam
[0] = (GLfloat
) params
[0];
217 fparam
[1] = (GLfloat
) params
[1];
218 fparam
[2] = (GLfloat
) params
[2];
219 fparam
[3] = (GLfloat
) params
[3];
221 case GL_SPOT_DIRECTION
:
222 fparam
[0] = (GLfloat
) params
[0];
223 fparam
[1] = (GLfloat
) params
[1];
224 fparam
[2] = (GLfloat
) params
[2];
226 case GL_SPOT_EXPONENT
:
228 case GL_CONSTANT_ATTENUATION
:
229 case GL_LINEAR_ATTENUATION
:
230 case GL_QUADRATIC_ATTENUATION
:
231 fparam
[0] = (GLfloat
) params
[0];
234 /* error will be caught later in gl_Lightfv */
238 _mesa_Lightfv( light
, pname
, fparam
);
244 _mesa_GetLightfv( GLenum light
, GLenum pname
, GLfloat
*params
)
246 GET_CURRENT_CONTEXT(ctx
);
247 GLint l
= (GLint
) (light
- GL_LIGHT0
);
249 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
251 if (l
<0 || l
>=MAX_LIGHTS
) {
252 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
258 COPY_4V( params
, ctx
->Light
.Light
[l
].Ambient
);
261 COPY_4V( params
, ctx
->Light
.Light
[l
].Diffuse
);
264 COPY_4V( params
, ctx
->Light
.Light
[l
].Specular
);
267 COPY_4V( params
, ctx
->Light
.Light
[l
].EyePosition
);
269 case GL_SPOT_DIRECTION
:
270 COPY_3V( params
, ctx
->Light
.Light
[l
].EyeDirection
);
272 case GL_SPOT_EXPONENT
:
273 params
[0] = ctx
->Light
.Light
[l
].SpotExponent
;
276 params
[0] = ctx
->Light
.Light
[l
].SpotCutoff
;
278 case GL_CONSTANT_ATTENUATION
:
279 params
[0] = ctx
->Light
.Light
[l
].ConstantAttenuation
;
281 case GL_LINEAR_ATTENUATION
:
282 params
[0] = ctx
->Light
.Light
[l
].LinearAttenuation
;
284 case GL_QUADRATIC_ATTENUATION
:
285 params
[0] = ctx
->Light
.Light
[l
].QuadraticAttenuation
;
288 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightfv" );
296 _mesa_GetLightiv( GLenum light
, GLenum pname
, GLint
*params
)
298 GET_CURRENT_CONTEXT(ctx
);
299 GLint l
= (GLint
) (light
- GL_LIGHT0
);
301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetLight");
303 if (l
<0 || l
>=MAX_LIGHTS
) {
304 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
310 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[0]);
311 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[1]);
312 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[2]);
313 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Ambient
[3]);
316 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[0]);
317 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[1]);
318 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[2]);
319 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Diffuse
[3]);
322 params
[0] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[0]);
323 params
[1] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[1]);
324 params
[2] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[2]);
325 params
[3] = FLOAT_TO_INT(ctx
->Light
.Light
[l
].Specular
[3]);
328 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[0];
329 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[1];
330 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[2];
331 params
[3] = (GLint
) ctx
->Light
.Light
[l
].EyePosition
[3];
333 case GL_SPOT_DIRECTION
:
334 params
[0] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[0];
335 params
[1] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[1];
336 params
[2] = (GLint
) ctx
->Light
.Light
[l
].EyeDirection
[2];
338 case GL_SPOT_EXPONENT
:
339 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotExponent
;
342 params
[0] = (GLint
) ctx
->Light
.Light
[l
].SpotCutoff
;
344 case GL_CONSTANT_ATTENUATION
:
345 params
[0] = (GLint
) ctx
->Light
.Light
[l
].ConstantAttenuation
;
347 case GL_LINEAR_ATTENUATION
:
348 params
[0] = (GLint
) ctx
->Light
.Light
[l
].LinearAttenuation
;
350 case GL_QUADRATIC_ATTENUATION
:
351 params
[0] = (GLint
) ctx
->Light
.Light
[l
].QuadraticAttenuation
;
354 gl_error( ctx
, GL_INVALID_ENUM
, "glGetLightiv" );
361 /**********************************************************************/
362 /*** Light Model ***/
363 /**********************************************************************/
367 _mesa_LightModelfv( GLenum pname
, const GLfloat
*params
)
369 GET_CURRENT_CONTEXT(ctx
);
370 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModelfv");
373 case GL_LIGHT_MODEL_AMBIENT
:
374 COPY_4V( ctx
->Light
.Model
.Ambient
, params
);
376 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
378 ctx
->Light
.Model
.LocalViewer
= GL_FALSE
;
380 ctx
->Light
.Model
.LocalViewer
= GL_TRUE
;
382 case GL_LIGHT_MODEL_TWO_SIDE
:
384 ctx
->Light
.Model
.TwoSide
= GL_FALSE
;
386 ctx
->Light
.Model
.TwoSide
= GL_TRUE
;
388 case GL_LIGHT_MODEL_COLOR_CONTROL
:
389 if (params
[0] == (GLfloat
) GL_SINGLE_COLOR
) {
390 ctx
->Light
.Model
.ColorControl
= GL_SINGLE_COLOR
;
391 if (!ctx
->Fog
.ColorSumEnabled
)
392 CLEAR_BITS(ctx
->TriangleCaps
, DD_SEPERATE_SPECULAR
);
394 else if (params
[0] == (GLfloat
) GL_SEPARATE_SPECULAR_COLOR
) {
395 ctx
->Light
.Model
.ColorControl
= GL_SEPARATE_SPECULAR_COLOR
;
396 SET_BITS(ctx
->TriangleCaps
, DD_SEPERATE_SPECULAR
);
399 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel(param)" );
403 gl_error( ctx
, GL_INVALID_ENUM
, "glLightModel" );
407 if (ctx
->Driver
.LightModelfv
)
408 ctx
->Driver
.LightModelfv( ctx
, pname
, params
);
410 ctx
->NewState
|= _NEW_LIGHT
;
415 _mesa_LightModeliv( GLenum pname
, const GLint
*params
)
418 GET_CURRENT_CONTEXT(ctx
);
419 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glLightModeliv");
422 case GL_LIGHT_MODEL_AMBIENT
:
423 fparam
[0] = INT_TO_FLOAT( params
[0] );
424 fparam
[1] = INT_TO_FLOAT( params
[1] );
425 fparam
[2] = INT_TO_FLOAT( params
[2] );
426 fparam
[3] = INT_TO_FLOAT( params
[3] );
428 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
429 case GL_LIGHT_MODEL_TWO_SIDE
:
430 case GL_LIGHT_MODEL_COLOR_CONTROL
:
431 fparam
[0] = (GLfloat
) params
[0];
434 /* Error will be caught later in gl_LightModelfv */
437 _mesa_LightModelfv( pname
, fparam
);
442 _mesa_LightModeli( GLenum pname
, GLint param
)
444 _mesa_LightModeliv( pname
, ¶m
);
449 _mesa_LightModelf( GLenum pname
, GLfloat param
)
451 _mesa_LightModelfv( pname
, ¶m
);
456 /********** MATERIAL **********/
460 * Given a face and pname value (ala glColorMaterial), compute a bitmask
461 * of the targeted material values.
463 GLuint
gl_material_bitmask( GLcontext
*ctx
, GLenum face
, GLenum pname
,
469 /* Make a bitmask indicating what material attribute(s) we're updating */
472 bitmask
|= FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
;
475 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
478 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
481 bitmask
|= FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
;
484 bitmask
|= FRONT_SHININESS_BIT
| BACK_SHININESS_BIT
;
486 case GL_AMBIENT_AND_DIFFUSE
:
487 bitmask
|= FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
;
488 bitmask
|= FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
;
490 case GL_COLOR_INDEXES
:
491 bitmask
|= FRONT_INDEXES_BIT
| BACK_INDEXES_BIT
;
494 gl_error( ctx
, GL_INVALID_ENUM
, where
);
498 if (face
==GL_FRONT
) {
499 bitmask
&= FRONT_MATERIAL_BITS
;
501 else if (face
==GL_BACK
) {
502 bitmask
&= BACK_MATERIAL_BITS
;
504 else if (face
!= GL_FRONT_AND_BACK
) {
505 gl_error( ctx
, GL_INVALID_ENUM
, where
);
509 if (bitmask
& ~legal
) {
510 gl_error( ctx
, GL_INVALID_ENUM
, where
);
520 * Check if the global material has to be updated with info that was
521 * associated with a vertex via glMaterial.
522 * This function is used when any material values get changed between
523 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
524 * when GL_COLOR_MATERIAL is enabled.
526 * src[0] is front material, src[1] is back material
528 * KW: Added code here to keep the precomputed variables uptodate.
529 * This means we can use the faster shade functions when using
530 * GL_COLOR_MATERIAL, and we can also now use the precomputed
531 * values in the slower shading functions, which further offsets
532 * the cost of doing this here.
534 void gl_update_material( GLcontext
*ctx
,
535 const struct gl_material src
[2],
538 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
540 if (ctx
->Light
.ColorMaterialEnabled
)
541 bitmask
&= ~ctx
->Light
.ColorMaterialBitmask
;
543 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
544 fprintf(stderr
, "gl_update_material, mask 0x%x\n", bitmask
);
549 /* update material emission */
550 if (bitmask
& FRONT_EMISSION_BIT
) {
551 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
552 COPY_4FV( mat
->Emission
, src
[0].Emission
);
554 if (bitmask
& BACK_EMISSION_BIT
) {
555 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
556 COPY_4FV( mat
->Emission
, src
[1].Emission
);
559 /* update material ambience */
560 if (bitmask
& FRONT_AMBIENT_BIT
) {
561 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
562 COPY_4FV( mat
->Ambient
, src
[0].Ambient
);
563 foreach (light
, list
) {
564 SCALE_3V( light
->MatAmbient
[0], light
->Ambient
, src
[0].Ambient
);
567 if (bitmask
& BACK_AMBIENT_BIT
) {
568 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
569 COPY_4FV( mat
->Ambient
, src
[1].Ambient
);
570 foreach (light
, list
) {
571 SCALE_3V( light
->MatAmbient
[1], light
->Ambient
, src
[1].Ambient
);
575 /* update BaseColor = emission + scene's ambience * material's ambience */
576 if (bitmask
& (FRONT_EMISSION_BIT
| FRONT_AMBIENT_BIT
)) {
577 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
578 COPY_3V( ctx
->Light
.BaseColor
[0], mat
->Emission
);
579 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
581 if (bitmask
& (BACK_EMISSION_BIT
| BACK_AMBIENT_BIT
)) {
582 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
583 COPY_3V( ctx
->Light
.BaseColor
[1], mat
->Emission
);
584 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
587 /* update material diffuse values */
588 if (bitmask
& FRONT_DIFFUSE_BIT
) {
589 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
591 SUB_3V( tmp
, src
[0].Diffuse
, mat
->Diffuse
);
592 foreach (light
, list
) {
593 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
595 COPY_4FV( mat
->Diffuse
, src
[0].Diffuse
);
596 FLOAT_COLOR_TO_CHAN(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
598 if (bitmask
& BACK_DIFFUSE_BIT
) {
599 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
601 SUB_3V( tmp
, src
[1].Diffuse
, mat
->Diffuse
);
602 foreach (light
, list
) {
603 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
605 COPY_4FV( mat
->Diffuse
, src
[1].Diffuse
);
606 FLOAT_COLOR_TO_CHAN(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
609 /* update material specular values */
610 if (bitmask
& FRONT_SPECULAR_BIT
) {
611 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
613 SUB_3V( tmp
, src
[0].Specular
, mat
->Specular
);
614 foreach (light
, list
) {
615 if (light
->Flags
& LIGHT_SPECULAR
) {
616 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
617 light
->IsMatSpecular
[0] =
618 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
621 COPY_4FV( mat
->Specular
, src
[0].Specular
);
623 if (bitmask
& BACK_SPECULAR_BIT
) {
624 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
626 SUB_3V( tmp
, src
[1].Specular
, mat
->Specular
);
627 foreach (light
, list
) {
628 if (light
->Flags
& LIGHT_SPECULAR
) {
629 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
630 light
->IsMatSpecular
[1] =
631 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
634 COPY_4FV( mat
->Specular
, src
[1].Specular
);
637 if (bitmask
& FRONT_SHININESS_BIT
) {
638 GLfloat shininess
= ctx
->Light
.Material
[0].Shininess
= src
[0].Shininess
;
639 gl_compute_shine_table( ctx
, 0, shininess
);
640 gl_compute_shine_table( ctx
, 2, shininess
* .5 );
642 if (bitmask
& BACK_SHININESS_BIT
) {
643 GLfloat shininess
= ctx
->Light
.Material
[1].Shininess
= src
[1].Shininess
;
644 gl_compute_shine_table( ctx
, 1, shininess
);
645 gl_compute_shine_table( ctx
, 3, shininess
* .5 );
648 if (bitmask
& FRONT_INDEXES_BIT
) {
649 ctx
->Light
.Material
[0].AmbientIndex
= src
[0].AmbientIndex
;
650 ctx
->Light
.Material
[0].DiffuseIndex
= src
[0].DiffuseIndex
;
651 ctx
->Light
.Material
[0].SpecularIndex
= src
[0].SpecularIndex
;
653 if (bitmask
& BACK_INDEXES_BIT
) {
654 ctx
->Light
.Material
[1].AmbientIndex
= src
[1].AmbientIndex
;
655 ctx
->Light
.Material
[1].DiffuseIndex
= src
[1].DiffuseIndex
;
656 ctx
->Light
.Material
[1].SpecularIndex
= src
[1].SpecularIndex
;
661 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
662 fprintf(stderr
, "update_mat emission : %f %f %f\n",
666 fprintf(stderr
, "update_mat specular : %f %f %f\n",
670 fprintf(stderr
, "update_mat diffuse : %f %f %f\n",
674 fprintf(stderr
, "update_mat ambient : %f %f %f\n",
685 * Update the current materials from the given rgba color
686 * according to the bitmask in ColorMaterialBitmask, which is
687 * set by glColorMaterial().
689 void gl_update_color_material( GLcontext
*ctx
,
690 const GLchan rgba
[4] )
692 struct gl_light
*light
, *list
= &ctx
->Light
.EnabledList
;
693 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
696 color
[0] = CHAN_TO_FLOAT(rgba
[0]);
697 color
[1] = CHAN_TO_FLOAT(rgba
[1]);
698 color
[2] = CHAN_TO_FLOAT(rgba
[2]);
699 color
[3] = CHAN_TO_FLOAT(rgba
[3]);
701 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
702 fprintf(stderr
, "gl_update_color_material, mask 0x%x\n", bitmask
);
704 /* update emissive colors */
705 if (bitmask
& FRONT_EMISSION_BIT
) {
706 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
707 COPY_4FV( mat
->Emission
, color
);
710 if (bitmask
& BACK_EMISSION_BIT
) {
711 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
712 COPY_4FV( mat
->Emission
, color
);
715 /* update light->MatAmbient = light's ambient * material's ambient */
716 if (bitmask
& FRONT_AMBIENT_BIT
) {
717 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
718 foreach (light
, list
) {
719 SCALE_3V( light
->MatAmbient
[0], light
->Ambient
, color
);
721 COPY_4FV( mat
->Ambient
, color
);
724 if (bitmask
& BACK_AMBIENT_BIT
) {
725 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
726 foreach (light
, list
) {
727 SCALE_3V( light
->MatAmbient
[1], light
->Ambient
, color
);
729 COPY_4FV( mat
->Ambient
, color
);
732 /* update BaseColor = emission + scene's ambience * material's ambience */
733 if (bitmask
& (FRONT_EMISSION_BIT
| FRONT_AMBIENT_BIT
)) {
734 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
735 COPY_3V( ctx
->Light
.BaseColor
[0], mat
->Emission
);
736 ACC_SCALE_3V( ctx
->Light
.BaseColor
[0], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
739 if (bitmask
& (BACK_EMISSION_BIT
| BACK_AMBIENT_BIT
)) {
740 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
741 COPY_3V( ctx
->Light
.BaseColor
[1], mat
->Emission
);
742 ACC_SCALE_3V( ctx
->Light
.BaseColor
[1], mat
->Ambient
, ctx
->Light
.Model
.Ambient
);
745 /* update light->MatDiffuse = light's diffuse * material's diffuse */
746 if (bitmask
& FRONT_DIFFUSE_BIT
) {
747 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
749 SUB_3V( tmp
, color
, mat
->Diffuse
);
750 foreach (light
, list
) {
751 ACC_SCALE_3V( light
->MatDiffuse
[0], light
->Diffuse
, tmp
);
753 COPY_4FV( mat
->Diffuse
, color
);
754 FLOAT_COLOR_TO_CHAN(ctx
->Light
.BaseAlpha
[0], mat
->Diffuse
[3]);
757 if (bitmask
& BACK_DIFFUSE_BIT
) {
758 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
760 SUB_3V( tmp
, color
, mat
->Diffuse
);
761 foreach (light
, list
) {
762 ACC_SCALE_3V( light
->MatDiffuse
[1], light
->Diffuse
, tmp
);
764 COPY_4FV( mat
->Diffuse
, color
);
765 FLOAT_COLOR_TO_CHAN(ctx
->Light
.BaseAlpha
[1], mat
->Diffuse
[3]);
768 /* update light->MatSpecular = light's specular * material's specular */
769 if (bitmask
& FRONT_SPECULAR_BIT
) {
770 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
772 SUB_3V( tmp
, color
, mat
->Specular
);
773 foreach (light
, list
) {
774 if (light
->Flags
& LIGHT_SPECULAR
) {
775 ACC_SCALE_3V( light
->MatSpecular
[0], light
->Specular
, tmp
);
776 light
->IsMatSpecular
[0] =
777 (LEN_SQUARED_3FV(light
->MatSpecular
[0]) > 1e-16);
780 COPY_4FV( mat
->Specular
, color
);
783 if (bitmask
& BACK_SPECULAR_BIT
) {
784 struct gl_material
*mat
= &ctx
->Light
.Material
[1];
786 SUB_3V( tmp
, color
, mat
->Specular
);
787 foreach (light
, list
) {
788 if (light
->Flags
& LIGHT_SPECULAR
) {
789 ACC_SCALE_3V( light
->MatSpecular
[1], light
->Specular
, tmp
);
790 light
->IsMatSpecular
[1] =
791 (LEN_SQUARED_3FV(light
->MatSpecular
[1]) > 1e-16);
794 COPY_4FV( mat
->Specular
, color
);
799 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
800 fprintf(stderr
, "update_color_mat emission : %f %f %f\n",
804 fprintf(stderr
, "update_color_mat specular : %f %f %f\n",
808 fprintf(stderr
, "update_color_mat diffuse : %f %f %f\n",
812 fprintf(stderr
, "update_color_mat ambient : %f %f %f\n",
823 _mesa_ColorMaterial( GLenum face
, GLenum mode
)
825 GET_CURRENT_CONTEXT(ctx
);
827 GLuint legal
= (FRONT_EMISSION_BIT
| BACK_EMISSION_BIT
|
828 FRONT_SPECULAR_BIT
| BACK_SPECULAR_BIT
|
829 FRONT_DIFFUSE_BIT
| BACK_DIFFUSE_BIT
|
830 FRONT_AMBIENT_BIT
| BACK_AMBIENT_BIT
);
832 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glColorMaterial");
834 if (MESA_VERBOSE
&VERBOSE_API
)
835 fprintf(stderr
, "glColorMaterial %s %s\n",
836 gl_lookup_enum_by_nr(face
),
837 gl_lookup_enum_by_nr(mode
));
839 bitmask
= gl_material_bitmask( ctx
, face
, mode
, legal
, "glColorMaterial" );
842 ctx
->Light
.ColorMaterialBitmask
= bitmask
;
843 ctx
->Light
.ColorMaterialFace
= face
;
844 ctx
->Light
.ColorMaterialMode
= mode
;
847 if (ctx
->Light
.ColorMaterialEnabled
)
848 gl_update_color_material( ctx
, ctx
->Current
.Color
);
850 ctx
->NewState
|= _NEW_LIGHT
;
857 _mesa_Materialf( GLenum face
, GLenum pname
, GLfloat param
)
859 _mesa_Materialfv( face
, pname
, ¶m
);
863 /* KW: This is now called directly (ie by name) from the glMaterial*
867 _mesa_Materialfv( GLenum face
, GLenum pname
, const GLfloat
*params
)
869 GET_CURRENT_CONTEXT(ctx
);
870 struct immediate
*IM
;
871 struct gl_material
*mat
;
875 bitmask
= gl_material_bitmask( ctx
, face
, pname
, ~0, "gl_Materialfv" );
884 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material
) *
886 IM
->MaterialMask
= (GLuint
*) MALLOC( sizeof(GLuint
) * VB_SIZE
);
890 if (!(IM
->Flag
[count
] & VERT_MATERIAL
)) {
891 IM
->Flag
[count
] |= VERT_MATERIAL
;
892 IM
->MaterialMask
[count
] = 0;
896 IM
->MaterialMask
[count
] |= bitmask
;
897 mat
= IM
->Material
[count
];
899 if (bitmask
& FRONT_AMBIENT_BIT
) {
900 COPY_4FV( mat
[0].Ambient
, params
);
902 if (bitmask
& BACK_AMBIENT_BIT
) {
903 COPY_4FV( mat
[1].Ambient
, params
);
905 if (bitmask
& FRONT_DIFFUSE_BIT
) {
906 COPY_4FV( mat
[0].Diffuse
, params
);
908 if (bitmask
& BACK_DIFFUSE_BIT
) {
909 COPY_4FV( mat
[1].Diffuse
, params
);
911 if (bitmask
& FRONT_SPECULAR_BIT
) {
912 COPY_4FV( mat
[0].Specular
, params
);
914 if (bitmask
& BACK_SPECULAR_BIT
) {
915 COPY_4FV( mat
[1].Specular
, params
);
917 if (bitmask
& FRONT_EMISSION_BIT
) {
918 COPY_4FV( mat
[0].Emission
, params
);
920 if (bitmask
& BACK_EMISSION_BIT
) {
921 COPY_4FV( mat
[1].Emission
, params
);
923 if (bitmask
& FRONT_SHININESS_BIT
) {
924 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
925 mat
[0].Shininess
= shininess
;
927 if (bitmask
& BACK_SHININESS_BIT
) {
928 GLfloat shininess
= CLAMP( params
[0], 0.0F
, 128.0F
);
929 mat
[1].Shininess
= shininess
;
931 if (bitmask
& FRONT_INDEXES_BIT
) {
932 mat
[0].AmbientIndex
= params
[0];
933 mat
[0].DiffuseIndex
= params
[1];
934 mat
[0].SpecularIndex
= params
[2];
936 if (bitmask
& BACK_INDEXES_BIT
) {
937 mat
[1].AmbientIndex
= params
[0];
938 mat
[1].DiffuseIndex
= params
[1];
939 mat
[1].SpecularIndex
= params
[2];
945 _mesa_Materiali(GLenum face
, GLenum pname
, GLint param
)
947 _mesa_Materialiv(face
, pname
, ¶m
);
952 _mesa_Materialiv(GLenum face
, GLenum pname
, const GLint
*params
)
960 case GL_AMBIENT_AND_DIFFUSE
:
961 fparam
[0] = INT_TO_FLOAT( params
[0] );
962 fparam
[1] = INT_TO_FLOAT( params
[1] );
963 fparam
[2] = INT_TO_FLOAT( params
[2] );
964 fparam
[3] = INT_TO_FLOAT( params
[3] );
967 fparam
[0] = (GLfloat
) params
[0];
969 case GL_COLOR_INDEXES
:
970 fparam
[0] = (GLfloat
) params
[0];
971 fparam
[1] = (GLfloat
) params
[1];
972 fparam
[2] = (GLfloat
) params
[2];
975 /* Error will be caught later in gl_Materialfv */
978 _mesa_Materialfv(face
, pname
, fparam
);
983 _mesa_GetMaterialfv( GLenum face
, GLenum pname
, GLfloat
*params
)
985 GET_CURRENT_CONTEXT(ctx
);
988 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialfv");
990 if (face
==GL_FRONT
) {
993 else if (face
==GL_BACK
) {
997 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(face)" );
1002 COPY_4FV( params
, ctx
->Light
.Material
[f
].Ambient
);
1005 COPY_4FV( params
, ctx
->Light
.Material
[f
].Diffuse
);
1008 COPY_4FV( params
, ctx
->Light
.Material
[f
].Specular
);
1011 COPY_4FV( params
, ctx
->Light
.Material
[f
].Emission
);
1014 *params
= ctx
->Light
.Material
[f
].Shininess
;
1016 case GL_COLOR_INDEXES
:
1017 params
[0] = ctx
->Light
.Material
[f
].AmbientIndex
;
1018 params
[1] = ctx
->Light
.Material
[f
].DiffuseIndex
;
1019 params
[2] = ctx
->Light
.Material
[f
].SpecularIndex
;
1022 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
1029 _mesa_GetMaterialiv( GLenum face
, GLenum pname
, GLint
*params
)
1031 GET_CURRENT_CONTEXT(ctx
);
1034 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetMaterialiv");
1036 if (face
==GL_FRONT
) {
1039 else if (face
==GL_BACK
) {
1043 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialiv(face)" );
1048 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[0] );
1049 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[1] );
1050 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[2] );
1051 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Ambient
[3] );
1054 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[0] );
1055 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[1] );
1056 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[2] );
1057 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Diffuse
[3] );
1060 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[0] );
1061 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[1] );
1062 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[2] );
1063 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Specular
[3] );
1066 params
[0] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[0] );
1067 params
[1] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[1] );
1068 params
[2] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[2] );
1069 params
[3] = FLOAT_TO_INT( ctx
->Light
.Material
[f
].Emission
[3] );
1072 *params
= ROUNDF( ctx
->Light
.Material
[f
].Shininess
);
1074 case GL_COLOR_INDEXES
:
1075 params
[0] = ROUNDF( ctx
->Light
.Material
[f
].AmbientIndex
);
1076 params
[1] = ROUNDF( ctx
->Light
.Material
[f
].DiffuseIndex
);
1077 params
[2] = ROUNDF( ctx
->Light
.Material
[f
].SpecularIndex
);
1080 gl_error( ctx
, GL_INVALID_ENUM
, "glGetMaterialfv(pname)" );
1087 /**********************************************************************/
1088 /***** Lighting computation *****/
1089 /**********************************************************************/
1094 * When two-sided lighting is enabled we compute the color (or index)
1095 * for both the front and back side of the primitive. Then, when the
1096 * orientation of the facet is later learned, we can determine which
1097 * color (or index) to use for rendering.
1099 * KW: We now know orientation in advance and only shade for
1100 * the side or sides which are actually required.
1104 * V = vertex position
1105 * P = light source position
1110 * // light at infinity
1111 * IF local_viewer THEN
1112 * VP_inf_norm = unit vector from V to P // Precompute
1114 * // eye at infinity
1115 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1120 * Normalize( v ) = normalized vector v
1121 * Magnitude( v ) = length of vector v
1127 * Whenever the spotlight exponent for a light changes we must call
1128 * this function to recompute the exponent lookup table.
1131 gl_compute_spot_exp_table( struct gl_light
*l
)
1134 GLdouble exponent
= l
->SpotExponent
;
1138 l
->SpotExpTable
[0][0] = 0.0;
1140 for (i
= EXP_TABLE_SIZE
- 1; i
> 0 ;i
--) {
1142 tmp
= pow(i
/ (GLdouble
) (EXP_TABLE_SIZE
- 1), exponent
);
1143 if (tmp
< FLT_MIN
* 100.0) {
1148 l
->SpotExpTable
[i
][0] = tmp
;
1150 for (i
= 0; i
< EXP_TABLE_SIZE
- 1; i
++) {
1151 l
->SpotExpTable
[i
][1] = l
->SpotExpTable
[i
+1][0] - l
->SpotExpTable
[i
][0];
1153 l
->SpotExpTable
[EXP_TABLE_SIZE
-1][1] = 0.0;
1159 /* Calculate a new shine table. Doing this here saves a branch in
1160 * lighting, and the cost of doing it early may be partially offset
1161 * by keeping a MRU cache of shine tables for various shine values.
1164 compute_shine_table( struct gl_shine_tab
*tab
, GLfloat shininess
)
1167 GLfloat
*m
= tab
->tab
;
1170 if (shininess
== 0.0) {
1171 for (i
= 1 ; i
<= SHINE_TABLE_SIZE
; i
++)
1175 for (i
= 1 ; i
< SHINE_TABLE_SIZE
; i
++) {
1176 GLdouble t
= pow(i
/ (GLfloat
) (SHINE_TABLE_SIZE
- 1), shininess
);
1182 m
[SHINE_TABLE_SIZE
] = 1.0;
1185 tab
->shininess
= shininess
;
1190 gl_compute_shine_table( GLcontext
*ctx
, GLuint i
, GLfloat shininess
)
1192 #define DISTSQR(a,b) ((a-b)*(a-b))
1193 struct gl_shine_tab
*list
= ctx
->ShineTabList
;
1194 struct gl_shine_tab
*s
;
1197 if ( DISTSQR(s
->shininess
, shininess
) < 1e-4 )
1202 if (s
->refcount
== 0)
1205 compute_shine_table( s
, shininess
);
1208 ctx
->ShineTable
[i
]->refcount
--;
1209 ctx
->ShineTable
[i
] = s
;
1210 move_to_tail( list
, s
);
1219 * Examine current lighting parameters to determine if the optimized lighting
1220 * function can be used.
1221 * Also, precompute some lighting values such as the products of light
1222 * source and material ambient, diffuse and specular coefficients.
1225 gl_update_lighting( GLcontext
*ctx
)
1227 struct gl_light
*light
;
1229 ctx
->Light
.Flags
= 0;
1231 foreach(light
, &ctx
->Light
.EnabledList
) {
1235 if (light
->EyePosition
[3] != 0.0F
)
1236 light
->Flags
|= LIGHT_POSITIONAL
;
1238 if (LEN_SQUARED_3FV(light
->Specular
) > 1e-16)
1239 light
->Flags
|= LIGHT_SPECULAR
;
1241 if (light
->SpotCutoff
!= 180.0F
)
1242 light
->Flags
|= LIGHT_SPOT
;
1244 ctx
->Light
.Flags
|= light
->Flags
;
1247 ctx
->Light
.NeedVertices
=
1248 ((ctx
->Light
.Flags
& (LIGHT_POSITIONAL
|LIGHT_SPOT
)) ||
1249 (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) ||
1250 (ctx
->Light
.Model
.LocalViewer
&& (ctx
->Light
.Flags
& LIGHT_SPECULAR
)));
1253 /* Precompute some shading values.
1255 if (ctx
->Visual
.RGBAflag
) {
1256 GLuint sides
= ((ctx
->TriangleCaps
& DD_TRI_LIGHT_TWOSIDE
) ? 2 : 1);
1258 for (side
=0; side
< sides
; side
++) {
1259 struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1261 COPY_3V(ctx
->Light
.BaseColor
[side
], mat
->Emission
);
1262 ACC_SCALE_3V(ctx
->Light
.BaseColor
[side
],
1263 ctx
->Light
.Model
.Ambient
,
1266 FLOAT_COLOR_TO_CHAN(ctx
->Light
.BaseAlpha
[side
],
1267 ctx
->Light
.Material
[side
].Diffuse
[3] );
1270 foreach (light
, &ctx
->Light
.EnabledList
) {
1271 for (side
=0; side
< sides
; side
++) {
1272 const struct gl_material
*mat
= &ctx
->Light
.Material
[side
];
1273 SCALE_3V( light
->MatDiffuse
[side
], light
->Diffuse
, mat
->Diffuse
);
1274 SCALE_3V( light
->MatAmbient
[side
], light
->Ambient
, mat
->Ambient
);
1275 if (light
->Flags
& LIGHT_SPECULAR
) {
1276 SCALE_3V( light
->MatSpecular
[side
], light
->Specular
,
1278 light
->IsMatSpecular
[side
] =
1279 (LEN_SQUARED_3FV(light
->MatSpecular
[side
]) > 1e-16);
1282 light
->IsMatSpecular
[side
] = 0;
1287 static const GLfloat ci
[3] = { .30, .59, .11 };
1288 foreach(light
, &ctx
->Light
.EnabledList
) {
1289 light
->dli
= DOT3(ci
, light
->Diffuse
);
1290 light
->sli
= DOT3(ci
, light
->Specular
);
1297 /* Need to seriously restrict the circumstances under which these
1298 * calc's are performed.
1301 gl_compute_light_positions( GLcontext
*ctx
)
1303 struct gl_light
*light
;
1305 if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) {
1306 static const GLfloat eye_z
[3] = { 0, 0, 1 };
1307 if (ctx
->NeedEyeCoords
) {
1308 COPY_3V( ctx
->EyeZDir
, eye_z
);
1311 TRANSFORM_NORMAL( ctx
->EyeZDir
, eye_z
, ctx
->ModelView
.m
);
1315 foreach (light
, &ctx
->Light
.EnabledList
) {
1317 if (ctx
->NeedEyeCoords
) {
1318 COPY_4FV( light
->Position
, light
->EyePosition
);
1321 TRANSFORM_POINT( light
->Position
, ctx
->ModelView
.inv
,
1322 light
->EyePosition
);
1325 if (!(light
->Flags
& LIGHT_POSITIONAL
)) {
1326 /* VP (VP) = Normalize( Position ) */
1327 COPY_3V( light
->VP_inf_norm
, light
->Position
);
1328 NORMALIZE_3FV( light
->VP_inf_norm
);
1330 if (!ctx
->Light
.Model
.LocalViewer
) {
1331 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1332 ADD_3V( light
->h_inf_norm
, light
->VP_inf_norm
, ctx
->EyeZDir
);
1333 NORMALIZE_3FV( light
->h_inf_norm
);
1335 light
->VP_inf_spot_attenuation
= 1.0;
1338 if (light
->Flags
& LIGHT_SPOT
) {
1339 if (ctx
->NeedEyeNormals
) {
1340 COPY_3V( light
->NormDirection
, light
->EyeDirection
);
1343 TRANSFORM_NORMAL( light
->NormDirection
,
1344 light
->EyeDirection
,
1348 NORMALIZE_3FV( light
->NormDirection
);
1351 /* Unlikely occurrance?
1353 if (!(light
->Flags
& LIGHT_POSITIONAL
)) {
1354 GLfloat PV_dot_dir
= - DOT3(light
->VP_inf_norm
,
1355 light
->NormDirection
);
1357 if (PV_dot_dir
> light
->CosCutoff
) {
1358 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
1360 light
->VP_inf_spot_attenuation
=
1361 (light
->SpotExpTable
[k
][0] +
1362 (x
-k
)*light
->SpotExpTable
[k
][1]);
1365 light
->VP_inf_spot_attenuation
= 0;
1374 gl_update_normal_transform( GLcontext
*ctx
)
1376 ctx
->vb_rescale_factor
= 1.0;
1378 if (ctx
->NeedEyeCoords
) {
1379 if (ctx
->NeedNormals
) {
1380 GLuint transform
= NORM_TRANSFORM_NO_ROT
;
1382 if (ctx
->ModelView
.flags
& (MAT_FLAG_GENERAL
|
1384 MAT_FLAG_GENERAL_3D
|
1385 MAT_FLAG_PERSPECTIVE
))
1386 transform
= NORM_TRANSFORM
;
1388 ctx
->vb_rescale_factor
= ctx
->rescale_factor
;
1390 if (ctx
->Transform
.Normalize
) {
1391 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_NORMALIZE
];
1393 else if (ctx
->Transform
.RescaleNormals
&&
1394 ctx
->rescale_factor
!= 1.0) {
1395 ctx
->NormalTransform
= gl_normal_tab
[transform
| NORM_RESCALE
];
1398 ctx
->NormalTransform
= gl_normal_tab
[transform
];
1402 ctx
->NormalTransform
= 0;
1406 if (ctx
->NeedNormals
) {
1407 ctx
->vb_rescale_factor
= 1.0/ctx
->rescale_factor
;
1409 if (ctx
->Transform
.Normalize
) {
1410 ctx
->NormalTransform
= gl_normal_tab
[NORM_NORMALIZE
];
1412 else if (!ctx
->Transform
.RescaleNormals
&&
1413 ctx
->rescale_factor
!= 1.0) {
1414 ctx
->NormalTransform
= gl_normal_tab
[NORM_RESCALE
];
1417 ctx
->NormalTransform
= 0;
1421 ctx
->NormalTransform
= 0;