Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5
 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 * copy of this software and associated documentation files (the "Software"),
9
 * to deal in the Software without restriction, including without limitation
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 * and/or sell copies of the Software, and to permit persons to whom the
12
 * Software is furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included
15
 * in all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
 
26
 
27
#include "c99_math.h"
28
#include "glheader.h"
29
#include "imports.h"
30
#include "context.h"
31
#include "enums.h"
32
#include "light.h"
33
#include "macros.h"
34
#include "util/simple_list.h"
35
#include "mtypes.h"
36
#include "math/m_matrix.h"
37
 
38
 
39
void GLAPIENTRY
40
_mesa_ShadeModel( GLenum mode )
41
{
42
   GET_CURRENT_CONTEXT(ctx);
43
 
44
   if (MESA_VERBOSE & VERBOSE_API)
45
      _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode));
46
 
47
   if (mode != GL_FLAT && mode != GL_SMOOTH) {
48
      _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel");
49
      return;
50
   }
51
 
52
   if (ctx->Light.ShadeModel == mode)
53
      return;
54
 
55
   FLUSH_VERTICES(ctx, _NEW_LIGHT);
56
   ctx->Light.ShadeModel = mode;
57
 
58
   if (ctx->Driver.ShadeModel)
59
      ctx->Driver.ShadeModel( ctx, mode );
60
}
61
 
62
 
63
/**
64
 * Set the provoking vertex (the vertex which specifies the prim's
65
 * color when flat shading) to either the first or last vertex of the
66
 * triangle or line.
67
 */
68
void GLAPIENTRY
69
_mesa_ProvokingVertex(GLenum mode)
70
{
71
   GET_CURRENT_CONTEXT(ctx);
72
 
73
   if (MESA_VERBOSE&VERBOSE_API)
74
      _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode);
75
 
76
   switch (mode) {
77
   case GL_FIRST_VERTEX_CONVENTION_EXT:
78
   case GL_LAST_VERTEX_CONVENTION_EXT:
79
      break;
80
   default:
81
      _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode);
82
      return;
83
   }
84
 
85
   if (ctx->Light.ProvokingVertex == mode)
86
      return;
87
 
88
   FLUSH_VERTICES(ctx, _NEW_LIGHT);
89
   ctx->Light.ProvokingVertex = mode;
90
}
91
 
92
 
93
/**
94
 * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
95
 * per-light state.
96
 * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
97
 * will have already been transformed by the modelview matrix!
98
 * Also, all error checking should have already been done.
99
 */
100
void
101
_mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
102
{
103
   struct gl_light *light;
104
 
105
   assert(lnum < MAX_LIGHTS);
106
   light = &ctx->Light.Light[lnum];
107
 
108
   switch (pname) {
109
   case GL_AMBIENT:
110
      if (TEST_EQ_4V(light->Ambient, params))
111
	 return;
112
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
113
      COPY_4V( light->Ambient, params );
114
      break;
115
   case GL_DIFFUSE:
116
      if (TEST_EQ_4V(light->Diffuse, params))
117
	 return;
118
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
119
      COPY_4V( light->Diffuse, params );
120
      break;
121
   case GL_SPECULAR:
122
      if (TEST_EQ_4V(light->Specular, params))
123
	 return;
124
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
125
      COPY_4V( light->Specular, params );
126
      break;
127
   case GL_POSITION:
128
      /* NOTE: position has already been transformed by ModelView! */
129
      if (TEST_EQ_4V(light->EyePosition, params))
130
	 return;
131
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
132
      COPY_4V(light->EyePosition, params);
133
      if (light->EyePosition[3] != 0.0F)
134
	 light->_Flags |= LIGHT_POSITIONAL;
135
      else
136
	 light->_Flags &= ~LIGHT_POSITIONAL;
137
      break;
138
   case GL_SPOT_DIRECTION:
139
      /* NOTE: Direction already transformed by inverse ModelView! */
140
      if (TEST_EQ_3V(light->SpotDirection, params))
141
	 return;
142
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
143
      COPY_3V(light->SpotDirection, params);
144
      break;
145
   case GL_SPOT_EXPONENT:
146
      assert(params[0] >= 0.0);
147
      assert(params[0] <= ctx->Const.MaxSpotExponent);
148
      if (light->SpotExponent == params[0])
149
	 return;
150
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
151
      light->SpotExponent = params[0];
152
      break;
153
   case GL_SPOT_CUTOFF:
154
      assert(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0));
155
      if (light->SpotCutoff == params[0])
156
         return;
157
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
158
      light->SpotCutoff = params[0];
159
      light->_CosCutoff = (GLfloat) (cos(light->SpotCutoff * M_PI / 180.0));
160
      if (light->_CosCutoff < 0)
161
         light->_CosCutoff = 0;
162
      if (light->SpotCutoff != 180.0F)
163
         light->_Flags |= LIGHT_SPOT;
164
      else
165
         light->_Flags &= ~LIGHT_SPOT;
166
      break;
167
   case GL_CONSTANT_ATTENUATION:
168
      assert(params[0] >= 0.0);
169
      if (light->ConstantAttenuation == params[0])
170
	 return;
171
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
172
      light->ConstantAttenuation = params[0];
173
      break;
174
   case GL_LINEAR_ATTENUATION:
175
      assert(params[0] >= 0.0);
176
      if (light->LinearAttenuation == params[0])
177
	 return;
178
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
179
      light->LinearAttenuation = params[0];
180
      break;
181
   case GL_QUADRATIC_ATTENUATION:
182
      assert(params[0] >= 0.0);
183
      if (light->QuadraticAttenuation == params[0])
184
	 return;
185
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
186
      light->QuadraticAttenuation = params[0];
187
      break;
188
   default:
189
      _mesa_problem(ctx, "Unexpected pname in _mesa_light()");
190
      return;
191
   }
