source: trunk/src/opengl/mesa/light.c

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

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