Subversion Repositories Kolibri OS

Rev

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

  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.                   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<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.  */
  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
  652.