192
 
193
   if (ctx->Driver.Lightfv)
194
      ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params );
195
}
196
 
197
 
198
void GLAPIENTRY
199
_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
200
{
201
   GLfloat fparam[4];
202
   fparam[0] = param;
203
   fparam[1] = fparam[2] = fparam[3] = 0.0F;
204
   _mesa_Lightfv( light, pname, fparam );
205
}
206
 
207
 
208
void GLAPIENTRY
209
_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
210
{
211
   GET_CURRENT_CONTEXT(ctx);
212
   GLint i = (GLint) (light - GL_LIGHT0);
213
   GLfloat temp[4];
214
 
215
   if (i < 0 || i >= (GLint) ctx->Const.MaxLights) {
216
      _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light );
217
      return;
218
   }
219
 
220
   /* do particular error checks, transformations */
221
   switch (pname) {
222
   case GL_AMBIENT:
223
   case GL_DIFFUSE:
224
   case GL_SPECULAR:
225
      /* nothing */
226
      break;
227
   case GL_POSITION:
228
      /* transform position by ModelView matrix */
229
      TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params);
230
      params = temp;
231
      break;
232
   case GL_SPOT_DIRECTION:
233
      /* transform direction by inverse modelview */
234
      if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
235
	 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
236
      }
237
      TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m);
238
      params = temp;
239
      break;
240
   case GL_SPOT_EXPONENT:
241
      if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) {
242
	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
243
	 return;
244
      }
245
      break;
246
   case GL_SPOT_CUTOFF:
247
      if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) {
248
	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
249
	 return;
250
      }
251
      break;
252
   case GL_CONSTANT_ATTENUATION:
253
      if (params[0] < 0.0) {
254
	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
255
	 return;
256
      }
257
      break;
258
   case GL_LINEAR_ATTENUATION:
259
      if (params[0] < 0.0) {
260
	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
261
	 return;
262
      }
263
      break;
264
   case GL_QUADRATIC_ATTENUATION:
265
      if (params[0] < 0.0) {
266
	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
267
	 return;
268
      }
269
      break;
270
   default:
271
      _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname);
272
      return;
273
   }
274
 
275
   _mesa_light(ctx, i, pname, params);
276
}
277
 
278
 
279
void GLAPIENTRY
280
_mesa_Lighti( GLenum light, GLenum pname, GLint param )
281
{
282
   GLint iparam[4];
283
   iparam[0] = param;
284
   iparam[1] = iparam[2] = iparam[3] = 0;
285
   _mesa_Lightiv( light, pname, iparam );
286
}
287
 
288
 
289
void GLAPIENTRY
290
_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
291
{
292
   GLfloat fparam[4];
293
 
294
   switch (pname) {
295
      case GL_AMBIENT:
296
      case GL_DIFFUSE:
297
      case GL_SPECULAR:
298
         fparam[0] = INT_TO_FLOAT( params[0] );
299
         fparam[1] = INT_TO_FLOAT( params[1] );
300
         fparam[2] = INT_TO_FLOAT( params[2] );
301
         fparam[3] = INT_TO_FLOAT( params[3] );
302
         break;
303
      case GL_POSITION:
304
         fparam[0] = (GLfloat) params[0];
305
         fparam[1] = (GLfloat) params[1];
306
         fparam[2] = (GLfloat) params[2];
307
         fparam[3] = (GLfloat) params[3];
308
         break;
309
      case GL_SPOT_DIRECTION:
310
         fparam[0] = (GLfloat) params[0];
311
         fparam[1] = (GLfloat) params[1];
312
         fparam[2] = (GLfloat) params[2];
313
         break;
314
      case GL_SPOT_EXPONENT:
315
      case GL_SPOT_CUTOFF:
316
      case GL_CONSTANT_ATTENUATION:
317
      case GL_LINEAR_ATTENUATION:
318
      case GL_QUADRATIC_ATTENUATION:
319
         fparam[0] = (GLfloat) params[0];
320
         break;
321
      default:
322
         /* error will be caught later in gl_Lightfv */
323
         ;
324
   }
325
 
326
   _mesa_Lightfv( light, pname, fparam );
327
}
328
 
