Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 1
/*
2
 * Mesa 3-D graphics library
3
 * Version:  5.1
4
 *
5
 * Copyright (C) 1999-2003  Brian Paul   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
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 *
24
 *
25
 * Authors:
26
 *    Brian Paul
27
 *    Keith Whitwell 
28
 */
29
 
30
 
31
#if IDX & LIGHT_TWOSIDE
32
#  define NR_SIDES 2
33
#else
34
#  define NR_SIDES 1
35
#endif
36
 
37
 
38
/* define TRACE to trace lighting code */
39
/* #define TRACE 1 */
40
 
41
/*
42
 * ctx is the current context
43
 * VB is the vertex buffer
44
 * stage is the lighting stage-private data
45
 * input is the vector of eye or object-space vertex coordinates
46
 */
47
static void TAG(light_rgba_spec)( struct gl_context *ctx,
48
				  struct vertex_buffer *VB,
49
				  struct tnl_pipeline_stage *stage,
50
				  GLvector4f *input )
51
{
52
   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
53
   GLfloat (*base)[3] = ctx->Light._BaseColor;
54
   GLfloat sumA[2];
55
   GLuint j;
56
 
57
   const GLuint vstride = input->stride;
58
   const GLfloat *vertex = (GLfloat *)input->data;
59
   const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
60
   const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
61
 
62
   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
63
   GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data;
64
#if IDX & LIGHT_TWOSIDE
65
   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
66
   GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data;
67
#endif
68
 
69
   const GLuint nr = VB->Count;
70
 
71
#ifdef TRACE
72
   fprintf(stderr, "%s\n", __FUNCTION__ );
73
#endif
74
 
75
   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
76
   VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &store->LitSecondary[0];
77
   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
78
 
79
#if IDX & LIGHT_TWOSIDE
80
   VB->BackfaceColorPtr = &store->LitColor[1];
81
   VB->BackfaceSecondaryColorPtr = &store->LitSecondary[1];
82
   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
83
#endif
84
 
85
 
86
   store->LitColor[0].stride = 16;
87
   store->LitColor[1].stride = 16;
88
 
89
   for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
90
      GLfloat sum[2][3], spec[2][3];
91
      struct gl_light *light;
92
 
93
#if IDX & LIGHT_MATERIAL
94
      update_materials( ctx, store );
95
      sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
96
#if IDX & LIGHT_TWOSIDE
97
      sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
98
#endif
99
#endif
100
 
101
      COPY_3V(sum[0], base[0]);
102
      ZERO_3V(spec[0]);
103
 
104
#if IDX & LIGHT_TWOSIDE
105
      COPY_3V(sum[1], base[1]);
106
      ZERO_3V(spec[1]);
107
#endif
108
 
109
      /* Add contribution from each enabled light source */
110
      foreach (light, &ctx->Light.EnabledList) {
111
	 GLfloat n_dot_h;
112
	 GLfloat correction;
113
	 GLint side;
114
	 GLfloat contrib[3];
115
	 GLfloat attenuation;
116
	 GLfloat VP[3];  /* unit vector from vertex to light */
117
	 GLfloat n_dot_VP;       /* n dot VP */
118
	 GLfloat *h;
119
 
120
	 /* compute VP and attenuation */
121
	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
122
	    /* directional light */
123
	    COPY_3V(VP, light->_VP_inf_norm);
124
	    attenuation = light->_VP_inf_spot_attenuation;
125
	 }
126
	 else {
127
	    GLfloat d;     /* distance from vertex to light */
128
 
129
	    SUB_3V(VP, light->_Position, vertex);
130
 
131
	    d = (GLfloat) LEN_3FV( VP );
132
 
133
	    if (d > 1e-6) {
134
	       GLfloat invd = 1.0F / d;
135
	       SELF_SCALE_SCALAR_3V(VP, invd);
136
	    }
137
 
138
	    attenuation = 1.0F / (light->ConstantAttenuation + d *
139
				  (light->LinearAttenuation + d *
140
				   light->QuadraticAttenuation));
141
 
142
	    /* spotlight attenuation */
143
	    if (light->_Flags & LIGHT_SPOT) {
144
	       GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection);
145
 
146
	       if (PV_dot_dir_CosCutoff) {
147
		  continue; /* this light makes no contribution */
148
	       }
149
	       else {
150
		  GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
151
		  GLint k = (GLint) x;
152
		  GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
153
				    + (x-k)*light->_SpotExpTable[k][1]);
154
		  attenuation *= spot;
155
	       }
156
	    }
