t_vb_lighttmp.h revision f9995b30756140724f41daf963fa06167912be7f
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 */ 47static 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 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 235static 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<light->_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 */ 424static 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 */ 532static 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 640static 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 652