329
 
330
 
331
void GLAPIENTRY
332
_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
333
{
334
   GET_CURRENT_CONTEXT(ctx);
335
   GLint l = (GLint) (light - GL_LIGHT0);
336
 
337
   if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
338
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
339
      return;
340
   }
341
 
342
   switch (pname) {
343
      case GL_AMBIENT:
344
         COPY_4V( params, ctx->Light.Light[l].Ambient );
345
         break;
346
      case GL_DIFFUSE:
347
         COPY_4V( params, ctx->Light.Light[l].Diffuse );
348
         break;
349
      case GL_SPECULAR:
350
         COPY_4V( params, ctx->Light.Light[l].Specular );
351
         break;
352
      case GL_POSITION:
353
         COPY_4V( params, ctx->Light.Light[l].EyePosition );
354
         break;
355
      case GL_SPOT_DIRECTION:
356
         COPY_3V( params, ctx->Light.Light[l].SpotDirection );
357
         break;
358
      case GL_SPOT_EXPONENT:
359
         params[0] = ctx->Light.Light[l].SpotExponent;
360
         break;
361
      case GL_SPOT_CUTOFF:
362
         params[0] = ctx->Light.Light[l].SpotCutoff;
363
         break;
364
      case GL_CONSTANT_ATTENUATION:
365
         params[0] = ctx->Light.Light[l].ConstantAttenuation;
366
         break;
367
      case GL_LINEAR_ATTENUATION:
368
         params[0] = ctx->Light.Light[l].LinearAttenuation;
369
         break;
370
      case GL_QUADRATIC_ATTENUATION:
371
         params[0] = ctx->Light.Light[l].QuadraticAttenuation;
372
         break;
373
      default:
374
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
375
         break;
376
   }
377
}
378
 
379
 
380
void GLAPIENTRY
381
_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
382
{
383
   GET_CURRENT_CONTEXT(ctx);
384
   GLint l = (GLint) (light - GL_LIGHT0);
385
 
386
   if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
387
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
388
      return;
389
   }
390
 
391
   switch (pname) {
392
      case GL_AMBIENT:
393
         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
394
         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
395
         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
396
         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
397
         break;
398
      case GL_DIFFUSE:
399
         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
400
         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
401
         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
402
         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
403
         break;
404
      case GL_SPECULAR:
405
         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
406
         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
407
         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
408
         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
409
         break;
410
      case GL_POSITION:
411
         params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
412
         params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
413
         params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
414
         params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
415
         break;
416
      case GL_SPOT_DIRECTION:
417
         params[0] = (GLint) ctx->Light.Light[l].SpotDirection[0];
418
         params[1] = (GLint) ctx->Light.Light[l].SpotDirection[1];
419
         params[2] = (GLint) ctx->Light.Light[l].SpotDirection[2];
420
         break;
421
      case GL_SPOT_EXPONENT:
422
         params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
423
         break;
424
      case GL_SPOT_CUTOFF:
425
         params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
426
         break;
427
      case GL_CONSTANT_ATTENUATION:
428
         params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
429
         break;
430
      case GL_LINEAR_ATTENUATION:
431
         params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
432
         break;
433
      case GL_QUADRATIC_ATTENUATION:
434
         params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
435
         break;
436
      default:
437
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
438
         break;
439
   }
440
}
441
 
442
 
443
 
444
/**********************************************************************/
445
/***                        Light Model                             ***/
446
/**********************************************************************/
447
 
448
 
449
void GLAPIENTRY
450
_mesa_LightModelfv( GLenum pname, const GLfloat *params )
451
{
452
   GLenum newenum;
453
   GLboolean newbool;
454
   GET_CURRENT_CONTEXT(ctx);
455
 
456
   switch (pname) {
457
      case GL_LIGHT_MODEL_AMBIENT:
458
         if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
459
	    return;
460
	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
461
         COPY_4V( ctx->Light.Model.Ambient, params );
462
         break;
463
      case GL_LIGHT_MODEL_LOCAL_VIEWER:
464
         if (ctx->API != API_OPENGL_COMPAT)
465
            goto invalid_pname;
466
         newbool = (params[0]!=0.0);
467
	 if (ctx->Light.Model.LocalViewer == newbool)
468
	    return;
469
	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
470
	 ctx->Light.Model.LocalViewer = newbool;
471
         break;
472
      case GL_LIGHT_MODEL_TWO_SIDE:
473
         newbool = (params[0]!=0.0);
474
	 if (ctx->Light.Model.TwoSide == newbool)
475
	    return;
476
	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
477
	 ctx->Light.Model.TwoSide = newbool;
478
         break;
479
      case GL_LIGHT_MODEL_COLOR_CONTROL:
480
         if (ctx->API != API_OPENGL_COMPAT)
481
            goto invalid_pname;
482
         if (params[0] == (GLfloat) GL_SINGLE_COLOR)
483
	    newenum = GL_SINGLE_COLOR;
484
         else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
485
	    newenum = GL_SEPARATE_SPECULAR_COLOR;
486
	 else {
487
            _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)",
488
                         (GLint) params[0] );
489
	    return;
490
         }