157
	 }
158
 
159
	 if (attenuation < 1e-3)
160
	    continue;		/* this light makes no contribution */
161
 
162
	 /* Compute dot product or normal and vector from V to light pos */
163
	 n_dot_VP = DOT3( normal, VP );
164
 
165
	 /* Which side gets the diffuse & specular terms? */
166
	 if (n_dot_VP < 0.0F) {
167
	    ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
168
#if IDX & LIGHT_TWOSIDE
169
	    side = 1;
170
	    correction = -1;
171
	    n_dot_VP = -n_dot_VP;
172
#else
173
            continue;
174
#endif
175
	 }
176
         else {
177
#if IDX & LIGHT_TWOSIDE
178
            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
179
#endif
180
	    side = 0;
181
	    correction = 1;
182
	 }
183
 
184
	 /* diffuse term */
185
	 COPY_3V(contrib, light->_MatAmbient[side]);
186
	 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
187
	 ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib );
188
 
189
	 /* specular term - cannibalize VP... */
190
	 if (ctx->Light.Model.LocalViewer) {
191
	    GLfloat v[3];
192
	    COPY_3V(v, vertex);
193
	    NORMALIZE_3FV(v);
194
	    SUB_3V(VP, VP, v);                /* h = VP + VPe */
195
	    h = VP;
196
	    NORMALIZE_3FV(h);
197
	 }
198
	 else if (light->_Flags & LIGHT_POSITIONAL) {
199
	    h = VP;
200
	    ACC_3V(h, ctx->_EyeZDir);
201
	    NORMALIZE_3FV(h);
202
	 }
203
         else {
204
	    h = light->_h_inf_norm;
205
	 }
206
 
207
	 n_dot_h = correction * DOT3(normal, h);
208
 
209
	 if (n_dot_h > 0.0F) {
210
	    GLfloat spec_coef;
211
	    struct gl_shine_tab *tab = ctx->_ShineTable[side];
212
	    GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
213
 
214
	    if (spec_coef > 1.0e-10) {
215
	       spec_coef *= attenuation;
216
	       ACC_SCALE_SCALAR_3V( spec[side], spec_coef,
217
				    light->_MatSpecular[side]);
218
	    }
219
	 }
220
      } /*loop over lights*/
221
 
222
      COPY_3V( Fcolor[j], sum[0] );
223
      COPY_3V( Fspec[j], spec[0] );
224
      Fcolor[j][3] = sumA[0];
225
 
226
#if IDX & LIGHT_TWOSIDE
227
      COPY_3V( Bcolor[j], sum[1] );
228
      COPY_3V( Bspec[j], spec[1] );
229
      Bcolor[j][3] = sumA[1];
230
#endif
231
   }
232
}
233
 
234
 
235
static void TAG(light_rgba)( struct gl_context *ctx,
236
			     struct vertex_buffer *VB,
237
			     struct tnl_pipeline_stage *stage,
238
			     GLvector4f *input )
