ReactOS 0.4.16-dev-303-g11d5cb8
light.c
Go to the documentation of this file.
1/* $Id: light.c,v 1.14 1997/07/24 01:24:11 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 2.4
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24/*
25 * $Log: light.c,v $
26 * Revision 1.14 1997/07/24 01:24:11 brianp
27 * changed precompiled header symbol from PCH to PC_HEADER
28 *
29 * Revision 1.13 1997/06/20 04:15:43 brianp
30 * optimized changing of SHININESS (Henk Kok)
31 *
32 * Revision 1.12 1997/05/28 03:25:26 brianp
33 * added precompiled header (PCH) support
34 *
35 * Revision 1.11 1997/05/01 01:38:57 brianp
36 * now use NORMALIZE_3FV() macro from mmath.h
37 *
38 * Revision 1.10 1997/04/20 20:28:49 brianp
39 * replaced abort() with gl_problem()
40 *
41 * Revision 1.9 1997/04/07 02:59:17 brianp
42 * small optimization to setting of shininess and spot exponent
43 *
44 * Revision 1.8 1997/04/01 04:09:31 brianp
45 * misc code clean-ups. moved shading code to shade.c
46 *
47 * Revision 1.7 1997/03/11 00:37:39 brianp
48 * spotlight factor now effects ambient lighting
49 *
50 * Revision 1.6 1996/12/18 20:02:07 brianp
51 * glColorMaterial() and glMaterial() should finally work right!
52 *
53 * Revision 1.5 1996/12/07 10:22:41 brianp
54 * gl_Materialfv() now calls gl_set_material() if GL_COLOR_MATERIAL disabled
55 * implemented gl_GetLightiv()
56 *
57 * Revision 1.4 1996/11/08 04:39:23 brianp
58 * new gl_compute_spot_exp_table() contributed by Randy Frank
59 *
60 * Revision 1.3 1996/09/27 01:27:55 brianp
61 * removed unused variables
62 *
63 * Revision 1.2 1996/09/15 14:18:10 brianp
64 * now use GLframebuffer and GLvisual
65 *
66 * Revision 1.1 1996/09/13 01:38:16 brianp
67 * Initial revision
68 *
69 */
70
71
72#ifdef PC_HEADER
73#include "all.h"
74#else
75#include <assert.h>
76#include <float.h>
77#include <math.h>
78#include <stdlib.h>
79#include "context.h"
80#include "light.h"
81#include "dlist.h"
82#include "macros.h"
83#include "matrix.h"
84#include "mmath.h"
85#include "types.h"
86#include "vb.h"
87#include "xform.h"
88#endif
89
90
91
93{
94 if (INSIDE_BEGIN_END(ctx)) {
95 gl_error( ctx, GL_INVALID_OPERATION, "glShadeModel" );
96 return;
97 }
98
99 switch (mode) {
100 case GL_FLAT:
101 case GL_SMOOTH:
102 if (ctx->Light.ShadeModel!=mode) {
103 ctx->Light.ShadeModel = mode;
104 ctx->NewState |= NEW_RASTER_OPS;
105 }
106 break;
107 default:
108 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
109 }
110}
111
112
113
116 GLint nparams )
117{
118 GLint l;
119
120 if (INSIDE_BEGIN_END(ctx)) {
121 gl_error( ctx, GL_INVALID_OPERATION, "glShadeModel" );
122 return;
123 }
124
125 l = (GLint) (light - GL_LIGHT0);
126
127 if (l<0 || l>=MAX_LIGHTS) {
128 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
129 return;
130 }
131
132 switch (pname) {
133 case GL_AMBIENT:
134 COPY_4V( ctx->Light.Light[l].Ambient, params );
135 break;
136 case GL_DIFFUSE:
137 COPY_4V( ctx->Light.Light[l].Diffuse, params );
138 break;
139 case GL_SPECULAR:
140 COPY_4V( ctx->Light.Light[l].Specular, params );
141 break;
142 case GL_POSITION:
143 /* transform position by ModelView matrix */
144 TRANSFORM_POINT( ctx->Light.Light[l].Position, ctx->ModelViewMatrix,
145 params );
146 break;
148 /* transform direction by inverse modelview */
149 {
150 GLfloat direction[4];
151 direction[0] = params[0];
152 direction[1] = params[1];
153 direction[2] = params[2];
154 direction[3] = 0.0;
155 if (ctx->NewModelViewMatrix) {
157 }
158 gl_transform_vector( ctx->Light.Light[l].Direction,
159 direction, ctx->ModelViewInv);
160 }
161 break;
162 case GL_SPOT_EXPONENT:
163 if (params[0]<0.0 || params[0]>128.0) {
164 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
165 return;
166 }
167 if (ctx->Light.Light[l].SpotExponent != params[0]) {
168 ctx->Light.Light[l].SpotExponent = params[0];
169 gl_compute_spot_exp_table( &ctx->Light.Light[l] );
170 }
171 break;
172 case GL_SPOT_CUTOFF:
173 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
174 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
175 return;
176 }
177 ctx->Light.Light[l].SpotCutoff = params[0];
178 ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
179 break;
181 if (params[0]<0.0) {
182 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
183 return;
184 }
185 ctx->Light.Light[l].ConstantAttenuation = params[0];
186 break;
188 if (params[0]<0.0) {
189 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
190 return;
191 }
192 ctx->Light.Light[l].LinearAttenuation = params[0];
193 break;
195 if (params[0]<0.0) {
196 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
197 return;
198 }
199 ctx->Light.Light[l].QuadraticAttenuation = params[0];
200 break;
201 default:
202 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
203 break;
204 }
205
206 ctx->NewState |= NEW_LIGHTING;
207}
208
209
210
213{
214 GLint l = (GLint) (light - GL_LIGHT0);
215
216 if (l<0 || l>=MAX_LIGHTS) {
217 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
218 return;
219 }
220
221 switch (pname) {
222 case GL_AMBIENT:
223 COPY_4V( params, ctx->Light.Light[l].Ambient );
224 break;
225 case GL_DIFFUSE:
226 COPY_4V( params, ctx->Light.Light[l].Diffuse );
227 break;
228 case GL_SPECULAR:
229 COPY_4V( params, ctx->Light.Light[l].Specular );
230 break;
231 case GL_POSITION:
232 COPY_4V( params, ctx->Light.Light[l].Position );
233 break;
235 COPY_3V( params, ctx->Light.Light[l].Direction );
236 break;
237 case GL_SPOT_EXPONENT:
238 params[0] = ctx->Light.Light[l].SpotExponent;
239 break;
240 case GL_SPOT_CUTOFF:
241 params[0] = ctx->Light.Light[l].SpotCutoff;
242 break;
244 params[0] = ctx->Light.Light[l].ConstantAttenuation;
245 break;
247 params[0] = ctx->Light.Light[l].LinearAttenuation;
248 break;
250 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
251 break;
252 default:
253 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
254 break;
255 }
256}
257
258
259
261{
262 GLint l = (GLint) (light - GL_LIGHT0);
263
264 if (l<0 || l>=MAX_LIGHTS) {
265 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
266 return;
267 }
268
269 switch (pname) {
270 case GL_AMBIENT:
271 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
272 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
273 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
274 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
275 break;
276 case GL_DIFFUSE:
277 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
278 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
279 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
280 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
281 break;
282 case GL_SPECULAR:
283 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
284 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
285 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
286 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
287 break;
288 case GL_POSITION:
289 params[0] = ctx->Light.Light[l].Position[0];
290 params[1] = ctx->Light.Light[l].Position[1];
291 params[2] = ctx->Light.Light[l].Position[2];
292 params[3] = ctx->Light.Light[l].Position[3];
293 break;
295 params[0] = ctx->Light.Light[l].Direction[0];
296 params[1] = ctx->Light.Light[l].Direction[1];
297 params[2] = ctx->Light.Light[l].Direction[2];
298 break;
299 case GL_SPOT_EXPONENT:
300 params[0] = ctx->Light.Light[l].SpotExponent;
301 break;
302 case GL_SPOT_CUTOFF:
303 params[0] = ctx->Light.Light[l].SpotCutoff;
304 break;
306 params[0] = ctx->Light.Light[l].ConstantAttenuation;
307 break;
309 params[0] = ctx->Light.Light[l].LinearAttenuation;
310 break;
312 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
313 break;
314 default:
315 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
316 break;
317 }
318}
319
320
321
322/**********************************************************************/
323/*** Light Model ***/
324/**********************************************************************/
325
326
328{
329 switch (pname) {
331 COPY_4V( ctx->Light.Model.Ambient, params );
332 break;
334 if (params[0]==0.0)
335 ctx->Light.Model.LocalViewer = GL_FALSE;
336 else
337 ctx->Light.Model.LocalViewer = GL_TRUE;
338 break;
340 if (params[0]==0.0)
341 ctx->Light.Model.TwoSide = GL_FALSE;
342 else
343 ctx->Light.Model.TwoSide = GL_TRUE;
344 break;
345 default:
346 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
347 break;
348 }
349 ctx->NewState |= NEW_LIGHTING;
350}
351
352
353
354
355/********** MATERIAL **********/
356
357
358/*
359 * Given a face and pname value (ala glColorMaterial), compute a bitmask
360 * of the targeted material values.
361 */
363{
364 GLuint bitmask = 0;
365
366 /* Make a bitmask indicating what material attribute(s) we're updating */
367 switch (pname) {
368 case GL_EMISSION:
370 break;
371 case GL_AMBIENT:
373 break;
374 case GL_DIFFUSE:
376 break;
377 case GL_SPECULAR:
379 break;
380 case GL_SHININESS:
382 break;
386 break;
387 case GL_COLOR_INDEXES:
389 break;
390 default:
391 gl_problem(NULL, "Bad param in gl_material_bitmask");
392 return 0;
393 }
394
396
397 if (face==GL_FRONT) {
398 bitmask &= FRONT_MATERIAL_BITS;
399 }
400 else if (face==GL_BACK) {
401 bitmask &= BACK_MATERIAL_BITS;
402 }
403
404 return bitmask;
405}
406
407
408
409/*
410 * This is called by glColor() when GL_COLOR_MATERIAL is enabled and
411 * called by glMaterial() when GL_COLOR_MATERIAL is disabled.
412 */
414{
415 struct gl_material *mat;
416
417 if (INSIDE_BEGIN_END(ctx)) {
418 struct vertex_buffer *VB = ctx->VB;
419 /* Save per-vertex material changes in the Vertex Buffer.
420 * The update_material function will eventually update the global
421 * ctx->Light.Material values.
422 */
423 mat = VB->Material[VB->Count];
424 VB->MaterialMask[VB->Count] |= bitmask;
425 VB->MonoMaterial = GL_FALSE;
426 }
427 else {
428 /* just update the global material property */
429 mat = ctx->Light.Material;
430 ctx->NewState |= NEW_LIGHTING;
431 }
432
433 if (bitmask & FRONT_AMBIENT_BIT) {
434 COPY_4V( mat[0].Ambient, params );
435 }
436 if (bitmask & BACK_AMBIENT_BIT) {
437 COPY_4V( mat[1].Ambient, params );
438 }
439 if (bitmask & FRONT_DIFFUSE_BIT) {
440 COPY_4V( mat[0].Diffuse, params );
441 }
442 if (bitmask & BACK_DIFFUSE_BIT) {
443 COPY_4V( mat[1].Diffuse, params );
444 }
445 if (bitmask & FRONT_SPECULAR_BIT) {
446 COPY_4V( mat[0].Specular, params );
447 }
448 if (bitmask & BACK_SPECULAR_BIT) {
449 COPY_4V( mat[1].Specular, params );
450 }
451 if (bitmask & FRONT_EMISSION_BIT) {
452 COPY_4V( mat[0].Emission, params );
453 }
454 if (bitmask & BACK_EMISSION_BIT) {
455 COPY_4V( mat[1].Emission, params );
456 }
457 if (bitmask & FRONT_SHININESS_BIT) {
458 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
459 if (mat[0].Shininess != shininess) {
460 mat[0].Shininess = shininess;
462 }
463 }
464 if (bitmask & BACK_SHININESS_BIT) {
465 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
466 if (mat[1].Shininess != shininess) {
467 mat[1].Shininess = shininess;
469 }
470 }
471 if (bitmask & FRONT_INDEXES_BIT) {
472 mat[0].AmbientIndex = params[0];
473 mat[0].DiffuseIndex = params[1];
474 mat[0].SpecularIndex = params[2];
475 }
476 if (bitmask & BACK_INDEXES_BIT) {
477 mat[1].AmbientIndex = params[0];
478 mat[1].DiffuseIndex = params[1];
479 mat[1].SpecularIndex = params[2];
480 }
481}
482
483
484
486{
487 if (INSIDE_BEGIN_END(ctx)) {
488 gl_error( ctx, GL_INVALID_OPERATION, "glColorMaterial" );
489 return;
490 }
491 switch (face) {
492 case GL_FRONT:
493 case GL_BACK:
495 ctx->Light.ColorMaterialFace = face;
496 break;
497 default:
498 gl_error( ctx, GL_INVALID_ENUM, "glColorMaterial(face)" );
499 return;
500 }
501 switch (mode) {
502 case GL_EMISSION:
503 case GL_AMBIENT:
504 case GL_DIFFUSE:
505 case GL_SPECULAR:
507 ctx->Light.ColorMaterialMode = mode;
508 break;
509 default:
510 gl_error( ctx, GL_INVALID_ENUM, "glColorMaterial(mode)" );
511 return;
512 }
513
514 ctx->Light.ColorMaterialBitmask = gl_material_bitmask( face, mode );
515}
516
517
518
519/*
520 * This is only called via the api_function_table struct or by the
521 * display list executor.
522 */
525{
526 GLuint bitmask;
527
528 /* error checking */
530 gl_error( ctx, GL_INVALID_ENUM, "glMaterial(face)" );
531 return;
532 }
533 switch (pname) {
534 case GL_EMISSION:
535 case GL_AMBIENT:
536 case GL_DIFFUSE:
537 case GL_SPECULAR:
538 case GL_SHININESS:
540 case GL_COLOR_INDEXES:
541 /* OK */
542 break;
543 default:
544 gl_error( ctx, GL_INVALID_ENUM, "glMaterial(pname)" );
545 return;
546 }
547
548 /* convert face and pname to a bitmask */
549 bitmask = gl_material_bitmask( face, pname );
550
551 if (ctx->Light.ColorMaterialEnabled) {
552 /* The material values specified by glColorMaterial() can't be */
553 /* updated by glMaterial() while GL_COLOR_MATERIAL is enabled! */
554 bitmask &= ~ctx->Light.ColorMaterialBitmask;
555 }
556
557 gl_set_material( ctx, bitmask, params );
558}
559
560
561
562
565{
566 GLuint f;
567
568 if (INSIDE_BEGIN_END(ctx)) {
569 gl_error( ctx, GL_INVALID_OPERATION, "glGetMaterialfv" );
570 return;
571 }
572 if (face==GL_FRONT) {
573 f = 0;
574 }
575 else if (face==GL_BACK) {
576 f = 1;
577 }
578 else {
579 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
580 return;
581 }
582 switch (pname) {
583 case GL_AMBIENT:
584 COPY_4V( params, ctx->Light.Material[f].Ambient );
585 break;
586 case GL_DIFFUSE:
587 COPY_4V( params, ctx->Light.Material[f].Diffuse );
588 break;
589 case GL_SPECULAR:
590 COPY_4V( params, ctx->Light.Material[f].Specular );
591 break;
592 case GL_EMISSION:
593 COPY_4V( params, ctx->Light.Material[f].Emission );
594 break;
595 case GL_SHININESS:
596 *params = ctx->Light.Material[f].Shininess;
597 break;
598 case GL_COLOR_INDEXES:
599 params[0] = ctx->Light.Material[f].AmbientIndex;
600 params[1] = ctx->Light.Material[f].DiffuseIndex;
601 params[2] = ctx->Light.Material[f].SpecularIndex;
602 break;
603 default:
604 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
605 }
606}
607
608
609
612{
613 GLuint f;
614
615 if (INSIDE_BEGIN_END(ctx)) {
616 gl_error( ctx, GL_INVALID_OPERATION, "glGetMaterialiv" );
617 return;
618 }
619 if (face==GL_FRONT) {
620 f = 0;
621 }
622 else if (face==GL_BACK) {
623 f = 1;
624 }
625 else {
626 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
627 return;
628 }
629 switch (pname) {
630 case GL_AMBIENT:
631 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
632 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
633 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
634 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
635 break;
636 case GL_DIFFUSE:
637 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
638 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
639 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
640 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
641 break;
642 case GL_SPECULAR:
643 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
644 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
645 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
646 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
647 break;
648 case GL_EMISSION:
649 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
650 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
651 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
652 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
653 break;
654 case GL_SHININESS:
655 *params = ROUNDF( ctx->Light.Material[f].Shininess );
656 break;
657 case GL_COLOR_INDEXES:
658 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
659 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
660 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
661 break;
662 default:
663 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
664 }
665}
666
667
668
669
670/**********************************************************************/
671/***** Lighting computation *****/
672/**********************************************************************/
673
674
675/*
676 * Notes:
677 * When two-sided lighting is enabled we compute the color (or index)
678 * for both the front and back side of the primitive. Then, when the
679 * orientation of the facet is later learned, we can determine which
680 * color (or index) to use for rendering.
681 *
682 * Variables:
683 * n = normal vector
684 * V = vertex position
685 * P = light source position
686 * Pe = (0,0,0,1)
687 *
688 * Precomputed:
689 * IF P[3]==0 THEN
690 * // light at infinity
691 * IF local_viewer THEN
692 * VP_inf_norm = unit vector from V to P // Precompute
693 * ELSE
694 * // eye at infinity
695 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
696 * ENDIF
697 * ENDIF
698 *
699 * Functions:
700 * Normalize( v ) = normalized vector v
701 * Magnitude( v ) = length of vector v
702 */
703
704
705
706/*
707 * Whenever the spotlight exponent for a light changes we must call
708 * this function to recompute the exponent lookup table.
709 */
711{
712 int i;
713 double exponent = l->SpotExponent;
714 double tmp;
715 int clamp = 0;
716
717 l->SpotExpTable[0][0] = 0.0;
718
719 for (i=EXP_TABLE_SIZE-1;i>0;i--) {
720 if (clamp == 0) {
721 tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
722 if (tmp < FLT_MIN*100.0) {
723 tmp = 0.0;
724 clamp = 1;
725 }
726 }
727 l->SpotExpTable[i][0] = tmp;
728 }
729 for (i=0;i<EXP_TABLE_SIZE-1;i++) {
730 l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
731 }
732 l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
733}
734
735
736
737/*
738 * Whenever the shininess of a material changes we must call this
739 * function to recompute the exponential lookup table.
740 */
742{
743 int i;
744
745 m->ShineTable[0] = 0.0F;
746 for (i=1;i<SHINE_TABLE_SIZE;i++) {
747#if 0
748 double x = pow( i/(double)(SHINE_TABLE_SIZE-1), exponent );
749 if (x<1.0e-10) {
750 m->ShineTable[i] = 0.0F;
751 }
752 else {
753 m->ShineTable[i] = x;
754 }
755#else
756 /* just invalidate the table */
757 m->ShineTable[i] = -1.0;
758#endif
759 }
760}
761
762
763
764/*
765 * Examine current lighting parameters to determine if the optimized lighting
766 * function can be used.
767 * Also, precompute some lighting values such as the products of light
768 * source and material ambient, diffuse and specular coefficients.
769 */
771{
772 GLint i, side;
773 struct gl_light *prev_enabled, *light;
774
775 if (!ctx->Light.Enabled) {
776 /* If lighting is not enabled, we can skip all this. */
777 return;
778 }
779
780 /* Setup linked list of enabled light sources */
781 prev_enabled = NULL;
782 ctx->Light.FirstEnabled = NULL;
783 for (i=0;i<MAX_LIGHTS;i++) {
784 ctx->Light.Light[i].NextEnabled = NULL;
785 if (ctx->Light.Light[i].Enabled) {
786 if (prev_enabled) {
787 prev_enabled->NextEnabled = &ctx->Light.Light[i];
788 }
789 else {
790 ctx->Light.FirstEnabled = &ctx->Light.Light[i];
791 }
792 prev_enabled = &ctx->Light.Light[i];
793 }
794 }
795
796 /* base color = material_emission + global_ambient * material_ambient */
797 for (side=0; side<2; side++) {
798 ctx->Light.BaseColor[side][0] = ctx->Light.Material[side].Emission[0]
799 + ctx->Light.Model.Ambient[0] * ctx->Light.Material[side].Ambient[0];
800 ctx->Light.BaseColor[side][1] = ctx->Light.Material[side].Emission[1]
801 + ctx->Light.Model.Ambient[1] * ctx->Light.Material[side].Ambient[1];
802 ctx->Light.BaseColor[side][2] = ctx->Light.Material[side].Emission[2]
803 + ctx->Light.Model.Ambient[2] * ctx->Light.Material[side].Ambient[2];
804 ctx->Light.BaseColor[side][3]
805 = MIN2( ctx->Light.Material[side].Diffuse[3], 1.0F );
806 }
807
808
809 /* Precompute some lighting stuff */
810 for (light = ctx->Light.FirstEnabled; light; light = light->NextEnabled) {
811 for (side=0; side<2; side++) {
812 struct gl_material *mat = &ctx->Light.Material[side];
813 /* Add each light's ambient component to base color */
814 ctx->Light.BaseColor[side][0] += light->Ambient[0] * mat->Ambient[0];
815 ctx->Light.BaseColor[side][1] += light->Ambient[1] * mat->Ambient[1];
816 ctx->Light.BaseColor[side][2] += light->Ambient[2] * mat->Ambient[2];
817 /* compute product of light's ambient with front material ambient */
818 light->MatAmbient[side][0] = light->Ambient[0] * mat->Ambient[0];
819 light->MatAmbient[side][1] = light->Ambient[1] * mat->Ambient[1];
820 light->MatAmbient[side][2] = light->Ambient[2] * mat->Ambient[2];
821 /* compute product of light's diffuse with front material diffuse */
822 light->MatDiffuse[side][0] = light->Diffuse[0] * mat->Diffuse[0];
823 light->MatDiffuse[side][1] = light->Diffuse[1] * mat->Diffuse[1];
824 light->MatDiffuse[side][2] = light->Diffuse[2] * mat->Diffuse[2];
825 /* compute product of light's specular with front material specular */
826 light->MatSpecular[side][0] = light->Specular[0] * mat->Specular[0];
827 light->MatSpecular[side][1] = light->Specular[1] * mat->Specular[1];
828 light->MatSpecular[side][2] = light->Specular[2] * mat->Specular[2];
829
830 /* VP (VP) = Normalize( Position ) */
831 COPY_3V( light->VP_inf_norm, light->Position );
832 NORMALIZE_3FV( light->VP_inf_norm );
833
834 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
835 COPY_3V( light->h_inf_norm, light->VP_inf_norm );
836 light->h_inf_norm[2] += 1.0F;
837 NORMALIZE_3FV( light->h_inf_norm );
838
839 COPY_3V( light->NormDirection, light->Direction );
840 NORMALIZE_3FV( light->NormDirection );
841
842 /* Compute color index diffuse and specular light intensities */
843 light->dli = 0.30F * light->Diffuse[0]
844 + 0.59F * light->Diffuse[1]
845 + 0.11F * light->Diffuse[2];
846 light->sli = 0.30F * light->Specular[0]
847 + 0.59F * light->Specular[1]
848 + 0.11F * light->Specular[2];
849
850 } /* loop over materials */
851 } /* loop over lights */
852
853 /* Determine if the fast lighting function can be used */
854 ctx->Light.Fast = GL_TRUE;
855 if ( ctx->Light.BaseColor[0][0]<0.0F
856 || ctx->Light.BaseColor[0][1]<0.0F
857 || ctx->Light.BaseColor[0][2]<0.0F
858 || ctx->Light.BaseColor[0][3]<0.0F
859 || ctx->Light.BaseColor[1][0]<0.0F
860 || ctx->Light.BaseColor[1][1]<0.0F
861 || ctx->Light.BaseColor[1][2]<0.0F
862 || ctx->Light.BaseColor[1][3]<0.0F
863 || ctx->Light.Model.LocalViewer
864 || ctx->Light.ColorMaterialEnabled) {
865 ctx->Light.Fast = GL_FALSE;
866 }
867 else {
868 for (light=ctx->Light.FirstEnabled; light; light=light->NextEnabled) {
869 if ( light->Position[3]!=0.0F
870 || light->SpotCutoff!=180.0F
871 || light->MatDiffuse[0][0]<0.0F
872 || light->MatDiffuse[0][1]<0.0F
873 || light->MatDiffuse[0][2]<0.0F
874 || light->MatSpecular[0][0]<0.0F
875 || light->MatSpecular[0][1]<0.0F
876 || light->MatSpecular[0][2]<0.0F
877 || light->MatDiffuse[1][0]<0.0F
878 || light->MatDiffuse[1][1]<0.0F
879 || light->MatDiffuse[1][2]<0.0F
880 || light->MatSpecular[1][0]<0.0F
881 || light->MatSpecular[1][1]<0.0F
882 || light->MatSpecular[1][2]<0.0F) {
883 ctx->Light.Fast = GL_FALSE;
884 break;
885 }
886 }
887 }
888}
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
#define DEG2RAD(degree)
Definition: precomp.h:76
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
WORD face[3]
Definition: mesh.c:4747
#define MAX_LIGHTS
Definition: config.h:84
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
void gl_error(GLcontext *ctx, GLenum error, const char *s)
Definition: context.c:1421
void gl_analyze_modelview_matrix(GLcontext *ctx)
Definition: matrix.c:420
#define FRONT_SHININESS_BIT
Definition: types.h:537
#define FRONT_SPECULAR_BIT
Definition: types.h:533
#define FRONT_INDEXES_BIT
Definition: types.h:539
#define FRONT_DIFFUSE_BIT
Definition: types.h:531
#define BACK_MATERIAL_BITS
Definition: types.h:546
#define BACK_INDEXES_BIT
Definition: types.h:540
#define NEW_LIGHTING
Definition: types.h:1232
#define BACK_EMISSION_BIT
Definition: types.h:536
#define SHINE_TABLE_SIZE
Definition: types.h:558
#define BACK_AMBIENT_BIT
Definition: types.h:530
#define FRONT_MATERIAL_BITS
Definition: types.h:542
#define FRONT_AMBIENT_BIT
Definition: types.h:529
#define EXP_TABLE_SIZE
Definition: types.h:557
#define BACK_DIFFUSE_BIT
Definition: types.h:532
#define NEW_RASTER_OPS
Definition: types.h:1233
#define BACK_SPECULAR_BIT
Definition: types.h:534
#define BACK_SHININESS_BIT
Definition: types.h:538
#define FRONT_EMISSION_BIT
Definition: types.h:535
double pow(double x, double y)
Definition: freeldr.c:110
#define FLT_MIN
Definition: gcc_float.h:124
#define GL_DIFFUSE
Definition: gl.h:325
#define GL_TRUE
Definition: gl.h:174
#define GL_INVALID_VALUE
Definition: gl.h:695
#define GL_POSITION
Definition: gl.h:329
#define GL_SHININESS
Definition: gl.h:327
#define GL_COLOR_INDEXES
Definition: gl.h:332
#define GL_AMBIENT_AND_DIFFUSE
Definition: gl.h:331
float GLfloat
Definition: gl.h:161
#define GL_FRONT_AND_BACK
Definition: gl.h:336
#define GL_SPOT_EXPONENT
Definition: gl.h:319
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define GL_SPECULAR
Definition: gl.h:326
#define GL_QUADRATIC_ATTENUATION
Definition: gl.h:323
#define GL_INVALID_OPERATION
Definition: gl.h:696
#define GL_SMOOTH
Definition: gl.h:339
#define GL_AMBIENT
Definition: gl.h:324
unsigned int GLenum
Definition: gl.h:150
#define GL_BACK
Definition: gl.h:271
unsigned int GLuint
Definition: gl.h:159
#define GL_LIGHT_MODEL_LOCAL_VIEWER
Definition: gl.h:334
#define GL_LINEAR_ATTENUATION
Definition: gl.h:322
#define GL_SPOT_DIRECTION
Definition: gl.h:330
#define GL_FALSE
Definition: gl.h:173
#define GL_EMISSION
Definition: gl.h:328
int GLint
Definition: gl.h:156
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: gl.h:333
#define GL_FRONT
Definition: gl.h:270
#define GL_FLAT
Definition: gl.h:338
#define GL_CONSTANT_ATTENUATION
Definition: gl.h:321
#define GL_SPOT_CUTOFF
Definition: gl.h:320
#define GL_INVALID_ENUM
Definition: gl.h:694
#define GL_LIGHT0
Definition: gl.h:311
#define GL_LIGHT_MODEL_AMBIENT
Definition: gl.h:335
GLenum clamp
Definition: glext.h:6216
GLenum pname
Definition: glext.h:5645
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLfloat f
Definition: glext.h:7540
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum light
Definition: glfuncs.h:170
#define f
Definition: ke_i.h:83
#define ROUNDF(X)
Definition: macros.h:147
#define INSIDE_BEGIN_END(CTX)
Definition: macros.h:135
#define MIN2(A, B)
Definition: macros.h:159
#define COPY_3V(DST, SRC)
Definition: macros.h:98
#define FLOAT_TO_INT(X)
Definition: macros.h:222
#define COPY_4V(DST, SRC)
Definition: macros.h:102
#define NORMALIZE_3FV(V)
Definition: mmath.h:68
#define ASSERT(a)
Definition: mode.c:44
static const MAT2 mat
Definition: font.c:66
void gl_GetMaterialfv(GLcontext *ctx, GLenum face, GLenum pname, GLfloat *params)
Definition: light.c:563
void gl_GetLightiv(GLcontext *ctx, GLenum light, GLenum pname, GLint *params)
Definition: light.c:260
GLuint gl_material_bitmask(GLenum face, GLenum pname)
Definition: light.c:362
void gl_Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params, GLint nparams)
Definition: light.c:114
void gl_GetLightfv(GLcontext *ctx, GLenum light, GLenum pname, GLfloat *params)
Definition: light.c:211
void gl_compute_spot_exp_table(struct gl_light *l)
Definition: light.c:710
void gl_set_material(GLcontext *ctx, GLuint bitmask, const GLfloat *params)
Definition: light.c:413
void gl_ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
Definition: light.c:485
void gl_update_lighting(GLcontext *ctx)
Definition: light.c:770
void gl_ShadeModel(GLcontext *ctx, GLenum mode)
Definition: light.c:92
void gl_compute_material_shine_table(struct gl_material *m)
Definition: light.c:741
void gl_Materialfv(GLcontext *ctx, GLenum face, GLenum pname, const GLfloat *params)
Definition: light.c:523
void gl_GetMaterialiv(GLcontext *ctx, GLenum face, GLenum pname, GLint *params)
Definition: light.c:610
void gl_LightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
Definition: light.c:327
struct gl_light * NextEnabled
Definition: types.h:574
#define CLAMP(f, min, max)
Definition: tif_color.c:177
struct vertex_buffer * VB
Definition: tritemp.h:139
void gl_transform_vector(GLfloat u[4], const GLfloat v[4], const GLfloat m[16])
Definition: xform.c:248
#define TRANSFORM_POINT(Q, M, P)
Definition: xform.h:51