491
	 if (ctx->Light.Model.ColorControl == newenum)
492
	    return;
493
	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
494
	 ctx->Light.Model.ColorControl = newenum;
495
         break;
496
      default:
497
         goto invalid_pname;
498
   }
499
 
500
   if (ctx->Driver.LightModelfv)
501
      ctx->Driver.LightModelfv( ctx, pname, params );
502
 
503
   return;
504
 
505
invalid_pname:
506
   _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );
507
   return;
508
}
509
 
510
 
511
void GLAPIENTRY
512
_mesa_LightModeliv( GLenum pname, const GLint *params )
513
{
514
   GLfloat fparam[4];
515
 
516
   switch (pname) {
517
      case GL_LIGHT_MODEL_AMBIENT:
518
         fparam[0] = INT_TO_FLOAT( params[0] );
519
         fparam[1] = INT_TO_FLOAT( params[1] );
520
         fparam[2] = INT_TO_FLOAT( params[2] );
521
         fparam[3] = INT_TO_FLOAT( params[3] );
522
         break;
523
      case GL_LIGHT_MODEL_LOCAL_VIEWER:
524
      case GL_LIGHT_MODEL_TWO_SIDE:
525
      case GL_LIGHT_MODEL_COLOR_CONTROL:
526
         fparam[0] = (GLfloat) params[0];
527
         break;
528
      default:
529
         /* Error will be caught later in gl_LightModelfv */
530
         ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
531
   }
532
   _mesa_LightModelfv( pname, fparam );
533
}
534
 
535
 
536
void GLAPIENTRY
537
_mesa_LightModeli( GLenum pname, GLint param )
538
{
539
   GLint iparam[4];
540
   iparam[0] = param;
541
   iparam[1] = iparam[2] = iparam[3] = 0;
542
   _mesa_LightModeliv( pname, iparam );
543
}
544
 
545
 
546
void GLAPIENTRY
547
_mesa_LightModelf( GLenum pname, GLfloat param )
548
{
549
   GLfloat fparam[4];
550
   fparam[0] = param;
551
   fparam[1] = fparam[2] = fparam[3] = 0.0F;
552
   _mesa_LightModelfv( pname, fparam );
553
}
554
 
555
 
556
 
557
/********** MATERIAL **********/
558
 
559
 
560
/*
561
 * Given a face and pname value (ala glColorMaterial), compute a bitmask
562
 * of the targeted material values.
563
 */
564
GLuint
565
_mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname,
566
                        GLuint legal, const char *where )
567
{
568
   GLuint bitmask = 0;
569
 
570
   /* Make a bitmask indicating what material attribute(s) we're updating */
571
   switch (pname) {
572
      case GL_EMISSION:
573
         bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;
574
         break;
575
      case GL_AMBIENT:
576
         bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
577
         break;
578
      case GL_DIFFUSE:
579
         bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
580
         break;
581
      case GL_SPECULAR:
582
         bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;
583
         break;
584
      case GL_SHININESS:
585
         bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;
586
         break;
587
      case GL_AMBIENT_AND_DIFFUSE:
588
         bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
589
         bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
590
         break;
591
      case GL_COLOR_INDEXES:
592
         bitmask |= MAT_BIT_FRONT_INDEXES  | MAT_BIT_BACK_INDEXES;
593
         break;
594
      default:
595
         _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
596
         return 0;
597
   }
598
 
599
   if (face==GL_FRONT) {
600
      bitmask &= FRONT_MATERIAL_BITS;
601
   }
602
   else if (face==GL_BACK) {
603
      bitmask &= BACK_MATERIAL_BITS;
604
   }
605
   else if (face != GL_FRONT_AND_BACK) {
606
      _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
607
      return 0;
608
   }
609
 
610
   if (bitmask & ~legal) {
611
      _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
612
      return 0;
613
   }
614
 
615
   return bitmask;
616
}
617
 
618
 
619
 
620
/* Update derived values following a change in ctx->Light.Material
621
 */