239
{
240
   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
241
   GLuint j;
242
 
243
   GLfloat (*base)[3] = ctx->Light._BaseColor;
244
   GLfloat sumA[2];
245
 
246
   const GLuint vstride = input->stride;
247
   const GLfloat *vertex = (GLfloat *) input->data;
248
   const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
249
   const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
250
 
251
   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
252
#if IDX & LIGHT_TWOSIDE
253
   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
254
#endif
255
 
256
   const GLuint nr = VB->Count;
257
 
258
#ifdef TRACE
259
   fprintf(stderr, "%s\n", __FUNCTION__ );
260
#endif
261
 
262
   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
263
   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
264
 
265
#if IDX & LIGHT_TWOSIDE
266
   VB->BackfaceColorPtr = &store->LitColor[1];
267
   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
268
#endif
269
 
270
   store->LitColor[0].stride = 16;
271
   store->LitColor[1].stride = 16;
272
 
273
   for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
274
      GLfloat sum[2][3];
275
      struct gl_light *light;
276
 
277
#if IDX & LIGHT_MATERIAL
278
      update_materials( ctx, store );
279
      sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
280
#if IDX & LIGHT_TWOSIDE
281
      sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
282
#endif
283
#endif
284
 
285
      COPY_3V(sum[0], base[0]);
286
 
287
#if IDX & LIGHT_TWOSIDE
288
      COPY_3V(sum[1], base[1]);
289
#endif
290
 
291
      /* Add contribution from each enabled light source */
292
      foreach (light, &ctx->Light.EnabledList) {
293
 
294
	 GLfloat n_dot_h;
295
	 GLfloat correction;
296
	 GLint side;
297
	 GLfloat contrib[3];
298
	 GLfloat attenuation = 1.0;
299
	 GLfloat VP[3];          /* unit vector from vertex to light */
300
	 GLfloat n_dot_VP;       /* n dot VP */
301
	 GLfloat *h;
302
 
303
	 /* compute VP and attenuation */
304
	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
305
	    /* directional light */
306
	    COPY_3V(VP, light->_VP_inf_norm);
307
	    attenuation = light->_VP_inf_spot_attenuation;
308
	 }
309
	 else {
310
	    GLfloat d;     /* distance from vertex to light */
311
 
312
 
313
	    SUB_3V(VP, light->_Position, vertex);
314
 
315
	    d = (GLfloat) LEN_3FV( VP );
316
 
317
	    if ( d > 1e-6) {
318
	       GLfloat invd = 1.0F / d;
319
	       SELF_SCALE_SCALAR_3V(VP, invd);
320
	    }
321
 
322
            attenuation = 1.0F / (light->ConstantAttenuation + d *
323
                                  (light->LinearAttenuation + d *
324
                                   light->QuadraticAttenuation));
325
 
326
	    /* spotlight attenuation */
327
	    if (light->_Flags & LIGHT_SPOT) {
328
	       GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection);
329
 
330
	       if (PV_dot_dir_CosCutoff) {
331
		  continue; /* this light makes no contribution */
332
	       }
333
	       else {
334
		  GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
335
		  GLint k = (GLint) x;
336
		  GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
337
				  + (x-k)*light->_SpotExpTable[k][1]);
338
		  attenuation *= spot;
339
	       }
340
	    }
341
	 }
342
 
343
	 if (attenuation < 1e-3)
344
	    continue;		/* this light makes no contribution */
345
 
346
	 /* Compute dot product or normal and vector from V to light pos */
347
	 n_dot_VP = DOT3( normal, VP );
348
 
349
	 /* which side are we lighting? */
350
	 if (n_dot_VP < 0.0F) {
351
	    ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
352
#if IDX & LIGHT_TWOSIDE
353
	    side = 1;
354
	    correction = -1;
355
	    n_dot_VP = -n_dot_VP;
356
#else
357
            continue;
358
#endif
359
	 }
360
         else {
361
#if IDX & LIGHT_TWOSIDE
362
            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
363
#endif
364
	    side = 0;
365
	    correction = 1;
366
	 }
367
 
368
	 COPY_3V(contrib, light->_MatAmbient[side]);
369
 
370
	 /* diffuse term */
371
	 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
372
 
373
	 /* specular term - cannibalize VP... */
