rearranged order of some functions
[mesa.git] / src / mesa / main / light.c
1 /* $Id: light.c,v 1.12 2000/01/31 23:33:53 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 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 /* XXX this is a bit of a hack needed for compilation within XFree86 */
47 #ifndef FLT_MIN
48 #define FLT_MIN 1e-37
49 #endif
50
51
52 void
53 _mesa_ShadeModel( GLenum mode )
54 {
55 GET_CURRENT_CONTEXT(ctx);
56 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
57
58 if (MESA_VERBOSE & VERBOSE_API)
59 fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
60
61 if (mode == GL_FLAT || mode == GL_SMOOTH) {
62 if (ctx->Light.ShadeModel != mode) {
63 ctx->Light.ShadeModel = mode;
64 if (ctx->Light.ShadeModel == GL_FLAT)
65 SET_BITS(ctx->TriangleCaps, DD_FLATSHADE);
66 else
67 CLEAR_BITS(ctx->TriangleCaps, DD_FLATSHADE);
68 ctx->NewState |= NEW_RASTER_OPS;
69 if (ctx->Driver.ShadeModel)
70 (*ctx->Driver.ShadeModel)( ctx, mode );
71 }
72 }
73 else {
74 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
75 }
76 }
77
78
79
80 void
81 _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
82 {
83 _mesa_Lightfv( light, pname, &param );
84 }
85
86
87 void
88 _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
89 {
90 GET_CURRENT_CONTEXT(ctx);
91 GLint l;
92 GLint nParams;
93
94 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
95
96 l = (GLint) (light - GL_LIGHT0);
97
98 if (l < 0 || l >= MAX_LIGHTS) {
99 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
100 return;
101 }
102
103 switch (pname) {
104 case GL_AMBIENT:
105 COPY_4V( ctx->Light.Light[l].Ambient, params );
106 nParams = 4;
107 break;
108 case GL_DIFFUSE:
109 COPY_4V( ctx->Light.Light[l].Diffuse, params );
110 nParams = 4;
111 break;
112 case GL_SPECULAR:
113 COPY_4V( ctx->Light.Light[l].Specular, params );
114 nParams = 4;
115 break;
116 case GL_POSITION:
117 /* transform position by ModelView matrix */
118 TRANSFORM_POINT( ctx->Light.Light[l].EyePosition,
119 ctx->ModelView.m,
120 params );
121 nParams = 4;
122 break;
123 case GL_SPOT_DIRECTION:
124 /* transform direction by inverse modelview */
125 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
126 gl_matrix_analyze( &ctx->ModelView );
127 }
128 TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
129 params,
130 ctx->ModelView.inv );
131 nParams = 3;
132 break;
133 case GL_SPOT_EXPONENT:
134 if (params[0]<0.0 || params[0]>128.0) {
135 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
136 return;
137 }
138 if (ctx->Light.Light[l].SpotExponent != params[0]) {
139 ctx->Light.Light[l].SpotExponent = params[0];
140 gl_compute_spot_exp_table( &ctx->Light.Light[l] );
141 }
142 nParams = 1;
143 break;
144 case GL_SPOT_CUTOFF:
145 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
146 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
147 return;
148 }
149 ctx->Light.Light[l].SpotCutoff = params[0];
150 ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
151 if (ctx->Light.Light[l].CosCutoff < 0)
152 ctx->Light.Light[l].CosCutoff = 0;
153 nParams = 1;
154 break;
155 case GL_CONSTANT_ATTENUATION:
156 if (params[0]<0.0) {
157 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
158 return;
159 }
160 ctx->Light.Light[l].ConstantAttenuation = params[0];
161 nParams = 1;
162 break;
163 case GL_LINEAR_ATTENUATION:
164 if (params[0]<0.0) {
165 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
166 return;
167 }
168 ctx->Light.Light[l].LinearAttenuation = params[0];
169 nParams = 1;
170 break;
171 case GL_QUADRATIC_ATTENUATION:
172 if (params[0]<0.0) {
173 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
174 return;
175 }
176 ctx->Light.Light[l].QuadraticAttenuation = params[0];
177 nParams = 1;
178 break;
179 default:
180 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
181 return;
182 }
183
184 if (ctx->Driver.Lightfv)
185 ctx->Driver.Lightfv( ctx, light, pname, params, nParams );
186
187 ctx->NewState |= NEW_LIGHTING;
188 }
189
190
191 void
192 _mesa_Lighti( GLenum light, GLenum pname, GLint param )
193 {
194 _mesa_Lightiv( light, pname, &param );
195 }
196
197
198 void
199 _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
200 {
201 GLfloat fparam[4];
202
203 switch (pname) {
204 case GL_AMBIENT:
205 case GL_DIFFUSE:
206 case GL_SPECULAR:
207 fparam[0] = INT_TO_FLOAT( params[0] );
208 fparam[1] = INT_TO_FLOAT( params[1] );
209 fparam[2] = INT_TO_FLOAT( params[2] );
210 fparam[3] = INT_TO_FLOAT( params[3] );
211 break;
212 case GL_POSITION:
213 fparam[0] = (GLfloat) params[0];
214 fparam[1] = (GLfloat) params[1];
215 fparam[2] = (GLfloat) params[2];
216 fparam[3] = (GLfloat) params[3];
217 break;
218 case GL_SPOT_DIRECTION:
219 fparam[0] = (GLfloat) params[0];
220 fparam[1] = (GLfloat) params[1];
221 fparam[2] = (GLfloat) params[2];
222 break;
223 case GL_SPOT_EXPONENT:
224 case GL_SPOT_CUTOFF:
225 case GL_CONSTANT_ATTENUATION:
226 case GL_LINEAR_ATTENUATION:
227 case GL_QUADRATIC_ATTENUATION:
228 fparam[0] = (GLfloat) params[0];
229 break;
230 default:
231 /* error will be caught later in gl_Lightfv */
232 ;
233 }
234
235 _mesa_Lightfv( light, pname, fparam );
236 }
237
238
239
240 void
241 _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
242 {
243 GET_CURRENT_CONTEXT(ctx);
244 GLint l = (GLint) (light - GL_LIGHT0);
245
246 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
247
248 if (l<0 || l>=MAX_LIGHTS) {
249 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
250 return;
251 }
252
253 switch (pname) {
254 case GL_AMBIENT:
255 COPY_4V( params, ctx->Light.Light[l].Ambient );
256 break;
257 case GL_DIFFUSE:
258 COPY_4V( params, ctx->Light.Light[l].Diffuse );
259 break;
260 case GL_SPECULAR:
261 COPY_4V( params, ctx->Light.Light[l].Specular );
262 break;
263 case GL_POSITION:
264 COPY_4V( params, ctx->Light.Light[l].EyePosition );
265 break;
266 case GL_SPOT_DIRECTION:
267 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
268 break;
269 case GL_SPOT_EXPONENT:
270 params[0] = ctx->Light.Light[l].SpotExponent;
271 break;
272 case GL_SPOT_CUTOFF:
273 params[0] = ctx->Light.Light[l].SpotCutoff;
274 break;
275 case GL_CONSTANT_ATTENUATION:
276 params[0] = ctx->Light.Light[l].ConstantAttenuation;
277 break;
278 case GL_LINEAR_ATTENUATION:
279 params[0] = ctx->Light.Light[l].LinearAttenuation;
280 break;
281 case GL_QUADRATIC_ATTENUATION:
282 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
283 break;
284 default:
285 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
286 break;
287 }
288 }
289
290
291
292 void
293 _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
294 {
295 GET_CURRENT_CONTEXT(ctx);
296 GLint l = (GLint) (light - GL_LIGHT0);
297
298 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
299
300 if (l<0 || l>=MAX_LIGHTS) {
301 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
302 return;
303 }
304
305 switch (pname) {
306 case GL_AMBIENT:
307 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
308 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
309 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
310 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
311 break;
312 case GL_DIFFUSE:
313 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
314 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
315 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
316 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
317 break;
318 case GL_SPECULAR:
319 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
320 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
321 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
322 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
323 break;
324 case GL_POSITION:
325 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
326 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
327 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
328 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
329 break;
330 case GL_SPOT_DIRECTION:
331 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
332 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
333 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
334 break;
335 case GL_SPOT_EXPONENT:
336 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
337 break;
338 case GL_SPOT_CUTOFF:
339 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
340 break;
341 case GL_CONSTANT_ATTENUATION:
342 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
343 break;
344 case GL_LINEAR_ATTENUATION:
345 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
346 break;
347 case GL_QUADRATIC_ATTENUATION:
348 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
349 break;
350 default:
351 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
352 break;
353 }
354 }
355
356
357
358 /**********************************************************************/
359 /*** Light Model ***/
360 /**********************************************************************/
361
362
363 void
364 _mesa_LightModelfv( GLenum pname, const GLfloat *params )
365 {
366 GET_CURRENT_CONTEXT(ctx);
367 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
368
369 switch (pname) {
370 case GL_LIGHT_MODEL_AMBIENT:
371 COPY_4V( ctx->Light.Model.Ambient, params );
372 break;
373 case GL_LIGHT_MODEL_LOCAL_VIEWER:
374 if (params[0]==0.0)
375 ctx->Light.Model.LocalViewer = GL_FALSE;
376 else
377 ctx->Light.Model.LocalViewer = GL_TRUE;
378 break;
379 case GL_LIGHT_MODEL_TWO_SIDE:
380 if (params[0]==0.0)
381 ctx->Light.Model.TwoSide = GL_FALSE;
382 else
383 ctx->Light.Model.TwoSide = GL_TRUE;
384 break;
385 case GL_LIGHT_MODEL_COLOR_CONTROL:
386 if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
387 ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
388 CLEAR_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
389 }
390 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
391 ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
392 SET_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
393 }
394 else {
395 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
396 }
397 ctx->NewState |= NEW_RASTER_OPS;
398 break;
399 default:
400 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
401 break;
402 }
403
404 if (ctx->Driver.LightModelfv)
405 ctx->Driver.LightModelfv( ctx, pname, params );
406
407 ctx->NewState |= NEW_LIGHTING;
408 }
409
410
411 void
412 _mesa_LightModeliv( GLenum pname, const GLint *params )
413 {
414 GLfloat fparam[4];
415 GET_CURRENT_CONTEXT(ctx);
416 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
417
418 switch (pname) {
419 case GL_LIGHT_MODEL_AMBIENT:
420 fparam[0] = INT_TO_FLOAT( params[0] );
421 fparam[1] = INT_TO_FLOAT( params[1] );
422 fparam[2] = INT_TO_FLOAT( params[2] );
423 fparam[3] = INT_TO_FLOAT( params[3] );
424 break;
425 case GL_LIGHT_MODEL_LOCAL_VIEWER:
426 case GL_LIGHT_MODEL_TWO_SIDE:
427 case GL_LIGHT_MODEL_COLOR_CONTROL:
428 fparam[0] = (GLfloat) params[0];
429 break;
430 default:
431 /* Error will be caught later in gl_LightModelfv */
432 ;
433 }
434 _mesa_LightModelfv( pname, fparam );
435 }
436
437
438 void
439 _mesa_LightModeli( GLenum pname, GLint param )
440 {
441 _mesa_LightModeliv( pname, &param );
442 }
443
444
445 void
446 _mesa_LightModelf( GLenum pname, GLfloat param )
447 {
448 _mesa_LightModelfv( pname, &param );
449 }
450
451
452
453 /********** MATERIAL **********/
454
455
456 /*
457 * Given a face and pname value (ala glColorMaterial), compute a bitmask
458 * of the targeted material values.
459 */
460 GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
461 GLuint legal,
462 const char *where )
463 {
464 GLuint bitmask = 0;
465
466 /* Make a bitmask indicating what material attribute(s) we're updating */
467 switch (pname) {
468 case GL_EMISSION:
469 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
470 break;
471 case GL_AMBIENT:
472 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
473 break;
474 case GL_DIFFUSE:
475 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
476 break;
477 case GL_SPECULAR:
478 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
479 break;
480 case GL_SHININESS:
481 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
482 break;
483 case GL_AMBIENT_AND_DIFFUSE:
484 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
485 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
486 break;
487 case GL_COLOR_INDEXES:
488 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
489 break;
490 default:
491 gl_error( ctx, GL_INVALID_ENUM, where );
492 return 0;
493 }
494
495 if (face==GL_FRONT) {
496 bitmask &= FRONT_MATERIAL_BITS;
497 }
498 else if (face==GL_BACK) {
499 bitmask &= BACK_MATERIAL_BITS;
500 }
501 else if (face != GL_FRONT_AND_BACK) {
502 gl_error( ctx, GL_INVALID_ENUM, where );
503 return 0;
504 }
505
506 if (bitmask & ~legal) {
507 gl_error( ctx, GL_INVALID_ENUM, where );
508 return 0;
509 }
510
511 return bitmask;
512 }
513
514
515
516
517
518
519 /*
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.
525 *
526 * KW: Added code here to keep the precomputed variables uptodate.
527 * This means we can use the faster shade functions when using
528 * GL_COLOR_MATERIAL, and we can also now use the precomputed
529 * values in the slower shading functions, which further offsets
530 * the cost of doing this here.
531 */
532 void gl_update_material( GLcontext *ctx,
533 struct gl_material *src,
534 GLuint bitmask )
535 {
536 struct gl_light *light, *list = &ctx->Light.EnabledList;
537 GLfloat tmp[4];
538
539 if (ctx->Light.ColorMaterialEnabled)
540 bitmask &= ~ctx->Light.ColorMaterialBitmask;
541
542 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
543 fprintf(stderr, "gl_update_material, mask %x\n", bitmask);
544
545 if (!bitmask)
546 return;
547
548 if (bitmask & FRONT_AMBIENT_BIT) {
549 struct gl_material *mat = &ctx->Light.Material[0];
550 SUB_3V( tmp, src[0].Ambient, mat->Ambient );
551 ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
552 foreach (light, list) {
553 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
554 }
555 COPY_4FV( mat->Ambient, src[0].Ambient );
556 }
557 if (bitmask & BACK_AMBIENT_BIT) {
558 struct gl_material *mat = &ctx->Light.Material[1];
559 SUB_3V( tmp, src[1].Ambient, mat->Ambient );
560 ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
561 foreach (light, list) {
562 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
563 }
564 COPY_4FV( mat->Ambient, src[1].Ambient );
565 }
566 if (bitmask & FRONT_DIFFUSE_BIT) {
567 struct gl_material *mat = &ctx->Light.Material[0];
568 SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
569 foreach (light, list) {
570 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
571 }
572 COPY_4FV( mat->Diffuse, src[0].Diffuse );
573 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
574 }
575 if (bitmask & BACK_DIFFUSE_BIT) {
576 struct gl_material *mat = &ctx->Light.Material[1];
577 SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
578 foreach (light, list) {
579 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
580 }
581 COPY_4FV( mat->Diffuse, src[1].Diffuse );
582 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
583 }
584 if (bitmask & FRONT_SPECULAR_BIT) {
585 struct gl_material *mat = &ctx->Light.Material[0];
586 SUB_3V( tmp, src[0].Specular, mat->Specular );
587 foreach (light, list) {
588 if (light->Flags & LIGHT_SPECULAR) {
589 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
590 light->IsMatSpecular[0] =
591 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
592 }
593 }
594 COPY_4FV( mat->Specular, src[0].Specular );
595 }
596 if (bitmask & BACK_SPECULAR_BIT) {
597 struct gl_material *mat = &ctx->Light.Material[1];
598 SUB_3V( tmp, src[1].Specular, mat->Specular );
599 foreach (light, list) {
600 if (light->Flags & LIGHT_SPECULAR) {
601 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
602 light->IsMatSpecular[1] =
603 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
604 }
605 }
606 COPY_4FV( mat->Specular, src[1].Specular );
607 }
608 if (bitmask & FRONT_EMISSION_BIT) {
609 struct gl_material *mat = &ctx->Light.Material[0];
610 SUB_3V( tmp, src[0].Emission, mat->Emission );
611 ACC_3V( ctx->Light.BaseColor[0], tmp );
612 COPY_4FV( mat->Emission, src[0].Emission );
613 }
614 if (bitmask & BACK_EMISSION_BIT) {
615 struct gl_material *mat = &ctx->Light.Material[1];
616 SUB_3V( tmp, src[1].Emission, mat->Emission );
617 ACC_3V( ctx->Light.BaseColor[1], tmp );
618 COPY_4FV( mat->Emission, src[1].Emission );
619 }
620 if (bitmask & FRONT_SHININESS_BIT) {
621 GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
622 gl_compute_shine_table( ctx, 0, shininess );
623 gl_compute_shine_table( ctx, 2, shininess * .5 );
624 }
625 if (bitmask & BACK_SHININESS_BIT) {
626 GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
627 gl_compute_shine_table( ctx, 1, shininess );
628 gl_compute_shine_table( ctx, 3, shininess * .5 );
629 }
630 if (bitmask & FRONT_INDEXES_BIT) {
631 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
632 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
633 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
634 }
635 if (bitmask & BACK_INDEXES_BIT) {
636 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
637 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
638 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
639 }
640
641 if (0)
642 {
643 struct gl_material *mat = &ctx->Light.Material[0];
644 fprintf(stderr, "update_mat emission : %f %f %f\n",
645 mat->Emission[0],
646 mat->Emission[1],
647 mat->Emission[2]);
648 fprintf(stderr, "update_mat specular : %f %f %f\n",
649 mat->Specular[0],
650 mat->Specular[1],
651 mat->Specular[2]);
652 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
653 mat->Diffuse[0],
654 mat->Diffuse[1],
655 mat->Diffuse[2]);
656 fprintf(stderr, "update_mat ambient : %f %f %f\n",
657 mat->Ambient[0],
658 mat->Ambient[1],
659 mat->Ambient[2]);
660 }
661 }
662
663
664
665
666
667
668 void gl_update_color_material( GLcontext *ctx,
669 const GLubyte rgba[4] )
670 {
671 struct gl_light *light, *list = &ctx->Light.EnabledList;
672 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
673 GLfloat tmp[4], color[4];
674
675 UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
676
677 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
678 fprintf(stderr, "gl_update_color_material, mask %x\n", bitmask);
679
680
681 if (bitmask & FRONT_AMBIENT_BIT) {
682 struct gl_material *mat = &ctx->Light.Material[0];
683 SUB_3V( tmp, color, mat->Ambient );
684 ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
685 foreach (light, list) {
686 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
687 }
688 COPY_4FV( mat->Ambient, color );
689 }
690
691 if (bitmask & BACK_AMBIENT_BIT) {
692 struct gl_material *mat = &ctx->Light.Material[1];
693 SUB_3V( tmp, color, mat->Ambient );
694 ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
695 foreach (light, list) {
696 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
697 }
698 COPY_4FV( mat->Ambient, color );
699 }
700
701 if (bitmask & FRONT_DIFFUSE_BIT) {
702 struct gl_material *mat = &ctx->Light.Material[0];
703 SUB_3V( tmp, color, mat->Diffuse );
704 foreach (light, list) {
705 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
706 }
707 COPY_4FV( mat->Diffuse, color );
708 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
709 }
710
711 if (bitmask & BACK_DIFFUSE_BIT) {
712 struct gl_material *mat = &ctx->Light.Material[1];
713 SUB_3V( tmp, color, mat->Diffuse );
714 foreach (light, list) {
715 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
716 }
717 COPY_4FV( mat->Diffuse, color );
718 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
719 }
720
721 if (bitmask & FRONT_SPECULAR_BIT) {
722 struct gl_material *mat = &ctx->Light.Material[0];
723 SUB_3V( tmp, color, mat->Specular );
724 foreach (light, list) {
725 if (light->Flags & LIGHT_SPECULAR) {
726 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
727 light->IsMatSpecular[0] =
728 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
729 }
730 }
731 COPY_4FV( mat->Specular, color );
732 }
733 if (bitmask & BACK_SPECULAR_BIT) {
734 struct gl_material *mat = &ctx->Light.Material[1];
735 SUB_3V( tmp, color, mat->Specular );
736 foreach (light, list) {
737 if (light->Flags & LIGHT_SPECULAR) {
738 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
739 light->IsMatSpecular[1] =
740 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
741 }
742 }
743 COPY_4FV( mat->Specular, color );
744 }
745 if (bitmask & FRONT_EMISSION_BIT) {
746 struct gl_material *mat = &ctx->Light.Material[0];
747 SUB_3V( tmp, color, mat->Emission );
748 ACC_3V( ctx->Light.BaseColor[0], tmp );
749 COPY_4FV( mat->Emission, color );
750 }
751 if (bitmask & BACK_EMISSION_BIT) {
752 struct gl_material *mat = &ctx->Light.Material[1];
753 SUB_3V( tmp, color, mat->Emission );
754 ACC_3V( ctx->Light.BaseColor[1], tmp );
755 COPY_4FV( mat->Emission, color );
756 }
757
758 if (0)
759 {
760 struct gl_material *mat = &ctx->Light.Material[0];
761 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
762 mat->Emission[0],
763 mat->Emission[1],
764 mat->Emission[2]);
765 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
766 mat->Specular[0],
767 mat->Specular[1],
768 mat->Specular[2]);
769 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
770 mat->Diffuse[0],
771 mat->Diffuse[1],
772 mat->Diffuse[2]);
773 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
774 mat->Ambient[0],
775 mat->Ambient[1],
776 mat->Ambient[2]);
777 }
778 }
779
780
781
782
783 void
784 _mesa_ColorMaterial( GLenum face, GLenum mode )
785 {
786 GET_CURRENT_CONTEXT(ctx);
787 GLuint bitmask;
788 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
789 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
790 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
791 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
792
793 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
794
795 if (MESA_VERBOSE&VERBOSE_API)
796 fprintf(stderr, "glColorMaterial %s %s\n",
797 gl_lookup_enum_by_nr(face),
798 gl_lookup_enum_by_nr(mode));
799
800 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
801
802 if (bitmask != 0) {
803 ctx->Light.ColorMaterialBitmask = bitmask;
804 ctx->Light.ColorMaterialFace = face;
805 ctx->Light.ColorMaterialMode = mode;
806 }
807
808 if (ctx->Light.ColorMaterialEnabled)
809 gl_update_color_material( ctx, ctx->Current.ByteColor );
810 }
811
812
813
814
815 void
816 _mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
817 {
818 _mesa_Materialfv( face, pname, &param );
819 }
820
821
822 /* KW: This is now called directly (ie by name) from the glMaterial*
823 * API functions.
824 */
825 void
826 _mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
827 {
828 GET_CURRENT_CONTEXT(ctx);
829 struct immediate *IM;
830 struct gl_material *mat;
831 GLuint bitmask;
832 GLuint count;
833
834 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
835 if (bitmask == 0)
836 return;
837
838 IM = ctx->input;
839 count = IM->Count;
840
841 if (!IM->Material) {
842 IM->Material =
843 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
844 VB_SIZE * 2 );
845 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
846 }
847
848
849 if (!(IM->Flag[count] & VERT_MATERIAL)) {
850 IM->Flag[count] |= VERT_MATERIAL;
851 IM->MaterialMask[count] = 0;
852 }
853
854
855 IM->MaterialMask[count] |= bitmask;
856 mat = IM->Material[count];
857
858 if (bitmask & FRONT_AMBIENT_BIT) {
859 COPY_4FV( mat[0].Ambient, params );
860 }
861 if (bitmask & BACK_AMBIENT_BIT) {
862 COPY_4FV( mat[1].Ambient, params );
863 }
864 if (bitmask & FRONT_DIFFUSE_BIT) {
865 COPY_4FV( mat[0].Diffuse, params );
866 }
867 if (bitmask & BACK_DIFFUSE_BIT) {
868 COPY_4FV( mat[1].Diffuse, params );
869 }
870 if (bitmask & FRONT_SPECULAR_BIT) {
871 COPY_4FV( mat[0].Specular, params );
872 }
873 if (bitmask & BACK_SPECULAR_BIT) {
874 COPY_4FV( mat[1].Specular, params );
875 }
876 if (bitmask & FRONT_EMISSION_BIT) {
877 COPY_4FV( mat[0].Emission, params );
878 }
879 if (bitmask & BACK_EMISSION_BIT) {
880 COPY_4FV( mat[1].Emission, params );
881 }
882 if (bitmask & FRONT_SHININESS_BIT) {
883 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
884 mat[0].Shininess = shininess;
885 }
886 if (bitmask & BACK_SHININESS_BIT) {
887 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
888 mat[1].Shininess = shininess;
889 }
890 if (bitmask & FRONT_INDEXES_BIT) {
891 mat[0].AmbientIndex = params[0];
892 mat[0].DiffuseIndex = params[1];
893 mat[0].SpecularIndex = params[2];
894 }
895 if (bitmask & BACK_INDEXES_BIT) {
896 mat[1].AmbientIndex = params[0];
897 mat[1].DiffuseIndex = params[1];
898 mat[1].SpecularIndex = params[2];
899 }
900 }
901
902
903 void
904 _mesa_Materiali(GLenum face, GLenum pname, GLint param )
905 {
906 _mesa_Materialiv(face, pname, &param);
907 }
908
909
910 void
911 _mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
912 {
913 GLfloat fparam[4];
914 switch (pname) {
915 case GL_AMBIENT:
916 case GL_DIFFUSE:
917 case GL_SPECULAR:
918 case GL_EMISSION:
919 case GL_AMBIENT_AND_DIFFUSE:
920 fparam[0] = INT_TO_FLOAT( params[0] );
921 fparam[1] = INT_TO_FLOAT( params[1] );
922 fparam[2] = INT_TO_FLOAT( params[2] );
923 fparam[3] = INT_TO_FLOAT( params[3] );
924 break;
925 case GL_SHININESS:
926 fparam[0] = (GLfloat) params[0];
927 break;
928 case GL_COLOR_INDEXES:
929 fparam[0] = (GLfloat) params[0];
930 fparam[1] = (GLfloat) params[1];
931 fparam[2] = (GLfloat) params[2];
932 break;
933 default:
934 /* Error will be caught later in gl_Materialfv */
935 ;
936 }
937 _mesa_Materialfv(face, pname, fparam);
938 }
939
940
941 void
942 _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
943 {
944 GET_CURRENT_CONTEXT(ctx);
945 GLuint f;
946
947 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
948
949 if (face==GL_FRONT) {
950 f = 0;
951 }
952 else if (face==GL_BACK) {
953 f = 1;
954 }
955 else {
956 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
957 return;
958 }
959 switch (pname) {
960 case GL_AMBIENT:
961 COPY_4FV( params, ctx->Light.Material[f].Ambient );
962 break;
963 case GL_DIFFUSE:
964 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
965 break;
966 case GL_SPECULAR:
967 COPY_4FV( params, ctx->Light.Material[f].Specular );
968 break;
969 case GL_EMISSION:
970 COPY_4FV( params, ctx->Light.Material[f].Emission );
971 break;
972 case GL_SHININESS:
973 *params = ctx->Light.Material[f].Shininess;
974 break;
975 case GL_COLOR_INDEXES:
976 params[0] = ctx->Light.Material[f].AmbientIndex;
977 params[1] = ctx->Light.Material[f].DiffuseIndex;
978 params[2] = ctx->Light.Material[f].SpecularIndex;
979 break;
980 default:
981 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
982 }
983 }
984
985
986
987 void
988 _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
989 {
990 GET_CURRENT_CONTEXT(ctx);
991 GLuint f;
992
993 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
994
995 if (face==GL_FRONT) {
996 f = 0;
997 }
998 else if (face==GL_BACK) {
999 f = 1;
1000 }
1001 else {
1002 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
1003 return;
1004 }
1005 switch (pname) {
1006 case GL_AMBIENT:
1007 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
1008 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
1009 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
1010 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
1011 break;
1012 case GL_DIFFUSE:
1013 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
1014 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
1015 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
1016 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
1017 break;
1018 case GL_SPECULAR:
1019 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
1020 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
1021 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
1022 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
1023 break;
1024 case GL_EMISSION:
1025 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
1026 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
1027 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
1028 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
1029 break;
1030 case GL_SHININESS:
1031 *params = ROUNDF( ctx->Light.Material[f].Shininess );
1032 break;
1033 case GL_COLOR_INDEXES:
1034 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
1035 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
1036 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
1037 break;
1038 default:
1039 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1040 }
1041 }
1042
1043
1044
1045
1046 /**********************************************************************/
1047 /***** Lighting computation *****/
1048 /**********************************************************************/
1049
1050
1051 /*
1052 * Notes:
1053 * When two-sided lighting is enabled we compute the color (or index)
1054 * for both the front and back side of the primitive. Then, when the
1055 * orientation of the facet is later learned, we can determine which
1056 * color (or index) to use for rendering.
1057 *
1058 * KW: We now know orientation in advance and only shade for
1059 * the side or sides which are actually required.
1060 *
1061 * Variables:
1062 * n = normal vector
1063 * V = vertex position
1064 * P = light source position
1065 * Pe = (0,0,0,1)
1066 *
1067 * Precomputed:
1068 * IF P[3]==0 THEN
1069 * // light at infinity
1070 * IF local_viewer THEN
1071 * VP_inf_norm = unit vector from V to P // Precompute
1072 * ELSE
1073 * // eye at infinity
1074 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1075 * ENDIF
1076 * ENDIF
1077 *
1078 * Functions:
1079 * Normalize( v ) = normalized vector v
1080 * Magnitude( v ) = length of vector v
1081 */
1082
1083
1084
1085 /*
1086 * Whenever the spotlight exponent for a light changes we must call
1087 * this function to recompute the exponent lookup table.
1088 */
1089 void gl_compute_spot_exp_table( struct gl_light *l )
1090 {
1091 int i;
1092 double exponent = l->SpotExponent;
1093 double tmp = 0;
1094 int clamp = 0;
1095
1096 l->SpotExpTable[0][0] = 0.0;
1097
1098 for (i=EXP_TABLE_SIZE-1;i>0;i--) {
1099 if (clamp == 0) {
1100 tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
1101 if (tmp < FLT_MIN*100.0) {
1102 tmp = 0.0;
1103 clamp = 1;
1104 }
1105 }
1106 l->SpotExpTable[i][0] = tmp;
1107 }
1108 for (i=0;i<EXP_TABLE_SIZE-1;i++) {
1109 l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
1110 }
1111 l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
1112 }
1113
1114
1115
1116
1117 /* Calculate a new shine table. Doing this here saves a branch in
1118 * lighting, and the cost of doing it early may be partially offset
1119 * by keeping a MRU cache of shine tables for various shine values.
1120 */
1121 static void compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
1122 {
1123 int i;
1124 GLfloat *m = tab->tab;
1125
1126 m[0] = 0;
1127 if (shininess == 0) {
1128 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
1129 m[i] = 1;
1130 } else {
1131 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) {
1132 double t = pow( i/(GLfloat)SHINE_TABLE_SIZE, shininess );
1133 m[i] = 0;
1134 if (t > 1e-20) m[i] = t;
1135 }
1136 }
1137
1138 tab->shininess = shininess;
1139 }
1140
1141 #define DISTSQR(a,b) ((a-b)*(a-b))
1142
1143 void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
1144 {
1145 struct gl_shine_tab *list = ctx->ShineTabList;
1146 struct gl_shine_tab *s;
1147
1148 foreach(s, list)
1149 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
1150 break;
1151
1152 if (s == list)
1153 {
1154 foreach(s, list)
1155 if (s->refcount == 0) break;
1156
1157 compute_shine_table( s, shininess );
1158 }
1159
1160 ctx->ShineTable[i]->refcount--;
1161 ctx->ShineTable[i] = s;
1162 move_to_tail( list, s );
1163 s->refcount++;
1164 }
1165
1166
1167
1168 #if 0
1169 static void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
1170 {
1171 GLuint i;
1172
1173 if (ctx->ShineTable[0]->shininess != l->Material[0].Shininess) {
1174 gl_compute_shine_table( ctx, 0, l->Material[0].Shininess );
1175 gl_compute_shine_table( ctx, 2, l->Material[0].Shininess * .5 );
1176 }
1177
1178 if (ctx->ShineTable[1]->shininess != l->Material[1].Shininess) {
1179 gl_compute_shine_table( ctx, 1, l->Material[1].Shininess );
1180 gl_compute_shine_table( ctx, 3, l->Material[1].Shininess * .5 );
1181 }
1182
1183 make_empty_list( &l->EnabledList );
1184 for (i = 0 ; i < MAX_LIGHTS ; i++) {
1185 if (l->Light[i].Enabled)
1186 insert_at_tail( &l->EnabledList, &l->Light[i] );
1187 }
1188 }
1189 #endif
1190
1191
1192 /*
1193 * Examine current lighting parameters to determine if the optimized lighting
1194 * function can be used.
1195 * Also, precompute some lighting values such as the products of light
1196 * source and material ambient, diffuse and specular coefficients.
1197 */
1198 void gl_update_lighting( GLcontext *ctx )
1199 {
1200 struct gl_light *light;
1201
1202 ctx->Light.Flags = 0;
1203
1204 foreach(light, &ctx->Light.EnabledList) {
1205
1206 light->Flags = 0;
1207
1208 if (light->EyePosition[3] != 0.0F)
1209 light->Flags |= LIGHT_POSITIONAL;
1210
1211 if (LEN_SQUARED_3FV(light->Specular) > 1e-16)
1212 light->Flags |= LIGHT_SPECULAR;
1213
1214 if (light->SpotCutoff != 180.0F)
1215 light->Flags |= LIGHT_SPOT;
1216
1217 ctx->Light.Flags |= light->Flags;
1218 }
1219
1220 ctx->Light.NeedVertices =
1221 ((ctx->Light.Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
1222 (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
1223 (ctx->Light.Model.LocalViewer && (ctx->Light.Flags & LIGHT_SPECULAR)));
1224
1225
1226 /* Precompute some shading values.
1227 */
1228 if (ctx->Visual->RGBAflag)
1229 {
1230 GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
1231 GLuint side;
1232 for (side=0; side < sides; side++) {
1233 struct gl_material *mat = &ctx->Light.Material[side];
1234
1235 COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
1236 ACC_SCALE_3V(ctx->Light.BaseColor[side],
1237 ctx->Light.Model.Ambient,
1238 mat->Ambient);
1239
1240 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[side],
1241 ctx->Light.Material[side].Diffuse[3] );
1242 }
1243
1244 foreach (light, &ctx->Light.EnabledList) {
1245 for (side=0; side< sides; side++) {
1246 struct gl_material *mat = &ctx->Light.Material[side];
1247 SCALE_3V( light->MatDiffuse[side], light->Diffuse, mat->Diffuse );
1248 SCALE_3V( light->MatAmbient[side], light->Ambient, mat->Ambient );
1249 ACC_3V( ctx->Light.BaseColor[side], light->MatAmbient[side] );
1250 if (light->Flags & LIGHT_SPECULAR)
1251 {
1252 SCALE_3V( light->MatSpecular[side], light->Specular,
1253 mat->Specular);
1254 light->IsMatSpecular[side] =
1255 (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
1256 }
1257 else
1258 light->IsMatSpecular[side] = 0;
1259 }
1260 }
1261 }
1262 else
1263 {
1264 static GLfloat ci[3] = { .30, .59, .11 };
1265
1266 foreach(light, &ctx->Light.EnabledList) {
1267 light->dli = DOT3(ci, light->Diffuse);
1268 light->sli = DOT3(ci, light->Specular);
1269 }
1270 }
1271 }
1272
1273 /* Need to seriously restrict the circumstances under which these
1274 * calc's are performed.
1275 */
1276 void gl_compute_light_positions( GLcontext *ctx )
1277 {
1278 struct gl_light *light;
1279
1280 if (ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer) {
1281 GLfloat eye_z[3] = { 0, 0, 1 };
1282 if (!ctx->NeedEyeCoords) {
1283 TRANSFORM_NORMAL( ctx->EyeZDir, eye_z, ctx->ModelView.m );
1284 } else {
1285 COPY_3V( ctx->EyeZDir, eye_z );
1286 }
1287 }
1288
1289 foreach (light, &ctx->Light.EnabledList) {
1290
1291 if (!ctx->NeedEyeCoords) {
1292 TRANSFORM_POINT( light->Position, ctx->ModelView.inv,
1293 light->EyePosition );
1294 } else {
1295 COPY_4FV( light->Position, light->EyePosition );
1296 }
1297
1298 if (!(light->Flags & LIGHT_POSITIONAL))
1299 {
1300 /* VP (VP) = Normalize( Position ) */
1301 COPY_3V( light->VP_inf_norm, light->Position );
1302 NORMALIZE_3FV( light->VP_inf_norm );
1303
1304 if (!ctx->Light.Model.LocalViewer)
1305 {
1306 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1307 ADD_3V( light->h_inf_norm, light->VP_inf_norm, ctx->EyeZDir);
1308 NORMALIZE_3FV( light->h_inf_norm );
1309 }
1310
1311 light->VP_inf_spot_attenuation = 1.0;
1312 }
1313
1314 if (light->Flags & LIGHT_SPOT)
1315 {
1316 if (ctx->NeedEyeNormals) {
1317 COPY_3V( light->NormDirection, light->EyeDirection );
1318 } else {
1319 TRANSFORM_NORMAL( light->NormDirection,
1320 light->EyeDirection,
1321 ctx->ModelView.m);
1322 }
1323
1324 NORMALIZE_3FV( light->NormDirection );
1325
1326
1327 /* Unlikely occurrance?
1328 */
1329 if (!(light->Flags & LIGHT_POSITIONAL)) {
1330 GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm,
1331 light->NormDirection);
1332
1333 if (PV_dot_dir > light->CosCutoff) {
1334 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1335 int k = (int) x;
1336 light->VP_inf_spot_attenuation =
1337 (light->SpotExpTable[k][0] +
1338 (x-k)*light->SpotExpTable[k][1]);
1339 }
1340 else
1341 light->VP_inf_spot_attenuation = 0;
1342 }
1343 }
1344 }
1345 }
1346
1347
1348
1349
1350
1351 void gl_update_normal_transform( GLcontext *ctx )
1352 {
1353 GLuint new_flag = 0;
1354 normal_func *last = ctx->NormalTransform;
1355
1356 ctx->vb_rescale_factor = 1.0;
1357
1358 if (ctx->NeedEyeCoords) {
1359 if (ctx->NeedNormals) {
1360 GLuint transform = NORM_TRANSFORM_NO_ROT;
1361
1362 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1363 MAT_FLAG_ROTATION |
1364 MAT_FLAG_GENERAL_3D |
1365 MAT_FLAG_PERSPECTIVE))
1366 transform = NORM_TRANSFORM;
1367
1368
1369 new_flag = ctx->NewState & NEW_MODELVIEW;
1370 ctx->vb_rescale_factor = ctx->rescale_factor;
1371
1372 if (ctx->Transform.Normalize)
1373 {
1374 ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
1375 }
1376 else if (ctx->Transform.RescaleNormals &&
1377 ctx->rescale_factor != 1.0)
1378 {
1379 ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
1380 }
1381 else
1382 {
1383 ctx->NormalTransform = gl_normal_tab[transform];
1384 }
1385 } else {
1386 ctx->NormalTransform = 0;
1387 }
1388 }
1389 else {
1390 if (ctx->NeedNormals) {
1391 ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
1392
1393 if (ctx->Transform.Normalize)
1394 {
1395 ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
1396 }
1397 else if (!ctx->Transform.RescaleNormals &&
1398 ctx->rescale_factor != 1.0)
1399 {
1400 ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
1401 }
1402 else
1403 {
1404 ctx->NormalTransform = 0;
1405 }
1406 } else {
1407 ctx->NormalTransform = 0;
1408 }
1409 }
1410
1411 if (last != ctx->NormalTransform || new_flag)
1412 ctx->NewState |= NEW_NORMAL_TRANSFORM;
1413 }
1414