622
void
623
_mesa_update_material( struct gl_context *ctx, GLuint bitmask )
624
{
625
   struct gl_light *light, *list = &ctx->Light.EnabledList;
626
   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
627
 
628
   if (MESA_VERBOSE & VERBOSE_MATERIAL)
629
      _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);
630
 
631
   if (!bitmask)
632
      return;
633
 
634
   /* update material ambience */
635
   if (bitmask & MAT_BIT_FRONT_AMBIENT) {
636
      foreach (light, list) {
637
         SCALE_3V( light->_MatAmbient[0], light->Ambient,
638
		   mat[MAT_ATTRIB_FRONT_AMBIENT]);
639
      }
640
   }
641
 
642
   if (bitmask & MAT_BIT_BACK_AMBIENT) {
643
      foreach (light, list) {
644
         SCALE_3V( light->_MatAmbient[1], light->Ambient,
645
		   mat[MAT_ATTRIB_BACK_AMBIENT]);
646
      }
647
   }
648
 
649
   /* update BaseColor = emission + scene's ambience * material's ambience */
650
   if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {
651
      COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );
652
      ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],
653
		    ctx->Light.Model.Ambient );
654
   }
655
 
656
   if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {
657
      COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );
658
      ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],
659
		    ctx->Light.Model.Ambient );
660
   }
661
 
662
   /* update material diffuse values */
663
   if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
664
      foreach (light, list) {
665
	 SCALE_3V( light->_MatDiffuse[0], light->Diffuse,
666
		   mat[MAT_ATTRIB_FRONT_DIFFUSE] );
667
      }
668
   }
669
 
670
   if (bitmask & MAT_BIT_BACK_DIFFUSE) {
671
      foreach (light, list) {
672
	 SCALE_3V( light->_MatDiffuse[1], light->Diffuse,
673
		   mat[MAT_ATTRIB_BACK_DIFFUSE] );
674
      }
675
   }
676
 
677
   /* update material specular values */
678
   if (bitmask & MAT_BIT_FRONT_SPECULAR) {
679
      foreach (light, list) {
680
	 SCALE_3V( light->_MatSpecular[0], light->Specular,
681
		   mat[MAT_ATTRIB_FRONT_SPECULAR]);
682
      }
683
   }
684
 
685
   if (bitmask & MAT_BIT_BACK_SPECULAR) {
686
      foreach (light, list) {
687
	 SCALE_3V( light->_MatSpecular[1], light->Specular,
688
		   mat[MAT_ATTRIB_BACK_SPECULAR]);
689
      }
690
   }
691
}
692
 
693
 
694
/*
695
 * Update the current materials from the given rgba color
696
 * according to the bitmask in _ColorMaterialBitmask, which is
697
 * set by glColorMaterial().
698
 */
699
void
700
_mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] )
701
{
702
   const GLbitfield bitmask = ctx->Light._ColorMaterialBitmask;
703
   struct gl_material *mat = &ctx->Light.Material;
704
   int i;
705
 
706
   for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
707
      if (bitmask & (1<
708
	 COPY_4FV( mat->Attrib[i], color );
709
 
710
   _mesa_update_material( ctx, bitmask );
711
}
712
 
713
 
714
void GLAPIENTRY
715
_mesa_ColorMaterial( GLenum face, GLenum mode )
716
{
717
   GET_CURRENT_CONTEXT(ctx);
718
   GLuint bitmask;
719
   GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |
720
		   MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |
721
		   MAT_BIT_FRONT_DIFFUSE  | MAT_BIT_BACK_DIFFUSE  |
722
		   MAT_BIT_FRONT_AMBIENT  | MAT_BIT_BACK_AMBIENT);
723
 
724
   if (MESA_VERBOSE&VERBOSE_API)
725
      _mesa_debug(ctx, "glColorMaterial %s %s\n",
726
                  _mesa_lookup_enum_by_nr(face),
727
                  _mesa_lookup_enum_by_nr(mode));
728
 
729
   bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
730
   if (bitmask == 0)
731
      return; /* error was recorded */
732
 
733
   if (ctx->Light._ColorMaterialBitmask == bitmask &&
734
       ctx->Light.ColorMaterialFace == face &&
735
       ctx->Light.ColorMaterialMode == mode)
736
      return;
737
 
738
   FLUSH_VERTICES(ctx, _NEW_LIGHT);
739
   ctx->Light._ColorMaterialBitmask = bitmask;
740
   ctx->Light.ColorMaterialFace = face;
741
   ctx->Light.ColorMaterialMode = mode;
742
 
743
   if (ctx->Light.ColorMaterialEnabled) {
744
      FLUSH_CURRENT( ctx, 0 );
745
      _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
746
   }
747
 
748
   if (ctx->Driver.ColorMaterial)
749
      ctx->Driver.ColorMaterial( ctx, face, mode );
750
}
751
 
752
 
753
void GLAPIENTRY
754
_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
755
{
756
   GET_CURRENT_CONTEXT(ctx);
757
   GLuint f;
758
   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
759
   FLUSH_VERTICES(ctx, 0); /* update materials */
760
 
761
   FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
762
 
763
   if (face==GL_FRONT) {
764
      f = 0;
765
   }
766
   else if (face==GL_BACK) {
767
      f = 1;
768
   }
769
   else {
770
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
771
      return;
772
   }
773
 
774
   switch (pname) {
775
      case GL_AMBIENT:
776
         COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );
777
         break;
778
      case GL_DIFFUSE:
779
         COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );
780
	 break;
781
      case GL_SPECULAR:
782
         COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );
783
	 break;
784
      case GL_EMISSION:
785
	 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );
786
	 break;
787
      case GL_SHININESS:
788
	 *params = mat[MAT_ATTRIB_SHININESS(f)][0];
789
	 break;
790
      case GL_COLOR_INDEXES:
791
         if (ctx->API != API_OPENGL_COMPAT) {
792
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
793
            return;
794
         }
795
	 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];
796
	 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];
797
	 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];
798
	 break;
799
      default:
800
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
801
   }
802
}
803
 
804
 
805
void GLAPIENTRY
806
_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
807
{
808
   GET_CURRENT_CONTEXT(ctx);
809
   GLuint f;
810
   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
811
 
812
   assert(ctx->API == API_OPENGL_COMPAT);
813
 
814
   FLUSH_VERTICES(ctx, 0); /* update materials */
815
   FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
816
 
817
   if (face==GL_FRONT) {
818
      f = 0;
819
   }
820
   else if (face==GL_BACK) {
821
      f = 1;
822
   }
823
   else {
824
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
825
      return;
826
   }
827
   switch (pname) {
828
      case GL_AMBIENT:
829
         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );
830
         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );
831
         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );
832
         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );
833
         break;
834
      case GL_DIFFUSE:
835
         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );
836
         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );
837
         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );
838
         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );
839
	 break;
840
      case GL_SPECULAR:
841
         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );
842
         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );
843
         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );
844
         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );
845
	 break;
846
      case GL_EMISSION:
847
         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );
848
         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );
849
         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );
850
         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );
851
	 break;
852
      case GL_SHININESS:
853
         *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] );
854
	 break;
855
      case GL_COLOR_INDEXES:
856
	 params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] );
857
	 params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] );
858
	 params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] );
859
	 break;
860
      default:
861
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
862
   }
863
}
864
 
865
 
866
 
867
/**
868
 * Examine current lighting parameters to determine if the optimized lighting
869
 * function can be used.
870
 * Also, precompute some lighting values such as the products of light
871
 * source and material ambient, diffuse and specular coefficients.
872
 */
873
void
874
_mesa_update_lighting( struct gl_context *ctx )
875
{
876
   GLbitfield flags = 0;
877
   struct gl_light *light;
878
   ctx->Light._NeedEyeCoords = GL_FALSE;
879
 
880
   if (!ctx->Light.Enabled)
881
      return;
882
 
883
   foreach(light, &ctx->Light.EnabledList) {
884
      flags |= light->_Flags;
885
   }
886
 
887
   ctx->Light._NeedVertices =
888
      ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
889
       ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
890
       ctx->Light.Model.LocalViewer);
891
 
892
   ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) ||
893
				ctx->Light.Model.LocalViewer);
894
 
895
   /* XXX: This test is overkill & needs to be fixed both for software and
896
    * hardware t&l drivers.  The above should be sufficient & should
897
    * be tested to verify this.
898
    */
899
   if (ctx->Light._NeedVertices)
900
      ctx->Light._NeedEyeCoords = GL_TRUE;
901
 
902
   /* Precompute some shading values.  Although we reference
903
    * Light.Material here, we can get away without flushing
904
    * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
905
    * are flushed, they will update the derived state at that time.
906
    */
907
   if (ctx->Light.Model.TwoSide)
908
      _mesa_update_material(ctx,
909
			    MAT_BIT_FRONT_EMISSION |
910
			    MAT_BIT_FRONT_AMBIENT |
911
			    MAT_BIT_FRONT_DIFFUSE |
912
			    MAT_BIT_FRONT_SPECULAR |
913
			    MAT_BIT_BACK_EMISSION |
914
			    MAT_BIT_BACK_AMBIENT |
915
			    MAT_BIT_BACK_DIFFUSE |
916
			    MAT_BIT_BACK_SPECULAR);
917
   else
918
      _mesa_update_material(ctx,
919
			    MAT_BIT_FRONT_EMISSION |
920
			    MAT_BIT_FRONT_AMBIENT |
921
			    MAT_BIT_FRONT_DIFFUSE |
922
			    MAT_BIT_FRONT_SPECULAR);