374
	 {
375
	    if (ctx->Light.Model.LocalViewer) {
376
	       GLfloat v[3];
377
	       COPY_3V(v, vertex);
378
	       NORMALIZE_3FV(v);
379
	       SUB_3V(VP, VP, v);                /* h = VP + VPe */
380
	       h = VP;
381
	       NORMALIZE_3FV(h);
382
	    }
383
	    else if (light->_Flags & LIGHT_POSITIONAL) {
384
	       h = VP;
385
	       ACC_3V(h, ctx->_EyeZDir);
386
	       NORMALIZE_3FV(h);
387
	    }
388
            else {
389
	       h = light->_h_inf_norm;
390
	    }
391
 
392
	    n_dot_h = correction * DOT3(normal, h);
393
 
394
	    if (n_dot_h > 0.0F)
395
	    {
396
	       GLfloat spec_coef;
397
	       struct gl_shine_tab *tab = ctx->_ShineTable[side];
398
 
399
	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
400
 
401
	       ACC_SCALE_SCALAR_3V( contrib, spec_coef,
402
				    light->_MatSpecular[side]);
403
	    }
404
	 }
405
 
406
	 ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
407
      }
408
 
409
      COPY_3V( Fcolor[j], sum[0] );
410
      Fcolor[j][3] = sumA[0];
411
 
412
#if IDX & LIGHT_TWOSIDE
413
      COPY_3V( Bcolor[j], sum[1] );
414
      Bcolor[j][3] = sumA[1];
415
#endif
416
   }
417
}
418
 
419
 
420
 
421
 
422
/* As below, but with just a single light.
423
 */
424
static void TAG(light_fast_rgba_single)( struct gl_context *ctx,
425
					 struct vertex_buffer *VB,
426
					 struct tnl_pipeline_stage *stage,
427
					 GLvector4f *input )
428
 
429
{
430
   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
431
   const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
432
   const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
433
   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
434
#if IDX & LIGHT_TWOSIDE
435
   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
436
#endif
437
   const struct gl_light *light = ctx->Light.EnabledList.next;
438
   GLuint j = 0;
439
   GLfloat base[2][4];
440
#if IDX & LIGHT_MATERIAL
441
   const GLuint nr = VB->Count;
442
#else
443
   const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
444
#endif
445
 
446
#ifdef TRACE
447
   fprintf(stderr, "%s\n", __FUNCTION__ );
448
#endif
449
 
450
   (void) input;		/* doesn't refer to Eye or Obj */
451
 
452
   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
453
#if IDX & LIGHT_TWOSIDE
454
   VB->BackfaceColorPtr = &store->LitColor[1];
455
#endif
456
 
457
   if (nr > 1) {
458
      store->LitColor[0].stride = 16;
459
      store->LitColor[1].stride = 16;
460
   }
461
   else {
462
      store->LitColor[0].stride = 0;
463
      store->LitColor[1].stride = 0;
464
   }
465
 
466
   for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
467
 
468
      GLfloat n_dot_VP;
469
 
470
#if IDX & LIGHT_MATERIAL
471
      update_materials( ctx, store );
472
#endif
473
 
474
      /* No attenuation, so incoporate _MatAmbient into base color.
475
       */
476
#if !(IDX & LIGHT_MATERIAL)
477
      if ( j == 0 )
478
#endif
479
      {
480
	 COPY_3V(base[0], light->_MatAmbient[0]);
481
	 ACC_3V(base[0], ctx->Light._BaseColor[0] );
482
	 base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
483
 
484
#if IDX & LIGHT_TWOSIDE
485
         COPY_3V(base[1], light->_MatAmbient[1]);
486
         ACC_3V(base[1], ctx->Light._BaseColor[1]);
487
         base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
488
#endif
489
      }
490
 
491
      n_dot_VP = DOT3(normal, light->_VP_inf_norm);
492
 
493
      if (n_dot_VP < 0.0F) {
494
#if IDX & LIGHT_TWOSIDE
495
         GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
496
         GLfloat sum[3];
497
         COPY_3V(sum, base[1]);
498
         ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
499
         if (n_dot_h > 0.0F) {
500
            GLfloat spec;
501
            GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
502
            ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
503
         }
504
         COPY_3V(Bcolor[j], sum );
505
         Bcolor[j][3] = base[1][3];
506
#endif
507
	 COPY_4FV(Fcolor[j], base[0]);
508
      }
509
      else {
510
	 GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
511
	 GLfloat sum[3];
512
	 COPY_3V(sum, base[0]);
513
	 ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
514
	 if (n_dot_h > 0.0F) {
515
	    GLfloat spec;
516
	    GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
517
	    ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
518
 
519
	 }
520
	 COPY_3V(Fcolor[j], sum );
521
	 Fcolor[j][3] = base[0][3];
522
#if IDX & LIGHT_TWOSIDE
523
         COPY_4FV(Bcolor[j], base[1]);
524
#endif
525
      }
526
   }
