mesa: remove gl_light::_SpotExpTable field
[mesa.git] / src / mesa / tnl / t_vb_lighttmp.h
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 <keith@tungstengraphics.com>
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<light->_CosCutoff) {
147 continue; /* this light makes no contribution */
148 }
149 else {
150 GLfloat spot = powf(PV_dot_dir, light->SpotExponent);
151 attenuation *= spot;
152 }
153 }
154 }
155
156 if (attenuation < 1e-3)
157 continue; /* this light makes no contribution */
158
159 /* Compute dot product or normal and vector from V to light pos */
160 n_dot_VP = DOT3( normal, VP );
161
162 /* Which side gets the diffuse & specular terms? */
163 if (n_dot_VP < 0.0F) {
164 ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
165 #if IDX & LIGHT_TWOSIDE
166 side = 1;
167 correction = -1;
168 n_dot_VP = -n_dot_VP;
169 #else
170 continue;
171 #endif
172 }
173 else {
174 #if IDX & LIGHT_TWOSIDE
175 ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
176 #endif
177 side = 0;
178 correction = 1;
179 }
180
181 /* diffuse term */
182 COPY_3V(contrib, light->_MatAmbient[side]);
183 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
184 ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib );
185
186 /* specular term - cannibalize VP... */
187 if (ctx->Light.Model.LocalViewer) {
188 GLfloat v[3];
189 COPY_3V(v, vertex);
190 NORMALIZE_3FV(v);
191 SUB_3V(VP, VP, v); /* h = VP + VPe */
192 h = VP;
193 NORMALIZE_3FV(h);
194 }
195 else if (light->_Flags & LIGHT_POSITIONAL) {
196 h = VP;
197 ACC_3V(h, ctx->_EyeZDir);
198 NORMALIZE_3FV(h);
199 }
200 else {
201 h = light->_h_inf_norm;
202 }
203
204 n_dot_h = correction * DOT3(normal, h);
205
206 if (n_dot_h > 0.0F) {
207 GLfloat spec_coef;
208 struct gl_shine_tab *tab = ctx->_ShineTable[side];
209 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
210
211 if (spec_coef > 1.0e-10) {
212 spec_coef *= attenuation;
213 ACC_SCALE_SCALAR_3V( spec[side], spec_coef,
214 light->_MatSpecular[side]);
215 }
216 }
217 } /*loop over lights*/
218
219 COPY_3V( Fcolor[j], sum[0] );
220 COPY_3V( Fspec[j], spec[0] );
221 Fcolor[j][3] = sumA[0];
222
223 #if IDX & LIGHT_TWOSIDE
224 COPY_3V( Bcolor[j], sum[1] );
225 COPY_3V( Bspec[j], spec[1] );
226 Bcolor[j][3] = sumA[1];
227 #endif
228 }
229 }
230
231
232 static void TAG(light_rgba)( struct gl_context *ctx,
233 struct vertex_buffer *VB,
234 struct tnl_pipeline_stage *stage,
235 GLvector4f *input )
236 {
237 struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
238 GLuint j;
239
240 GLfloat (*base)[3] = ctx->Light._BaseColor;
241 GLfloat sumA[2];
242
243 const GLuint vstride = input->stride;
244 const GLfloat *vertex = (GLfloat *) input->data;
245 const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
246 const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
247
248 GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
249 #if IDX & LIGHT_TWOSIDE
250 GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
251 #endif
252
253 const GLuint nr = VB->Count;
254
255 #ifdef TRACE
256 fprintf(stderr, "%s\n", __FUNCTION__ );
257 #endif
258
259 VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
260 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
261
262 #if IDX & LIGHT_TWOSIDE
263 VB->BackfaceColorPtr = &store->LitColor[1];
264 sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
265 #endif
266
267 store->LitColor[0].stride = 16;
268 store->LitColor[1].stride = 16;
269
270 for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
271 GLfloat sum[2][3];
272 struct gl_light *light;
273
274 #if IDX & LIGHT_MATERIAL
275 update_materials( ctx, store );
276 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
277 #if IDX & LIGHT_TWOSIDE
278 sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
279 #endif
280 #endif
281
282 COPY_3V(sum[0], base[0]);
283
284 #if IDX & LIGHT_TWOSIDE
285 COPY_3V(sum[1], base[1]);
286 #endif
287
288 /* Add contribution from each enabled light source */
289 foreach (light, &ctx->Light.EnabledList) {
290
291 GLfloat n_dot_h;
292 GLfloat correction;
293 GLint side;
294 GLfloat contrib[3];
295 GLfloat attenuation = 1.0;
296 GLfloat VP[3]; /* unit vector from vertex to light */
297 GLfloat n_dot_VP; /* n dot VP */
298 GLfloat *h;
299
300 /* compute VP and attenuation */
301 if (!(light->_Flags & LIGHT_POSITIONAL)) {
302 /* directional light */
303 COPY_3V(VP, light->_VP_inf_norm);
304 attenuation = light->_VP_inf_spot_attenuation;
305 }
306 else {
307 GLfloat d; /* distance from vertex to light */
308
309
310 SUB_3V(VP, light->_Position, vertex);
311
312 d = (GLfloat) LEN_3FV( VP );
313
314 if ( d > 1e-6) {
315 GLfloat invd = 1.0F / d;
316 SELF_SCALE_SCALAR_3V(VP, invd);
317 }
318
319 attenuation = 1.0F / (light->ConstantAttenuation + d *
320 (light->LinearAttenuation + d *
321 light->QuadraticAttenuation));
322
323 /* spotlight attenuation */
324 if (light->_Flags & LIGHT_SPOT) {
325 GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection);
326
327 if (PV_dot_dir<light->_CosCutoff) {
328 continue; /* this light makes no contribution */
329 }
330 else {
331 GLfloat spot = powf(PV_dot_dir, light->SpotExponent);
332 attenuation *= spot;
333 }
334 }
335 }
336
337 if (attenuation < 1e-3)
338 continue; /* this light makes no contribution */
339
340 /* Compute dot product or normal and vector from V to light pos */
341 n_dot_VP = DOT3( normal, VP );
342
343 /* which side are we lighting? */
344 if (n_dot_VP < 0.0F) {
345 ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
346 #if IDX & LIGHT_TWOSIDE
347 side = 1;
348 correction = -1;
349 n_dot_VP = -n_dot_VP;
350 #else
351 continue;
352 #endif
353 }
354 else {
355 #if IDX & LIGHT_TWOSIDE
356 ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
357 #endif
358 side = 0;
359 correction = 1;
360 }
361
362 COPY_3V(contrib, light->_MatAmbient[side]);
363
364 /* diffuse term */
365 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
366
367 /* specular term - cannibalize VP... */
368 {
369 if (ctx->Light.Model.LocalViewer) {
370 GLfloat v[3];
371 COPY_3V(v, vertex);
372 NORMALIZE_3FV(v);
373 SUB_3V(VP, VP, v); /* h = VP + VPe */
374 h = VP;
375 NORMALIZE_3FV(h);
376 }
377 else if (light->_Flags & LIGHT_POSITIONAL) {
378 h = VP;
379 ACC_3V(h, ctx->_EyeZDir);
380 NORMALIZE_3FV(h);
381 }
382 else {
383 h = light->_h_inf_norm;
384 }
385
386 n_dot_h = correction * DOT3(normal, h);
387
388 if (n_dot_h > 0.0F)
389 {
390 GLfloat spec_coef;
391 struct gl_shine_tab *tab = ctx->_ShineTable[side];
392
393 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
394
395 ACC_SCALE_SCALAR_3V( contrib, spec_coef,
396 light->_MatSpecular[side]);
397 }
398 }
399
400 ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
401 }
402
403 COPY_3V( Fcolor[j], sum[0] );
404 Fcolor[j][3] = sumA[0];
405
406 #if IDX & LIGHT_TWOSIDE
407 COPY_3V( Bcolor[j], sum[1] );
408 Bcolor[j][3] = sumA[1];
409 #endif
410 }
411 }
412
413
414
415
416 /* As below, but with just a single light.
417 */
418 static void TAG(light_fast_rgba_single)( struct gl_context *ctx,
419 struct vertex_buffer *VB,
420 struct tnl_pipeline_stage *stage,
421 GLvector4f *input )
422
423 {
424 struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
425 const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
426 const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
427 GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
428 #if IDX & LIGHT_TWOSIDE
429 GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
430 #endif
431 const struct gl_light *light = ctx->Light.EnabledList.next;
432 GLuint j = 0;
433 GLfloat base[2][4];
434 #if IDX & LIGHT_MATERIAL
435 const GLuint nr = VB->Count;
436 #else
437 const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
438 #endif
439
440 #ifdef TRACE
441 fprintf(stderr, "%s\n", __FUNCTION__ );
442 #endif
443
444 (void) input; /* doesn't refer to Eye or Obj */
445
446 VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
447 #if IDX & LIGHT_TWOSIDE
448 VB->BackfaceColorPtr = &store->LitColor[1];
449 #endif
450
451 if (nr > 1) {
452 store->LitColor[0].stride = 16;
453 store->LitColor[1].stride = 16;
454 }
455 else {
456 store->LitColor[0].stride = 0;
457 store->LitColor[1].stride = 0;
458 }
459
460 for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
461
462 GLfloat n_dot_VP;
463
464 #if IDX & LIGHT_MATERIAL
465 update_materials( ctx, store );
466 #endif
467
468 /* No attenuation, so incoporate _MatAmbient into base color.
469 */
470 #if !(IDX & LIGHT_MATERIAL)
471 if ( j == 0 )
472 #endif
473 {
474 COPY_3V(base[0], light->_MatAmbient[0]);
475 ACC_3V(base[0], ctx->Light._BaseColor[0] );
476 base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
477
478 #if IDX & LIGHT_TWOSIDE
479 COPY_3V(base[1], light->_MatAmbient[1]);
480 ACC_3V(base[1], ctx->Light._BaseColor[1]);
481 base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
482 #endif
483 }
484
485 n_dot_VP = DOT3(normal, light->_VP_inf_norm);
486
487 if (n_dot_VP < 0.0F) {
488 #if IDX & LIGHT_TWOSIDE
489 GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
490 GLfloat sum[3];
491 COPY_3V(sum, base[1]);
492 ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
493 if (n_dot_h > 0.0F) {
494 GLfloat spec;
495 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
496 ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
497 }
498 COPY_3V(Bcolor[j], sum );
499 Bcolor[j][3] = base[1][3];
500 #endif
501 COPY_4FV(Fcolor[j], base[0]);
502 }
503 else {
504 GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
505 GLfloat sum[3];
506 COPY_3V(sum, base[0]);
507 ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
508 if (n_dot_h > 0.0F) {
509 GLfloat spec;
510 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
511 ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
512
513 }
514 COPY_3V(Fcolor[j], sum );
515 Fcolor[j][3] = base[0][3];
516 #if IDX & LIGHT_TWOSIDE
517 COPY_4FV(Bcolor[j], base[1]);
518 #endif
519 }
520 }
521 }
522
523
524 /* Light infinite lights
525 */
526 static void TAG(light_fast_rgba)( struct gl_context *ctx,
527 struct vertex_buffer *VB,
528 struct tnl_pipeline_stage *stage,
529 GLvector4f *input )
530 {
531 struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
532 GLfloat sumA[2];
533 const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
534 const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
535 GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
536 #if IDX & LIGHT_TWOSIDE
537 GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
538 #endif
539 GLuint j = 0;
540 #if IDX & LIGHT_MATERIAL
541 const GLuint nr = VB->Count;
542 #else
543 const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
544 #endif
545 const struct gl_light *light;
546
547 #ifdef TRACE
548 fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
549 #endif
550
551 (void) input;
552
553 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
554 sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
555
556 VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
557 #if IDX & LIGHT_TWOSIDE
558 VB->BackfaceColorPtr = &store->LitColor[1];
559 #endif
560
561 if (nr > 1) {
562 store->LitColor[0].stride = 16;
563 store->LitColor[1].stride = 16;
564 }
565 else {
566 store->LitColor[0].stride = 0;
567 store->LitColor[1].stride = 0;
568 }
569
570 for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
571
572 GLfloat sum[2][3];
573
574 #if IDX & LIGHT_MATERIAL
575 update_materials( ctx, store );
576
577 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
578 #if IDX & LIGHT_TWOSIDE
579 sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
580 #endif
581 #endif
582
583
584 COPY_3V(sum[0], ctx->Light._BaseColor[0]);
585 #if IDX & LIGHT_TWOSIDE
586 COPY_3V(sum[1], ctx->Light._BaseColor[1]);
587 #endif
588
589 foreach (light, &ctx->Light.EnabledList) {
590 GLfloat n_dot_h, n_dot_VP, spec;
591
592 ACC_3V(sum[0], light->_MatAmbient[0]);
593 #if IDX & LIGHT_TWOSIDE
594 ACC_3V(sum[1], light->_MatAmbient[1]);
595 #endif
596
597 n_dot_VP = DOT3(normal, light->_VP_inf_norm);
598
599 if (n_dot_VP > 0.0F) {
600 ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
601 n_dot_h = DOT3(normal, light->_h_inf_norm);
602 if (n_dot_h > 0.0F) {
603 struct gl_shine_tab *tab = ctx->_ShineTable[0];
604 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
605 ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]);
606 }
607 }
608 #if IDX & LIGHT_TWOSIDE
609 else {
610 ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
611 n_dot_h = -DOT3(normal, light->_h_inf_norm);
612 if (n_dot_h > 0.0F) {
613 struct gl_shine_tab *tab = ctx->_ShineTable[1];
614 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
615 ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]);
616 }
617 }
618 #endif
619 }
620
621 COPY_3V( Fcolor[j], sum[0] );
622 Fcolor[j][3] = sumA[0];
623
624 #if IDX & LIGHT_TWOSIDE
625 COPY_3V( Bcolor[j], sum[1] );
626 Bcolor[j][3] = sumA[1];
627 #endif
628 }
629 }
630
631
632
633
634 static void TAG(init_light_tab)( void )
635 {
636 _tnl_light_tab[IDX] = TAG(light_rgba);
637 _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba);
638 _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single);
639 _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec);
640 }
641
642
643 #undef TAG
644 #undef IDX
645 #undef NR_SIDES