923
}
924
 
925
 
926
/**
927
 * Update state derived from light position, spot direction.
928
 * Called upon:
929
 *   _NEW_MODELVIEW
930
 *   _NEW_LIGHT
931
 *   _TNL_NEW_NEED_EYE_COORDS
932
 *
933
 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
934
 * Also update on lighting space changes.
935
 */
936
static void
937
compute_light_positions( struct gl_context *ctx )
938
{
939
   struct gl_light *light;
940
   static const GLfloat eye_z[3] = { 0, 0, 1 };
941
 
942
   if (!ctx->Light.Enabled)
943
      return;
944
 
945
   if (ctx->_NeedEyeCoords) {
946
      COPY_3V( ctx->_EyeZDir, eye_z );
947
   }
948
   else {
949
      TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
950
   }
951
 
952
   foreach (light, &ctx->Light.EnabledList) {
953
 
954
      if (ctx->_NeedEyeCoords) {
955
         /* _Position is in eye coordinate space */
956
	 COPY_4FV( light->_Position, light->EyePosition );
957
      }
958
      else {
959
         /* _Position is in object coordinate space */
960
	 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
961
			  light->EyePosition );
962
      }
963
 
964
      if (!(light->_Flags & LIGHT_POSITIONAL)) {
965
	 /* VP (VP) = Normalize( Position ) */
966
	 COPY_3V( light->_VP_inf_norm, light->_Position );
967
	 NORMALIZE_3FV( light->_VP_inf_norm );
968
 
969
	 if (!ctx->Light.Model.LocalViewer) {
970
	    /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
971
	    ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
972
	    NORMALIZE_3FV( light->_h_inf_norm );
973
	 }
974
	 light->_VP_inf_spot_attenuation = 1.0;
975
      }
976
      else {
977
         /* positional light w/ homogeneous coordinate, divide by W */
978
         GLfloat wInv = (GLfloat)1.0 / light->_Position[3];
979
         light->_Position[0] *= wInv;
980
         light->_Position[1] *= wInv;
981
         light->_Position[2] *= wInv;
982
      }
983
 
984
      if (light->_Flags & LIGHT_SPOT) {
985
         /* Note: we normalize the spot direction now */
986
 
987
	 if (ctx->_NeedEyeCoords) {
988
	    COPY_3V( light->_NormSpotDirection, light->SpotDirection );
989
            NORMALIZE_3FV( light->_NormSpotDirection );
990
	 }
991
         else {
992
            GLfloat spotDir[3];
993
            COPY_3V(spotDir, light->SpotDirection);
994
            NORMALIZE_3FV(spotDir);
995
	    TRANSFORM_NORMAL( light->_NormSpotDirection,
996
			      spotDir,
997
			      ctx->ModelviewMatrixStack.Top->m);
998
	 }
999
 
1000
	 NORMALIZE_3FV( light->_NormSpotDirection );
1001
 
1002
	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1003
	    GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
1004
					light->_NormSpotDirection);
1005
 
1006
	    if (PV_dot_dir > light->_CosCutoff) {
1007
	       light->_VP_inf_spot_attenuation =
1008
                  powf(PV_dot_dir, light->SpotExponent);
1009
	    }
1010
	    else {
1011
	       light->_VP_inf_spot_attenuation = 0;
1012
            }
1013
	 }
1014
      }
1015
   }
1016
}
1017
 
1018
 
1019
 
1020
static void
1021
update_modelview_scale( struct gl_context *ctx )
1022
{
1023
   ctx->_ModelViewInvScale = 1.0F;
1024
   if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
1025
      const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
1026
      GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
1027
      if (f < 1e-12) f = 1.0;
1028
      if (ctx->_NeedEyeCoords)
1029
	 ctx->_ModelViewInvScale = 1.0f / sqrtf(f);
1030
      else
1031
	 ctx->_ModelViewInvScale = sqrtf(f);
1032
   }
1033
}
1034
 
1035
 
1036
/**
1037
 * Bring up to date any state that relies on _NeedEyeCoords.
1038
 */
1039
void
1040
_mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state )
1041
{
1042
   const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
1043
 
1044
   (void) new_state;
1045
   ctx->_NeedEyeCoords = GL_FALSE;
1046
 
1047
   if (ctx->_ForceEyeCoords ||
1048
       (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) ||
1049
       ctx->Point._Attenuated ||
1050
       ctx->Light._NeedEyeCoords)
1051
      ctx->_NeedEyeCoords = GL_TRUE;
1052
 
1053
   if (ctx->Light.Enabled &&
1054
       !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top))
1055
      ctx->_NeedEyeCoords = GL_TRUE;
1056
 
1057
   /* Check if the truth-value interpretations of the bitfields have
1058
    * changed:
1059
    */
