ReactOS  0.4.14-dev-49-gfb4591c
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;
147  case GL_SPOT_DIRECTION:
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;
234  case GL_SPOT_DIRECTION:
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;
294  case GL_SPOT_DIRECTION:
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:
372  bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
373  break;
374  case GL_DIFFUSE:
375  bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
376  break;
377  case GL_SPECULAR:
379  break;
380  case GL_SHININESS:
382  break;
384  bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
385  bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
386  break;
387  case GL_COLOR_INDEXES:
388  bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
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  */
413 void gl_set_material( GLcontext *ctx, GLuint bitmask, const GLfloat *params )
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:
494  case GL_FRONT_AND_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  */
524  GLenum face, GLenum pname, const GLfloat *params )
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 }
#define GL_CONSTANT_ATTENUATION
Definition: gl.h:321
#define GL_BACK
Definition: gl.h:271
#define FRONT_AMBIENT_BIT
Definition: types.h:529
#define GL_SPOT_EXPONENT
Definition: gl.h:319
#define GL_FLAT
Definition: gl.h:338
#define SHINE_TABLE_SIZE
Definition: types.h:558
GLfloat ModelViewMatrix[16]
Definition: types.h:1284
GLuint NewState
Definition: types.h:1355
#define GL_SPOT_DIRECTION
Definition: gl.h:330
#define GL_FALSE
Definition: gl.h:173
void gl_set_material(GLcontext *ctx, GLuint bitmask, const GLfloat *params)
Definition: light.c:413
#define FRONT_MATERIAL_BITS
Definition: types.h:542
#define FRONT_DIFFUSE_BIT
Definition: types.h:531
GLboolean NewModelViewMatrix
Definition: types.h:1282
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: gl.h:333
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define FLT_MIN
Definition: gcc_float.h:124
static const MAT2 mat
Definition: font.c:66
#define GL_SPOT_CUTOFF
Definition: gl.h:320
void gl_update_lighting(GLcontext *ctx)
Definition: light.c:770
WORD face[3]
Definition: mesh.c:4747
#define GL_DIFFUSE
Definition: gl.h:325
#define GL_SMOOTH
Definition: gl.h:339
const GLfloat * m
Definition: glext.h:10848
void gl_transform_vector(GLfloat u[4], const GLfloat v[4], const GLfloat m[16])
Definition: xform.c:248
#define INSIDE_BEGIN_END(CTX)
Definition: macros.h:135
#define ROUNDF(X)
Definition: macros.h:147
#define TRANSFORM_POINT(Q, M, P)
Definition: xform.h:51
#define GL_FRONT_AND_BACK
Definition: gl.h:336
GLenum pname
Definition: glext.h:5645
#define BACK_EMISSION_BIT
Definition: types.h:536
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
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
#define BACK_AMBIENT_BIT
Definition: types.h:530
#define GL_LIGHT0
Definition: gl.h:311
GLenum const GLfloat * params
Definition: glext.h:5645
float pow(float __x, int __y)
Definition: _cmath.h:458
#define GL_LIGHT_MODEL_AMBIENT
Definition: gl.h:335
#define e
Definition: ke_i.h:82
#define CLAMP(f, min, max)
Definition: tif_color.c:177
#define GL_FRONT
Definition: gl.h:270
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
#define MAX_LIGHTS
Definition: config.h:84
smooth NULL
Definition: ftsmooth.c:416
GLuint gl_material_bitmask(GLenum face, GLenum pname)
Definition: light.c:362
void gl_ShadeModel(GLcontext *ctx, GLenum mode)
Definition: light.c:92
void gl_Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params, GLint nparams)
Definition: light.c:114
#define COPY_3V(DST, SRC)
Definition: macros.h:98
#define GL_COLOR_INDEXES
Definition: gl.h:332
r l[0]
Definition: byte_order.h:167
#define FLOAT_TO_INT(X)
Definition: macros.h:222
GLenum clamp
Definition: glext.h:6216
GLfloat f
Definition: glext.h:7540
#define GL_LIGHT_MODEL_LOCAL_VIEWER
Definition: gl.h:334
#define GL_SPECULAR
Definition: gl.h:326
#define GL_AMBIENT_AND_DIFFUSE
Definition: gl.h:331
#define GL_SHININESS
Definition: gl.h:327
GLfloat ModelViewInv[16]
Definition: types.h:1285
#define BACK_INDEXES_BIT
Definition: types.h:540
#define GL_INVALID_VALUE
Definition: gl.h:695
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NORMALIZE_3FV(V)
Definition: mmath.h:68
#define GL_INVALID_OPERATION
Definition: gl.h:696
struct vertex_buffer * VB
Definition: tritemp.h:139
struct gl_light * NextEnabled
Definition: types.h:574
#define DEG2RAD
Definition: macros.h:268
void gl_Materialfv(GLcontext *ctx, GLenum face, GLenum pname, const GLfloat *params)
Definition: light.c:523
void gl_GetLightiv(GLcontext *ctx, GLenum light, GLenum pname, GLint *params)
Definition: light.c:260
#define EXP_TABLE_SIZE
Definition: types.h:557
#define NEW_RASTER_OPS
Definition: types.h:1233
unsigned int GLenum
Definition: gl.h:150
#define GL_AMBIENT
Definition: gl.h:324
GLenum mode
Definition: glext.h:6217
#define FRONT_INDEXES_BIT
Definition: types.h:539
void gl_GetMaterialfv(GLcontext *ctx, GLenum face, GLenum pname, GLfloat *params)
Definition: light.c:563
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
void gl_GetLightfv(GLcontext *ctx, GLenum light, GLenum pname, GLfloat *params)
Definition: light.c:211
void gl_error(GLcontext *ctx, GLenum error, const char *s)
Definition: context.c:1421
#define GL_QUADRATIC_ATTENUATION
Definition: gl.h:323
#define GL_EMISSION
Definition: gl.h:328
unsigned int GLuint
Definition: gl.h:159
void gl_compute_spot_exp_table(struct gl_light *l)
Definition: light.c:710
#define f
Definition: ke_i.h:83
#define FRONT_EMISSION_BIT
Definition: types.h:535
#define GL_TRUE
Definition: gl.h:174
#define BACK_SHININESS_BIT
Definition: types.h:538
void gl_ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
Definition: light.c:485
#define GL_INVALID_ENUM
Definition: gl.h:694
void gl_GetMaterialiv(GLcontext *ctx, GLenum face, GLenum pname, GLint *params)
Definition: light.c:610
#define FRONT_SPECULAR_BIT
Definition: types.h:533
#define FRONT_SHININESS_BIT
Definition: types.h:537
#define NEW_LIGHTING
Definition: types.h:1232
float GLfloat
Definition: gl.h:161
#define MIN2(A, B)
Definition: macros.h:159
void gl_analyze_modelview_matrix(GLcontext *ctx)
Definition: matrix.c:420
void gl_compute_material_shine_table(struct gl_material *m)
Definition: light.c:741
#define GL_POSITION
Definition: gl.h:329
#define GL_LINEAR_ATTENUATION
Definition: gl.h:322
int GLint
Definition: gl.h:156
#define BACK_SPECULAR_BIT
Definition: types.h:534
void gl_LightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
Definition: light.c:327
struct gl_light_attrib Light
Definition: types.h:1325
struct vertex_buffer * VB
Definition: types.h:1380
#define BACK_DIFFUSE_BIT
Definition: types.h:532
#define BACK_MATERIAL_BITS
Definition: types.h:546
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
#define F(x, y, z)
Definition: md5.c:51
#define COPY_4V(DST, SRC)
Definition: macros.h:102