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