1060
   if (oldneedeyecoords != ctx->_NeedEyeCoords) {
1061
      /* Recalculate all state that depends on _NeedEyeCoords.
1062
       */
1063
      update_modelview_scale(ctx);
1064
      compute_light_positions( ctx );
1065
 
1066
      if (ctx->Driver.LightingSpaceChange)
1067
	 ctx->Driver.LightingSpaceChange( ctx );
1068
   }
1069
   else {
1070
      GLuint new_state2 = ctx->NewState;
1071
 
1072
      /* Recalculate that same state only if it has been invalidated
1073
       * by other statechanges.
1074
       */
1075
      if (new_state2 & _NEW_MODELVIEW)
1076
	 update_modelview_scale(ctx);
1077
 
1078
      if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
1079
	 compute_light_positions( ctx );
1080
   }
1081
}
1082
 
1083
 
1084
/**
1085
 * Drivers may need this if the hardware tnl unit doesn't support the
1086
 * light-in-modelspace optimization.  It's also useful for debugging.
1087
 */
1088
void
1089
_mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag )
1090
{
1091
   ctx->_ForceEyeCoords = !flag;
1092
   ctx->NewState |= _NEW_POINT;	/* one of the bits from
1093
				 * _MESA_NEW_NEED_EYE_COORDS.
1094
				 */
1095
}
1096
 
1097
 
1098
 
1099
/**********************************************************************/
1100
/*****                      Initialization                        *****/
1101
/**********************************************************************/
1102
 
1103
/**
1104
 * Initialize the n-th light data structure.
1105
 *
1106
 * \param l pointer to the gl_light structure to be initialized.
1107
 * \param n number of the light.
1108
 * \note The defaults for light 0 are different than the other lights.
1109
 */
1110
static void
1111
init_light( struct gl_light *l, GLuint n )
1112
{
1113
   make_empty_list( l );
1114
 
1115
   ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
1116
   if (n==0) {
1117
      ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
1118
      ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
1119
   }
1120
   else {
1121
      ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
1122
      ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
1123
   }
1124
   ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
1125
   ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 );
1126
   l->SpotExponent = 0.0;
1127
   l->SpotCutoff = 180.0;
1128
   l->_CosCutoff = 0.0;		/* KW: -ve values not admitted */
1129
   l->ConstantAttenuation = 1.0;
1130
   l->LinearAttenuation = 0.0;
1131
   l->QuadraticAttenuation = 0.0;
1132
   l->Enabled = GL_FALSE;
1133
}
1134
 
1135
 
1136
/**
1137
 * Initialize the light model data structure.
1138
 *
1139
 * \param lm pointer to the gl_lightmodel structure to be initialized.
1140
 */
1141
static void
1142
init_lightmodel( struct gl_lightmodel *lm )
1143
{
1144
   ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F );
1145
   lm->LocalViewer = GL_FALSE;
1146
   lm->TwoSide = GL_FALSE;
1147
   lm->ColorControl = GL_SINGLE_COLOR;
1148
}
1149
 
1150
 
1151
/**
1152
 * Initialize the material data structure.
1153
 *
1154
 * \param m pointer to the gl_material structure to be initialized.
1155
 */
1156
static void
1157
init_material( struct gl_material *m )
1158
{
1159
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1160
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1161
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1162
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1163
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1164
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1165
 
1166
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1167
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1168
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1169
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1170
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1171
   ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1172
}
1173
 
1174
 
1175
/**
1176
 * Initialize all lighting state for the given context.
1177
 */
1178
void
1179
_mesa_init_lighting( struct gl_context *ctx )
1180
{
1181
   GLuint i;
1182
 
1183
   /* Lighting group */
1184
   for (i = 0; i < MAX_LIGHTS; i++) {
1185
      init_light( &ctx->Light.Light[i], i );
1186
   }
1187
   make_empty_list( &ctx->Light.EnabledList );
1188
 
1189
   init_lightmodel( &ctx->Light.Model );
1190
   init_material( &ctx->Light.Material );
1191
   ctx->Light.ShadeModel = GL_SMOOTH;
1192
   ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1193
   ctx->Light.Enabled = GL_FALSE;
1194
   ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
1195
   ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
1196
   ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx,
1197
                                               GL_FRONT_AND_BACK,
1198
                                               GL_AMBIENT_AND_DIFFUSE, ~0,
1199
                                               NULL );
1200
 
1201
   ctx->Light.ColorMaterialEnabled = GL_FALSE;
1202
   ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
1203
   ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
1204
 
1205
   /* Miscellaneous */
1206
   ctx->Light._NeedEyeCoords = GL_FALSE;
1207
   ctx->_NeedEyeCoords = GL_FALSE;
1208
   ctx->_ForceEyeCoords = GL_FALSE;
1209
   ctx->_ModelViewInvScale = 1.0;
1210
}