527
}
528
 
529
 
530
/* Light infinite lights
531
 */
532
static void TAG(light_fast_rgba)( struct gl_context *ctx,
533
				  struct vertex_buffer *VB,
534
				  struct tnl_pipeline_stage *stage,
535
				  GLvector4f *input )
536
{
537
   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
538
   GLfloat sumA[2];
539
   const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
540
   const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
541
   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
542
#if IDX & LIGHT_TWOSIDE
543
   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
544
#endif
545
   GLuint j = 0;
546
#if IDX & LIGHT_MATERIAL
547
   const GLuint nr = VB->Count;
548
#else
549
   const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
550
#endif
551
   const struct gl_light *light;
552
 
553
#ifdef TRACE
554
   fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
555
#endif
556
 
557
   (void) input;
558
 
559
   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
560
   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
561
 
562
   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
563
#if IDX & LIGHT_TWOSIDE
564
   VB->BackfaceColorPtr = &store->LitColor[1];
565
#endif
566
 
567
   if (nr > 1) {
568
      store->LitColor[0].stride = 16;
569
      store->LitColor[1].stride = 16;
570
   }
571
   else {
572
      store->LitColor[0].stride = 0;
573
      store->LitColor[1].stride = 0;
574
   }
575
 
576
   for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
577
 
578
      GLfloat sum[2][3];
579
 
580
#if IDX & LIGHT_MATERIAL
581
      update_materials( ctx, store );
582
 
583
      sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
584
#if IDX & LIGHT_TWOSIDE
585
      sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
586
#endif
587
#endif
588
 
589
 
590
      COPY_3V(sum[0], ctx->Light._BaseColor[0]);
591
#if IDX & LIGHT_TWOSIDE
592
      COPY_3V(sum[1], ctx->Light._BaseColor[1]);
593
#endif
594
 
595
      foreach (light, &ctx->Light.EnabledList) {
596
	 GLfloat n_dot_h, n_dot_VP, spec;
597
 
598
	 ACC_3V(sum[0], light->_MatAmbient[0]);
599
#if IDX & LIGHT_TWOSIDE
600
         ACC_3V(sum[1], light->_MatAmbient[1]);
601
#endif
602
 
603
	 n_dot_VP = DOT3(normal, light->_VP_inf_norm);
604
 
605
	 if (n_dot_VP > 0.0F) {
606
	    ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
607
	    n_dot_h = DOT3(normal, light->_h_inf_norm);
608
	    if (n_dot_h > 0.0F) {
609
	       struct gl_shine_tab *tab = ctx->_ShineTable[0];
610
	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
611
	       ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]);
612
	    }
613
	 }
614
#if IDX & LIGHT_TWOSIDE
615
         else {
616
	    ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
617
	    n_dot_h = -DOT3(normal, light->_h_inf_norm);
618
	    if (n_dot_h > 0.0F) {
619
	       struct gl_shine_tab *tab = ctx->_ShineTable[1];
620
	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
621
	       ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]);
622
	    }
623
	 }
624
#endif
625
      }
626
 
627
      COPY_3V( Fcolor[j], sum[0] );
628
      Fcolor[j][3] = sumA[0];
629
 
630
#if IDX & LIGHT_TWOSIDE
631
      COPY_3V( Bcolor[j], sum[1] );
632
      Bcolor[j][3] = sumA[1];
633
#endif
634
   }
635
}
636
 
637
 
638
 
639
 
640
static void TAG(init_light_tab)( void )
641
{
642
   _tnl_light_tab[IDX] = TAG(light_rgba);
643
   _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba);
644
   _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single);
645
   _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec);
646
}
647
 
648
 
649
#undef TAG
650
#undef IDX
651
#undef NR_SIDES