changed a warning string
[mesa.git] / src / mesa / main / light.c
1 /* $Id: light.c,v 1.9 1999/11/11 01:22:27 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "enums.h"
34 #include "light.h"
35 #include "macros.h"
36 #include "matrix.h"
37 #include "mem.h"
38 #include "mmath.h"
39 #include "simple_list.h"
40 #include "types.h"
41 #include "vb.h"
42 #include "xform.h"
43 #endif
44
45
46
47 void
48 _mesa_ShadeModel( GLenum mode )
49 {
50 GET_CURRENT_CONTEXT(ctx);
51 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
52
53 if (MESA_VERBOSE & VERBOSE_API)
54 fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
55
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 );
63 }
64 }
65 else {
66 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
67 }
68 }
69
70
71
72 void
73 _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
74 {
75 _mesa_Lightfv( light, pname, &param );
76 }
77
78
79 void
80 _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
81 {
82 GET_CURRENT_CONTEXT(ctx);
83 GLint l;
84 GLint nParams;
85
86 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
87
88 l = (GLint) (light - GL_LIGHT0);
89
90 if (l < 0 || l >= MAX_LIGHTS) {
91 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
92 return;
93 }
94
95 switch (pname) {
96 case GL_AMBIENT:
97 COPY_4V( ctx->Light.Light[l].Ambient, params );
98 nParams = 4;
99 break;
100 case GL_DIFFUSE:
101 COPY_4V( ctx->Light.Light[l].Diffuse, params );
102 nParams = 4;
103 break;
104 case GL_SPECULAR:
105 COPY_4V( ctx->Light.Light[l].Specular, params );
106 nParams = 4;
107 break;
108 case GL_POSITION:
109 /* transform position by ModelView matrix */
110 TRANSFORM_POINT( ctx->Light.Light[l].EyePosition,
111 ctx->ModelView.m,
112 params );
113 nParams = 4;
114 break;
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 );
119 }
120 TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
121 params,
122 ctx->ModelView.inv );
123 nParams = 3;
124 break;
125 case GL_SPOT_EXPONENT:
126 if (params[0]<0.0 || params[0]>128.0) {
127 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
128 return;
129 }
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] );
133 }
134 nParams = 1;
135 break;
136 case GL_SPOT_CUTOFF:
137 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
138 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
139 return;
140 }
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;
145 nParams = 1;
146 break;
147 case GL_CONSTANT_ATTENUATION:
148 if (params[0]<0.0) {
149 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
150 return;
151 }
152 ctx->Light.Light[l].ConstantAttenuation = params[0];
153 nParams = 1;
154 break;
155 case GL_LINEAR_ATTENUATION:
156 if (params[0]<0.0) {
157 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
158 return;
159 }
160 ctx->Light.Light[l].LinearAttenuation = params[0];
161 nParams = 1;
162 break;
163 case GL_QUADRATIC_ATTENUATION:
164 if (params[0]<0.0) {
165 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
166 return;
167 }
168 ctx->Light.Light[l].QuadraticAttenuation = params[0];
169 nParams = 1;
170 break;
171 default:
172 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
173 return;
174 }
175
176 if (ctx->Driver.Lightfv)
177 ctx->Driver.Lightfv( ctx, light, pname, params, nParams );
178
179 ctx->NewState |= NEW_LIGHTING;
180 }
181
182
183 void
184 _mesa_Lighti( GLenum light, GLenum pname, GLint param )
185 {
186 _mesa_Lightiv( light, pname, &param );
187 }
188
189
190 void
191 _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
192 {
193 GLfloat fparam[4];
194
195 switch (pname) {
196 case GL_AMBIENT:
197 case GL_DIFFUSE:
198 case GL_SPECULAR:
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] );
203 break;
204 case GL_POSITION:
205 fparam[0] = (GLfloat) params[0];
206 fparam[1] = (GLfloat) params[1];
207 fparam[2] = (GLfloat) params[2];
208 fparam[3] = (GLfloat) params[3];
209 break;
210 case GL_SPOT_DIRECTION:
211 fparam[0] = (GLfloat) params[0];
212 fparam[1] = (GLfloat) params[1];
213 fparam[2] = (GLfloat) params[2];
214 break;
215 case GL_SPOT_EXPONENT:
216 case GL_SPOT_CUTOFF:
217 case GL_CONSTANT_ATTENUATION:
218 case GL_LINEAR_ATTENUATION:
219 case GL_QUADRATIC_ATTENUATION:
220 fparam[0] = (GLfloat) params[0];
221 break;
222 default:
223 /* error will be caught later in gl_Lightfv */
224 ;
225 }
226
227 _mesa_Lightfv( light, pname, fparam );
228 }
229
230
231
232 void
233 _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
234 {
235 GET_CURRENT_CONTEXT(ctx);
236 GLint l = (GLint) (light - GL_LIGHT0);
237
238 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
239
240 if (l<0 || l>=MAX_LIGHTS) {
241 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
242 return;
243 }
244
245 switch (pname) {
246 case GL_AMBIENT:
247 COPY_4V( params, ctx->Light.Light[l].Ambient );
248 break;
249 case GL_DIFFUSE:
250 COPY_4V( params, ctx->Light.Light[l].Diffuse );
251 break;
252 case GL_SPECULAR:
253 COPY_4V( params, ctx->Light.Light[l].Specular );
254 break;
255 case GL_POSITION:
256 COPY_4V( params, ctx->Light.Light[l].EyePosition );
257 break;
258 case GL_SPOT_DIRECTION:
259 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
260 break;
261 case GL_SPOT_EXPONENT:
262 params[0] = ctx->Light.Light[l].SpotExponent;
263 break;
264 case GL_SPOT_CUTOFF:
265 params[0] = ctx->Light.Light[l].SpotCutoff;
266 break;
267 case GL_CONSTANT_ATTENUATION:
268 params[0] = ctx->Light.Light[l].ConstantAttenuation;
269 break;
270 case GL_LINEAR_ATTENUATION:
271 params[0] = ctx->Light.Light[l].LinearAttenuation;
272 break;
273 case GL_QUADRATIC_ATTENUATION:
274 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
275 break;
276 default:
277 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
278 break;
279 }
280 }
281
282
283
284 void
285 _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
286 {
287 GET_CURRENT_CONTEXT(ctx);
288 GLint l = (GLint) (light - GL_LIGHT0);
289
290 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
291
292 if (l<0 || l>=MAX_LIGHTS) {
293 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
294 return;
295 }
296
297 switch (pname) {
298 case GL_AMBIENT:
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]);
303 break;
304 case GL_DIFFUSE:
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]);
309 break;
310 case GL_SPECULAR:
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]);
315 break;
316 case GL_POSITION:
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];
321 break;
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];
326 break;
327 case GL_SPOT_EXPONENT:
328 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
329 break;
330 case GL_SPOT_CUTOFF:
331 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
332 break;
333 case GL_CONSTANT_ATTENUATION:
334 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
335 break;
336 case GL_LINEAR_ATTENUATION:
337 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
338 break;
339 case GL_QUADRATIC_ATTENUATION:
340 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
341 break;
342 default:
343 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
344 break;
345 }
346 }
347
348
349
350 /**********************************************************************/
351 /*** Light Model ***/
352 /**********************************************************************/
353
354
355 void
356 _mesa_LightModelfv( GLenum pname, const GLfloat *params )
357 {
358 GET_CURRENT_CONTEXT(ctx);
359 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
360
361 switch (pname) {
362 case GL_LIGHT_MODEL_AMBIENT:
363 COPY_4V( ctx->Light.Model.Ambient, params );
364 break;
365 case GL_LIGHT_MODEL_LOCAL_VIEWER:
366 if (params[0]==0.0)
367 ctx->Light.Model.LocalViewer = GL_FALSE;
368 else
369 ctx->Light.Model.LocalViewer = GL_TRUE;
370 break;
371 case GL_LIGHT_MODEL_TWO_SIDE:
372 if (params[0]==0.0)
373 ctx->Light.Model.TwoSide = GL_FALSE;
374 else
375 ctx->Light.Model.TwoSide = GL_TRUE;
376 break;
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;
381 }
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;
385 }
386 else {
387 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
388 }
389 ctx->NewState |= NEW_RASTER_OPS;
390 break;
391 default:
392 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
393 break;
394 }
395
396 if (ctx->Driver.LightModelfv)
397 ctx->Driver.LightModelfv( ctx, pname, params );
398
399 ctx->NewState |= NEW_LIGHTING;
400 }
401
402
403 void
404 _mesa_LightModeliv( GLenum pname, const GLint *params )
405 {
406 GLfloat fparam[4];
407 GET_CURRENT_CONTEXT(ctx);
408 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
409
410 switch (pname) {
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] );
416 break;
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];
421 break;
422 default:
423 /* Error will be caught later in gl_LightModelfv */
424 ;
425 }
426 _mesa_LightModelfv( pname, fparam );
427 }
428
429
430 void
431 _mesa_LightModeli( GLenum pname, GLint param )
432 {
433 _mesa_LightModeliv( pname, &param );
434 }
435
436
437 void
438 _mesa_LightModelf( GLenum pname, GLfloat param )
439 {
440 _mesa_LightModelfv( pname, &param );
441 }
442
443
444
445 /********** MATERIAL **********/
446
447
448 /*
449 * Given a face and pname value (ala glColorMaterial), compute a bitmask
450 * of the targeted material values.
451 */
452 GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
453 GLuint legal,
454 const char *where )
455 {
456 GLuint bitmask = 0;
457
458 /* Make a bitmask indicating what material attribute(s) we're updating */
459 switch (pname) {
460 case GL_EMISSION:
461 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
462 break;
463 case GL_AMBIENT:
464 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
465 break;
466 case GL_DIFFUSE:
467 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
468 break;
469 case GL_SPECULAR:
470 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
471 break;
472 case GL_SHININESS:
473 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
474 break;
475 case GL_AMBIENT_AND_DIFFUSE:
476 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
477 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
478 break;
479 case GL_COLOR_INDEXES:
480 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
481 break;
482 default:
483 gl_error( ctx, GL_INVALID_ENUM, where );
484 return 0;
485 }
486
487 if (face==GL_FRONT) {
488 bitmask &= FRONT_MATERIAL_BITS;
489 }
490 else if (face==GL_BACK) {
491 bitmask &= BACK_MATERIAL_BITS;
492 }
493 else if (face != GL_FRONT_AND_BACK) {
494 gl_error( ctx, GL_INVALID_ENUM, where );
495 return 0;
496 }
497
498 if (bitmask & ~legal) {
499 gl_error( ctx, GL_INVALID_ENUM, where );
500 return 0;
501 }
502
503 return bitmask;
504 }
505
506
507
508
509
510
511 /*
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.
517 *
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.
523 */
524 void gl_update_material( GLcontext *ctx,
525 struct gl_material *src,
526 GLuint bitmask )
527 {
528 struct gl_light *light, *list = &ctx->Light.EnabledList;
529 GLfloat tmp[4];
530
531 if (ctx->Light.ColorMaterialEnabled)
532 bitmask &= ~ctx->Light.ColorMaterialBitmask;
533
534 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
535 fprintf(stderr, "gl_update_material, mask %x\n", bitmask);
536
537 if (!bitmask)
538 return;
539
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 );
546 }
547 COPY_4FV( mat->Ambient, src[0].Ambient );
548 }
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 );
555 }
556 COPY_4FV( mat->Ambient, src[1].Ambient );
557 }
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 );
563 }
564 COPY_4FV( mat->Diffuse, src[0].Diffuse );
565 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
566 }
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 );
572 }
573 COPY_4FV( mat->Diffuse, src[1].Diffuse );
574 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
575 }
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);
584 }
585 }
586 COPY_4FV( mat->Specular, src[0].Specular );
587 }
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);
596 }
597 }
598 COPY_4FV( mat->Specular, src[1].Specular );
599 }
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 );
605 }
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 );
611 }
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 );
616 }
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 );
621 }
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;
626 }
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;
631 }
632
633 if (0)
634 {
635 struct gl_material *mat = &ctx->Light.Material[0];
636 fprintf(stderr, "update_mat emission : %f %f %f\n",
637 mat->Emission[0],
638 mat->Emission[1],
639 mat->Emission[2]);
640 fprintf(stderr, "update_mat specular : %f %f %f\n",
641 mat->Specular[0],
642 mat->Specular[1],
643 mat->Specular[2]);
644 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
645 mat->Diffuse[0],
646 mat->Diffuse[1],
647 mat->Diffuse[2]);
648 fprintf(stderr, "update_mat ambient : %f %f %f\n",
649 mat->Ambient[0],
650 mat->Ambient[1],
651 mat->Ambient[2]);
652 }
653 }
654
655
656
657
658
659
660 void gl_update_color_material( GLcontext *ctx,
661 const GLubyte rgba[4] )
662 {
663 struct gl_light *light, *list = &ctx->Light.EnabledList;
664 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
665 GLfloat tmp[4], color[4];
666
667 UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
668
669 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
670 fprintf(stderr, "gl_update_color_material, mask %x\n", bitmask);
671
672
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 );
679 }
680 COPY_4FV( mat->Ambient, color );
681 }
682
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 );
689 }
690 COPY_4FV( mat->Ambient, color );
691 }
692
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 );
698 }
699 COPY_4FV( mat->Diffuse, color );
700 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
701 }
702
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 );
708 }
709 COPY_4FV( mat->Diffuse, color );
710 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
711 }
712
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);
721 }
722 }
723 COPY_4FV( mat->Specular, color );
724 }
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);
733 }
734 }
735 COPY_4FV( mat->Specular, color );
736 }
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 );
742 }
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 );
748 }
749
750 if (0)
751 {
752 struct gl_material *mat = &ctx->Light.Material[0];
753 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
754 mat->Emission[0],
755 mat->Emission[1],
756 mat->Emission[2]);
757 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
758 mat->Specular[0],
759 mat->Specular[1],
760 mat->Specular[2]);
761 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
762 mat->Diffuse[0],
763 mat->Diffuse[1],
764 mat->Diffuse[2]);
765 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
766 mat->Ambient[0],
767 mat->Ambient[1],
768 mat->Ambient[2]);
769 }
770 }
771
772
773
774
775 void
776 _mesa_ColorMaterial( GLenum face, GLenum mode )
777 {
778 GET_CURRENT_CONTEXT(ctx);
779 GLuint bitmask;
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);
784
785 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
786
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));
791
792 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
793
794 if (bitmask != 0) {
795 ctx->Light.ColorMaterialBitmask = bitmask;
796 ctx->Light.ColorMaterialFace = face;
797 ctx->Light.ColorMaterialMode = mode;
798 }
799
800 if (ctx->Light.ColorMaterialEnabled)
801 gl_update_color_material( ctx, ctx->Current.ByteColor );
802 }
803
804
805
806
807 void
808 _mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
809 {
810 _mesa_Materialfv( face, pname, &param );
811 }
812
813
814 /* KW: This is now called directly (ie by name) from the glMaterial*
815 * API functions.
816 */
817 void
818 _mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
819 {
820 GET_CURRENT_CONTEXT(ctx);
821 struct immediate *IM;
822 struct gl_material *mat;
823 GLuint bitmask;
824 GLuint count;
825
826 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
827 if (bitmask == 0)
828 return;
829
830 IM = ctx->input;
831 count = IM->Count;
832
833 if (!IM->Material) {
834 IM->Material =
835 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
836 VB_SIZE * 2 );
837 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
838 }
839
840
841 if (!(IM->Flag[count] & VERT_MATERIAL)) {
842 IM->Flag[count] |= VERT_MATERIAL;
843 IM->MaterialMask[count] = 0;
844 }
845
846
847 IM->MaterialMask[count] |= bitmask;
848 mat = IM->Material[count];
849
850 if (bitmask & FRONT_AMBIENT_BIT) {
851 COPY_4FV( mat[0].Ambient, params );
852 }
853 if (bitmask & BACK_AMBIENT_BIT) {
854 COPY_4FV( mat[1].Ambient, params );
855 }
856 if (bitmask & FRONT_DIFFUSE_BIT) {
857 COPY_4FV( mat[0].Diffuse, params );
858 }
859 if (bitmask & BACK_DIFFUSE_BIT) {
860 COPY_4FV( mat[1].Diffuse, params );
861 }
862 if (bitmask & FRONT_SPECULAR_BIT) {
863 COPY_4FV( mat[0].Specular, params );
864 }
865 if (bitmask & BACK_SPECULAR_BIT) {
866 COPY_4FV( mat[1].Specular, params );
867 }
868 if (bitmask & FRONT_EMISSION_BIT) {
869 COPY_4FV( mat[0].Emission, params );
870 }
871 if (bitmask & BACK_EMISSION_BIT) {
872 COPY_4FV( mat[1].Emission, params );
873 }
874 if (bitmask & FRONT_SHININESS_BIT) {
875 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
876 mat[0].Shininess = shininess;
877 }
878 if (bitmask & BACK_SHININESS_BIT) {
879 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
880 mat[1].Shininess = shininess;
881 }
882 if (bitmask & FRONT_INDEXES_BIT) {
883 mat[0].AmbientIndex = params[0];
884 mat[0].DiffuseIndex = params[1];
885 mat[0].SpecularIndex = params[2];
886 }
887 if (bitmask & BACK_INDEXES_BIT) {
888 mat[1].AmbientIndex = params[0];
889 mat[1].DiffuseIndex = params[1];
890 mat[1].SpecularIndex = params[2];
891 }
892 }
893
894
895 void
896 _mesa_Materiali(GLenum face, GLenum pname, GLint param )
897 {
898 _mesa_Materialiv(face, pname, &param);
899 }
900
901
902 void
903 _mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
904 {
905 GLfloat fparam[4];
906 switch (pname) {
907 case GL_AMBIENT:
908 case GL_DIFFUSE:
909 case GL_SPECULAR:
910 case GL_EMISSION:
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] );
916 break;
917 case GL_SHININESS:
918 fparam[0] = (GLfloat) params[0];
919 break;
920 case GL_COLOR_INDEXES:
921 fparam[0] = (GLfloat) params[0];
922 fparam[1] = (GLfloat) params[1];
923 fparam[2] = (GLfloat) params[2];
924 break;
925 default:
926 /* Error will be caught later in gl_Materialfv */
927 ;
928 }
929 _mesa_Materialfv(face, pname, fparam);
930 }
931
932
933 void
934 _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
935 {
936 GET_CURRENT_CONTEXT(ctx);
937 GLuint f;
938
939 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
940
941 if (face==GL_FRONT) {
942 f = 0;
943 }
944 else if (face==GL_BACK) {
945 f = 1;
946 }
947 else {
948 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
949 return;
950 }
951 switch (pname) {
952 case GL_AMBIENT:
953 COPY_4FV( params, ctx->Light.Material[f].Ambient );
954 break;
955 case GL_DIFFUSE:
956 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
957 break;
958 case GL_SPECULAR:
959 COPY_4FV( params, ctx->Light.Material[f].Specular );
960 break;
961 case GL_EMISSION:
962 COPY_4FV( params, ctx->Light.Material[f].Emission );
963 break;
964 case GL_SHININESS:
965 *params = ctx->Light.Material[f].Shininess;
966 break;
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;
971 break;
972 default:
973 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
974 }
975 }
976
977
978
979 void
980 _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
981 {
982 GET_CURRENT_CONTEXT(ctx);
983 GLuint f;
984
985 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
986
987 if (face==GL_FRONT) {
988 f = 0;
989 }
990 else if (face==GL_BACK) {
991 f = 1;
992 }
993 else {
994 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
995 return;
996 }
997 switch (pname) {
998 case GL_AMBIENT:
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] );
1003 break;
1004 case GL_DIFFUSE:
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] );
1009 break;
1010 case GL_SPECULAR:
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] );
1015 break;
1016 case GL_EMISSION:
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] );
1021 break;
1022 case GL_SHININESS:
1023 *params = ROUNDF( ctx->Light.Material[f].Shininess );
1024 break;
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 );
1029 break;
1030 default:
1031 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1032 }
1033 }
1034
1035
1036
1037
1038 /**********************************************************************/
1039 /***** Lighting computation *****/
1040 /**********************************************************************/
1041
1042
1043 /*
1044 * Notes:
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.
1049 *
1050 * KW: We now know orientation in advance and only shade for
1051 * the side or sides which are actually required.
1052 *
1053 * Variables:
1054 * n = normal vector
1055 * V = vertex position
1056 * P = light source position
1057 * Pe = (0,0,0,1)
1058 *
1059 * Precomputed:
1060 * IF P[3]==0 THEN
1061 * // light at infinity
1062 * IF local_viewer THEN
1063 * VP_inf_norm = unit vector from V to P // Precompute
1064 * ELSE
1065 * // eye at infinity
1066 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1067 * ENDIF
1068 * ENDIF
1069 *
1070 * Functions:
1071 * Normalize( v ) = normalized vector v
1072 * Magnitude( v ) = length of vector v
1073 */
1074
1075
1076
1077 /*
1078 * Whenever the spotlight exponent for a light changes we must call
1079 * this function to recompute the exponent lookup table.
1080 */
1081 void gl_compute_spot_exp_table( struct gl_light *l )
1082 {
1083 int i;
1084 double exponent = l->SpotExponent;
1085 double tmp = 0;
1086 int clamp = 0;
1087
1088 l->SpotExpTable[0][0] = 0.0;
1089
1090 for (i=EXP_TABLE_SIZE-1;i>0;i--) {
1091 if (clamp == 0) {
1092 tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
1093 if (tmp < FLT_MIN*100.0) {
1094 tmp = 0.0;
1095 clamp = 1;
1096 }
1097 }
1098 l->SpotExpTable[i][0] = tmp;
1099 }
1100 for (i=0;i<EXP_TABLE_SIZE-1;i++) {
1101 l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
1102 }
1103 l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
1104 }
1105
1106
1107
1108
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.
1112 */
1113 static void compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
1114 {
1115 int i;
1116 GLfloat *m = tab->tab;
1117
1118 m[0] = 0;
1119 if (shininess == 0) {
1120 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
1121 m[i] = 1;
1122 } else {
1123 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) {
1124 double t = pow( i/(GLfloat)SHINE_TABLE_SIZE, shininess );
1125 m[i] = 0;
1126 if (t > 1e-20) m[i] = t;
1127 }
1128 }
1129
1130 tab->shininess = shininess;
1131 }
1132
1133 #define DISTSQR(a,b) ((a-b)*(a-b))
1134
1135 void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
1136 {
1137 struct gl_shine_tab *list = ctx->ShineTabList;
1138 struct gl_shine_tab *s;
1139
1140 foreach(s, list)
1141 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
1142 break;
1143
1144 if (s == list)
1145 {
1146 foreach(s, list)
1147 if (s->refcount == 0) break;
1148
1149 compute_shine_table( s, shininess );
1150 }
1151
1152 ctx->ShineTable[i]->refcount--;
1153 ctx->ShineTable[i] = s;
1154 move_to_tail( list, s );
1155 s->refcount++;
1156 }
1157
1158
1159
1160
1161 void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
1162 {
1163 GLuint i;
1164
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 );
1168 }
1169
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 );
1173 }
1174
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] );
1179 }
1180 }
1181
1182
1183
1184 /*
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.
1189 */
1190 void gl_update_lighting( GLcontext *ctx )
1191 {
1192 struct gl_light *light;
1193
1194 ctx->Light.Flags = 0;
1195
1196 foreach(light, &ctx->Light.EnabledList) {
1197
1198 light->Flags = 0;
1199
1200 if (light->EyePosition[3] != 0.0F)
1201 light->Flags |= LIGHT_POSITIONAL;
1202
1203 if (LEN_SQUARED_3FV(light->Specular) > 1e-16)
1204 light->Flags |= LIGHT_SPECULAR;
1205
1206 if (light->SpotCutoff != 180.0F)
1207 light->Flags |= LIGHT_SPOT;
1208
1209 ctx->Light.Flags |= light->Flags;
1210 }
1211
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)));
1216
1217
1218 /* Precompute some shading values.
1219 */
1220 if (ctx->Visual->RGBAflag)
1221 {
1222 GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
1223 GLuint side;
1224 for (side=0; side < sides; side++) {
1225 struct gl_material *mat = &ctx->Light.Material[side];
1226
1227 COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
1228 ACC_SCALE_3V(ctx->Light.BaseColor[side],
1229 ctx->Light.Model.Ambient,
1230 mat->Ambient);
1231
1232 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[side],
1233 ctx->Light.Material[side].Diffuse[3] );
1234 }
1235
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)
1243 {
1244 SCALE_3V( light->MatSpecular[side], light->Specular,
1245 mat->Specular);
1246 light->IsMatSpecular[side] =
1247 (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
1248 }
1249 else
1250 light->IsMatSpecular[side] = 0;
1251 }
1252 }
1253 }
1254 else
1255 {
1256 static GLfloat ci[3] = { .30, .59, .11 };
1257
1258 foreach(light, &ctx->Light.EnabledList) {
1259 light->dli = DOT3(ci, light->Diffuse);
1260 light->sli = DOT3(ci, light->Specular);
1261 }
1262 }
1263 }
1264
1265 /* Need to seriously restrict the circumstances under which these
1266 * calc's are performed.
1267 */
1268 void gl_compute_light_positions( GLcontext *ctx )
1269 {
1270 struct gl_light *light;
1271
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 );
1276 } else {
1277 COPY_3V( ctx->EyeZDir, eye_z );
1278 }
1279 }
1280
1281 foreach (light, &ctx->Light.EnabledList) {
1282
1283 if (!ctx->NeedEyeCoords) {
1284 TRANSFORM_POINT( light->Position, ctx->ModelView.inv,
1285 light->EyePosition );
1286 } else {
1287 COPY_4FV( light->Position, light->EyePosition );
1288 }
1289
1290 if (!(light->Flags & LIGHT_POSITIONAL))
1291 {
1292 /* VP (VP) = Normalize( Position ) */
1293 COPY_3V( light->VP_inf_norm, light->Position );
1294 NORMALIZE_3FV( light->VP_inf_norm );
1295
1296 if (!ctx->Light.Model.LocalViewer)
1297 {
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 );
1301 }
1302
1303 light->VP_inf_spot_attenuation = 1.0;
1304 }
1305
1306 if (light->Flags & LIGHT_SPOT)
1307 {
1308 if (ctx->NeedEyeNormals) {
1309 COPY_3V( light->NormDirection, light->EyeDirection );
1310 } else {
1311 TRANSFORM_NORMAL( light->NormDirection,
1312 light->EyeDirection,
1313 ctx->ModelView.m);
1314 }
1315
1316 NORMALIZE_3FV( light->NormDirection );
1317
1318
1319 /* Unlikely occurrance?
1320 */
1321 if (!(light->Flags & LIGHT_POSITIONAL)) {
1322 GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm,
1323 light->NormDirection);
1324
1325 if (PV_dot_dir > light->CosCutoff) {
1326 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1327 int k = (int) x;
1328 light->VP_inf_spot_attenuation =
1329 (light->SpotExpTable[k][0] +
1330 (x-k)*light->SpotExpTable[k][1]);
1331 }
1332 else
1333 light->VP_inf_spot_attenuation = 0;
1334 }
1335 }
1336 }
1337 }
1338
1339
1340
1341
1342
1343 void gl_update_normal_transform( GLcontext *ctx )
1344 {
1345 GLuint new_flag = 0;
1346 normal_func *last = ctx->NormalTransform;
1347
1348 ctx->vb_rescale_factor = 1.0;
1349
1350 if (ctx->NeedEyeCoords) {
1351 if (ctx->NeedNormals) {
1352 GLuint transform = NORM_TRANSFORM_NO_ROT;
1353
1354 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1355 MAT_FLAG_ROTATION |
1356 MAT_FLAG_GENERAL_3D |
1357 MAT_FLAG_PERSPECTIVE))
1358 transform = NORM_TRANSFORM;
1359
1360
1361 new_flag = ctx->NewState & NEW_MODELVIEW;
1362 ctx->vb_rescale_factor = ctx->rescale_factor;
1363
1364 if (ctx->Transform.Normalize)
1365 {
1366 ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
1367 }
1368 else if (ctx->Transform.RescaleNormals &&
1369 ctx->rescale_factor != 1.0)
1370 {
1371 ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
1372 }
1373 else
1374 {
1375 ctx->NormalTransform = gl_normal_tab[transform];
1376 }
1377 } else {
1378 ctx->NormalTransform = 0;
1379 }
1380 }
1381 else {
1382 if (ctx->NeedNormals) {
1383 ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
1384
1385 if (ctx->Transform.Normalize)
1386 {
1387 ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
1388 }
1389 else if (!ctx->Transform.RescaleNormals &&
1390 ctx->rescale_factor != 1.0)
1391 {
1392 ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
1393 }
1394 else
1395 {
1396 ctx->NormalTransform = 0;
1397 }
1398 } else {
1399 ctx->NormalTransform = 0;
1400 }
1401 }
1402
1403 if (last != ctx->NormalTransform || new_flag)
1404 ctx->NewState |= NEW_NORMAL_TRANSFORM;
1405 }
1406