home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / shade_tmp.h < prev    next >
Text File  |  2000-01-07  |  24KB  |  881 lines

  1. /* $Id: shade_tmp.h,v 1.3.2.3 1999/12/12 18:30:47 keithw Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * New (3.1) transformation code written by Keith Whitwell.
  29.  */
  30.  
  31.  
  32. static void TAG(shade_rgba_spec)( struct vertex_buffer *VB )
  33. {
  34.    GLcontext *ctx = VB->ctx;
  35.    GLfloat (*base)[3] = ctx->Light.BaseColor;
  36.    GLubyte *sumA = ctx->Light.BaseAlpha;
  37.  
  38.    GLuint j;
  39.  
  40.    GLuint  vstride = VB->Unprojected->stride;
  41.    const GLfloat *vertex = VB->Unprojected->start;
  42.    GLuint vertex_size = VB->Unprojected->size;
  43.  
  44.    GLuint  nstride = VB->NormalPtr->stride; 
  45.    const GLfloat *normal = VB->NormalPtr->start;
  46.    CONST GLfloat (*first_normal)[3] = (CONST GLfloat (*)[3]) VB->NormalPtr->start;
  47.  
  48.    /* Has stride 4 to help the drivers - and us...
  49.     */
  50.    GLubyte (*CMcolor)[4] = 0;
  51.  
  52.    GLubyte (*Fcolor)[4] = (GLubyte (*)[4])VB->LitColor[0]->start;
  53.    GLubyte (*Bcolor)[4] = (GLubyte (*)[4])VB->LitColor[1]->start;
  54.    GLubyte (*Fspec)[4] = VB->Spec[0] + VB->Start;
  55.    GLubyte (*Bspec)[4] = VB->Spec[1] + VB->Start; 
  56.    GLubyte *mask = VB->CullMask + VB->Start;
  57.    GLubyte *cullmask = mask;
  58.    GLuint *flags = VB->Flag + VB->Start;
  59.  
  60.    struct gl_material (*new_material)[2] = VB->Material + VB->Start;
  61.    GLuint *new_material_mask = VB->MaterialMask + VB->Start;
  62.    GLuint nr = VB->Count - VB->Start;
  63.  
  64.    GLuint cm_flags = 0;
  65.  
  66.    (void) cullmask;
  67.    (void) nstride;
  68.    (void) first_normal;
  69.    (void) flags;
  70.  
  71.    if (ctx->Light.ColorMaterialEnabled) {
  72.       cm_flags = VERT_RGBA;
  73.  
  74.       if (VB->ColorPtr->flags & VEC_BAD_STRIDE) 
  75.      gl_clean_color(VB);
  76.  
  77.       CMcolor =  (GLubyte (*)[4])VB->ColorPtr->start;
  78.    }
  79.  
  80.    VB->Color[0] = VB->LitColor[0];
  81.    VB->Color[1] = VB->LitColor[1];
  82.    VB->ColorPtr = VB->LitColor[0];
  83.    VB->Specular = VB->Spec[0];
  84.  
  85.  
  86.    for ( j=0 ; j<nr ; j++,STRIDE_F(vertex,vstride),NEXT_VERTEX_NORMAL) 
  87.    {
  88.       GLfloat sum[2][3], spec[2][3];
  89.       struct gl_light *light;
  90.      
  91.       if ( flags[j] & cm_flags ) 
  92.      gl_update_color_material( ctx, CMcolor[j] );
  93.      
  94.       if ( flags[j] & VERT_MATERIAL )
  95.      gl_update_material( ctx, new_material[j], new_material_mask[j] );
  96.  
  97.       if ( CULL(*mask) ) 
  98.      continue;
  99.       
  100.       if (LIGHT_FRONT(*mask)) {
  101.      COPY_3V(sum[0], base[0]);
  102.      ZERO_3V(spec[0]);
  103.       }
  104.  
  105.       if (LIGHT_REAR(*mask)) {
  106.      COPY_3V(sum[1], base[1]);
  107.      ZERO_3V(spec[1]);
  108.       }
  109.       
  110.       /* Add contribution from each enabled light source */
  111.       foreach (light, &ctx->Light.EnabledList) {
  112.      GLfloat n_dot_h;
  113.      GLfloat correction;
  114.      GLint side; 
  115.      GLfloat contrib[3];
  116.      GLfloat attenuation;
  117.      GLfloat VP[3];  /* unit vector from vertex to light */
  118.      GLfloat n_dot_VP;       /* n dot VP */
  119.      GLfloat *h;
  120.      GLboolean normalized;
  121.  
  122.      /* compute VP and attenuation */
  123.      if (!(light->Flags & LIGHT_POSITIONAL)) {
  124.         /* directional light */
  125.         COPY_3V(VP, light->VP_inf_norm);
  126.         attenuation = light->VP_inf_spot_attenuation;
  127.      }
  128.      else {
  129.         GLfloat d;     /* distance from vertex to light */
  130.  
  131.         if (vertex_size == 2) {
  132.            SUB_2V(VP, light->Position, vertex);
  133.            VP[2] = light->Position[2];
  134.         } else {
  135.            SUB_3V(VP, light->Position, vertex);
  136.         }
  137.  
  138.         d = LEN_3FV( VP );
  139.  
  140.         if (d > 1e-6) {
  141.            GLfloat invd = 1.0F / d;
  142.            SELF_SCALE_SCALAR_3V(VP, invd);
  143.         }
  144.         
  145.         attenuation = 1.0F / (light->ConstantAttenuation + d * 
  146.                   (light->LinearAttenuation + d * 
  147.                    light->QuadraticAttenuation));
  148.  
  149.         /* spotlight attenuation */
  150.         if (light->Flags & LIGHT_SPOT) 
  151.         {
  152.            GLfloat PV_dot_dir = - DOT3(VP, light->NormDirection);
  153.            
  154.            if (PV_dot_dir<light->CosCutoff) {
  155.           continue; /* this light makes no contribution */
  156.            }
  157.            else {
  158.           double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  159.           int k = (int) x;
  160.           GLfloat spot = (light->SpotExpTable[k][0]
  161.                   + (x-k)*light->SpotExpTable[k][1]);
  162.           attenuation *= spot;
  163.            }
  164.         }
  165.      }
  166.  
  167.  
  168.      if (attenuation < 1e-3) 
  169.         continue;        /* this light makes no contribution */
  170.  
  171.      /* Compute dot product or normal and vector from V to light pos */
  172.      n_dot_VP = DOT3( normal, VP );
  173.  
  174.      /* Which side gets the diffuse & specular terms? */
  175.      if (n_dot_VP < 0.0F) {
  176.         if (LIGHT_FRONT(*mask)) {
  177.            ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->MatAmbient[0]);
  178.         }
  179.         if (!LIGHT_REAR(*mask)) {
  180.            continue;
  181.         }
  182.         side = 1;
  183.         correction = -1;
  184.         n_dot_VP = -n_dot_VP;
  185.      } else {
  186.         if (LIGHT_REAR(*mask)) {
  187.            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->MatAmbient[1]);
  188.         } 
  189.         if (!LIGHT_FRONT(*mask)) {
  190.            continue;
  191.         }
  192.         side = 0;
  193.         correction = 1;
  194.      } 
  195.  
  196.      /* diffuse term */
  197.      COPY_3V(contrib, light->MatAmbient[side]);
  198.      ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->MatDiffuse[side]);
  199.      ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib );
  200.  
  201.      if (!light->IsMatSpecular[side])
  202.         continue;
  203.  
  204.      /* specular term - cannibalize VP... */
  205.      if (ctx->Light.Model.LocalViewer) {
  206.         GLfloat v[3];
  207.         COPY_3V(v, vertex);
  208.         if (vertex_size == 2) v[2] = 0;
  209.         NORMALIZE_3FV(v);
  210.         SUB_3V(VP, VP, v);                /* h = VP + VPe */
  211.         h = VP;
  212.         normalized = 0;
  213.      }
  214.      else if (light->Flags & LIGHT_POSITIONAL) {
  215.         h = VP;
  216.         ACC_3V(h, ctx->EyeZDir);
  217.         normalized = 0;
  218.      } else {
  219.         h = light->h_inf_norm;
  220.         normalized = 1;
  221.      }
  222.      
  223.      n_dot_h = correction * DOT3(normal, h);
  224.  
  225.      if (n_dot_h > 0.0F) 
  226.      {
  227.         GLfloat spec_coef;
  228.         struct gl_shine_tab *tab = ctx->ShineTable[side];
  229.  
  230.         if (!normalized) {
  231.            n_dot_h *= n_dot_h;
  232.            n_dot_h /= LEN_SQUARED_3FV( h );
  233.            tab = ctx->ShineTable[side+2];
  234.         }
  235.         
  236.         if (n_dot_h>1.0) {
  237.            spec_coef = pow( n_dot_h, tab->shininess );
  238.         } else 
  239.            GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
  240.         
  241.         if (spec_coef > 1.0e-10) {
  242.            spec_coef *= attenuation;
  243.            ACC_SCALE_SCALAR_3V( spec[side], spec_coef,
  244.                     light->MatSpecular[side]);
  245.         }
  246.      }
  247.       } /*loop over lights*/
  248.  
  249.       if (LIGHT_FRONT(*mask)) {
  250.      FLOAT_RGB_TO_UBYTE_RGB( Fcolor[j], sum[0] );
  251.      FLOAT_RGB_TO_UBYTE_RGB( Fspec[j], spec[0] );
  252.      Fcolor[j][3] = sumA[0];
  253.       }
  254.  
  255.       if (LIGHT_REAR(*mask)) {
  256.      FLOAT_RGB_TO_UBYTE_RGB( Bcolor[j], sum[1] );
  257.      FLOAT_RGB_TO_UBYTE_RGB( Bspec[j], spec[1] );
  258.      Bcolor[j][3] = sumA[1];
  259.       }
  260.    } 
  261.  
  262.    if ( flags[j] & cm_flags ) 
  263.       gl_update_color_material( ctx, CMcolor[j] );
  264.    
  265.    if ( flags[j] & VERT_MATERIAL )
  266.       gl_update_material( ctx, new_material[j], new_material_mask[j] );
  267. }
  268.  
  269.  
  270. static void TAG(shade_rgba)( struct vertex_buffer *VB )
  271. {
  272.    GLuint j;
  273.    GLcontext *ctx = VB->ctx;
  274.  
  275.    GLfloat (*base)[3] = ctx->Light.BaseColor;
  276.    GLubyte *sumA = ctx->Light.BaseAlpha;
  277.  
  278.    GLuint  vstride = VB->Unprojected->stride;
  279.    const GLfloat *vertex = (GLfloat *)VB->Unprojected->start;
  280.    GLuint vertex_size = VB->Unprojected->size;
  281.  
  282.    GLuint  nstride = VB->NormalPtr->stride; 
  283.    const GLfloat *normal = VB->NormalPtr->start;
  284.    CONST GLfloat (*first_normal)[3] = (CONST GLfloat (*)[3])VB->NormalPtr->start;
  285.  
  286.    GLubyte (*CMcolor)[4] = 0;
  287.    GLubyte (*Fcolor)[4] = (GLubyte (*)[4])VB->LitColor[0]->start;
  288.    GLubyte (*Bcolor)[4] = (GLubyte (*)[4])VB->LitColor[1]->start;
  289.    GLubyte *mask = VB->CullMask + VB->Start;
  290.    GLubyte *cullmask = mask;
  291.    GLuint *flags = VB->Flag + VB->Start;
  292.    GLuint cm_flags = 0;
  293.  
  294.    struct gl_material (*new_material)[2] = VB->Material + VB->Start;
  295.    GLuint *new_material_mask = VB->MaterialMask + VB->Start;
  296.    GLuint nr = VB->Count - VB->Start;
  297.  
  298.    (void) cullmask;
  299.    (void) nstride;
  300.    (void) first_normal;
  301.    (void) flags;
  302.  
  303.    if (ctx->Light.ColorMaterialEnabled) {
  304.       cm_flags = VERT_RGBA;
  305.  
  306.       if (VB->ColorPtr->flags & VEC_BAD_STRIDE) 
  307.      gl_clean_color(VB);
  308.  
  309.       CMcolor =  (GLubyte (*)[4])VB->ColorPtr->start;
  310.    }
  311.  
  312.    VB->ColorPtr = VB->LitColor[0];
  313.    VB->Color[0] = VB->LitColor[0];
  314.    VB->Color[1] = VB->LitColor[1];
  315.  
  316.    for ( j=0 ; j<nr ; j++,STRIDE_F(vertex,vstride),NEXT_VERTEX_NORMAL) 
  317.    {
  318.       GLfloat sum[2][3];
  319.       struct gl_light *light;
  320.  
  321.       if ( flags[j] & cm_flags ) 
  322.      gl_update_color_material( ctx, CMcolor[j] );
  323.      
  324.       if ( flags[j] & VERT_MATERIAL )
  325.      gl_update_material( ctx, new_material[j], new_material_mask[j] );
  326.  
  327.       if ( CULL(*mask) ) 
  328.      continue;      
  329.  
  330.       COPY_3V(sum[0], base[0]);
  331.       
  332.       if ( NR_SIDES == 2 ) 
  333.      COPY_3V(sum[1], base[1]);
  334.       
  335.       /* Add contribution from each enabled light source */
  336.       foreach (light, &ctx->Light.EnabledList) {
  337.  
  338.      GLfloat n_dot_h;
  339.      GLfloat correction;
  340.      GLint side; 
  341.      GLfloat contrib[3];
  342.      GLfloat attenuation = 1.0;
  343.      GLfloat VP[3];          /* unit vector from vertex to light */
  344.      GLfloat n_dot_VP;       /* n dot VP */
  345.      GLfloat *h;
  346.      GLboolean normalized;
  347.  
  348.      /* compute VP and attenuation */
  349.      if (!(light->Flags & LIGHT_POSITIONAL)) {
  350.         /* directional light */
  351.         COPY_3V(VP, light->VP_inf_norm);
  352.         attenuation = light->VP_inf_spot_attenuation;
  353.      }
  354.      else {
  355.         GLfloat d;     /* distance from vertex to light */
  356.  
  357.  
  358.         /* KW: fix me */
  359.         if (vertex_size == 2) {
  360.            SUB_2V(VP, light->Position, vertex);
  361.            VP[2] = light->Position[2];
  362.         } else {
  363.            SUB_3V(VP, light->Position, vertex);
  364.         }
  365.  
  366.         d = LEN_3FV( VP );
  367.  
  368.         if ( d > 1e-6) {
  369.            GLfloat invd = 1.0F / d;
  370.            SELF_SCALE_SCALAR_3V(VP, invd);
  371.         }
  372. /*         if (light->Flags & LIGHT_ATTENUATED)  */
  373.            attenuation = 1.0F / (light->ConstantAttenuation + d * 
  374.                      (light->LinearAttenuation + d * 
  375.                       light->QuadraticAttenuation));
  376.  
  377.         /* spotlight attenuation */
  378.         if (light->Flags & LIGHT_SPOT) 
  379.         {
  380.            GLfloat PV_dot_dir = - DOT3(VP, light->NormDirection);
  381.  
  382.            if (PV_dot_dir<light->CosCutoff) {
  383.           continue; /* this light makes no contribution */
  384.            }
  385.            else {
  386.           double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  387.           int k = (int) x;
  388.           GLfloat spot = (light->SpotExpTable[k][0]
  389.                   + (x-k)*light->SpotExpTable[k][1]);
  390.           attenuation *= spot;
  391.            }
  392.         }
  393.      }
  394.  
  395.      
  396.      if (attenuation < 1e-3) 
  397.         continue;        /* this light makes no contribution */
  398.  
  399.  
  400.      /* Compute dot product or normal and vector from V to light pos */
  401.      n_dot_VP = DOT3( normal, VP );
  402.  
  403.      /* which side are we lighting? */
  404.      if (n_dot_VP < 0.0F) {
  405.         if (LIGHT_FRONT(*mask)) {
  406.            ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->MatAmbient[0]);
  407.         }
  408.         if (!LIGHT_REAR(*mask))
  409.            continue; 
  410.  
  411.         side = 1;
  412.         correction = -1;
  413.         n_dot_VP = -n_dot_VP;
  414.      } else {
  415.         if (LIGHT_REAR(*mask)) {
  416.            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->MatAmbient[1]);
  417.         } 
  418.         if (!LIGHT_FRONT(*mask))
  419.            continue; 
  420.         side = 0;
  421.         correction = 1;
  422.      } 
  423.       
  424.      COPY_3V(contrib, light->MatAmbient[side]);
  425.  
  426.      /* diffuse term */
  427.      ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->MatDiffuse[side]);
  428.  
  429.      /* specular term - cannibalize VP... */
  430.      if (light->IsMatSpecular[side])
  431.      {
  432.         if (ctx->Light.Model.LocalViewer) {
  433.            GLfloat v[3];
  434.            COPY_3V(v, vertex);
  435.            if (vertex_size == 2) v[2] = 0;
  436.            NORMALIZE_3FV(v);
  437.            SUB_3V(VP, VP, v);                /* h = VP + VPe */
  438.            h = VP;
  439.            normalized = 0;
  440.         }
  441.         else if (light->Flags & LIGHT_POSITIONAL) {
  442.            h = VP;
  443.            ACC_3V(h, ctx->EyeZDir);
  444.            normalized = 0;
  445.         } else {
  446.            h = light->h_inf_norm;
  447.            normalized = 1;
  448.         }
  449.      
  450.         n_dot_h = correction * DOT3(normal, h);
  451.  
  452.         if (n_dot_h > 0.0F) 
  453.         {
  454.            GLfloat spec_coef;
  455.            struct gl_shine_tab *tab = ctx->ShineTable[side];
  456.  
  457.            if (!normalized) {
  458.           n_dot_h *= n_dot_h;
  459.           n_dot_h /= LEN_SQUARED_3FV( h );
  460.           tab = ctx->ShineTable[side+2];
  461.            }
  462.                       
  463.            if (n_dot_h>1.0) {
  464.           spec_coef = pow( n_dot_h, tab->shininess );
  465.            } else {
  466.           GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
  467.            }
  468.  
  469.            ACC_SCALE_SCALAR_3V( contrib, spec_coef,
  470.                     light->MatSpecular[side]);
  471.         }
  472.      }
  473.  
  474.      ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
  475.       } 
  476.  
  477.       if (LIGHT_FRONT(*mask)) {
  478.      FLOAT_RGB_TO_UBYTE_RGB( Fcolor[j], sum[0] );
  479.      Fcolor[j][3] = sumA[0];
  480.       }
  481.  
  482.       if (LIGHT_REAR(*mask)) {
  483.      FLOAT_RGB_TO_UBYTE_RGB( Bcolor[j], sum[1] );
  484.      Bcolor[j][3] = sumA[1];
  485.       }
  486.    } 
  487.  
  488.    if ( flags[j] & cm_flags ) 
  489.       gl_update_color_material( ctx, CMcolor[j] );
  490.    
  491.    if ( flags[j] & VERT_MATERIAL )
  492.       gl_update_material( ctx, new_material[j], new_material_mask[j] );
  493. }
  494.  
  495.  
  496.  
  497.  
  498. /* Vertex size doesn't matter - yay! 
  499.  */
  500. static void TAG(shade_fast_rgba)( struct vertex_buffer *VB )
  501. {
  502.    GLcontext *ctx = VB->ctx;
  503.    GLfloat (*base)[3] = ctx->Light.BaseColor;
  504.    GLubyte *sumA = ctx->Light.BaseAlpha;
  505.    GLuint  nstride = VB->NormalPtr->stride; 
  506.    const GLfloat *normal = VB->NormalPtr->start;
  507.    CONST GLfloat (*first_normal)[3] = (CONST GLfloat (*)[3])VB->NormalPtr->start;
  508.    GLubyte (*CMcolor)[4] = 0;
  509.    GLubyte (*Fcolor)[4] = (GLubyte (*)[4])VB->LitColor[0]->start;
  510.    GLubyte (*Bcolor)[4] = (GLubyte (*)[4])VB->LitColor[1]->start;
  511.    GLubyte *mask = VB->NormCullStart;
  512.    GLubyte *cullmask = mask;
  513.    GLuint *flags = VB->Flag + VB->Start;
  514.    GLuint cm_flags = 0;
  515.    GLuint interesting;
  516.    GLuint j = 0;
  517.    struct gl_material (*new_material)[2] = VB->Material + VB->Start;
  518.    GLuint *new_material_mask = VB->MaterialMask + VB->Start;
  519.  
  520.    (void) cullmask;
  521.    (void) first_normal;
  522.    (void) flags;
  523.    (void) nstride;
  524.  
  525.    if (ctx->Light.ColorMaterialEnabled) 
  526.    {
  527.       cm_flags = VERT_RGBA;
  528.  
  529.       if (VB->ColorPtr->flags & VEC_BAD_STRIDE) 
  530.      gl_clean_color(VB);
  531.  
  532.       CMcolor =  (GLubyte (*)[4])VB->ColorPtr->start;
  533.       if ( *flags & VERT_RGBA ) 
  534.      gl_update_color_material( ctx, *CMcolor );
  535.    
  536.    }
  537.  
  538.    interesting = cm_flags | VERT_MATERIAL | VERT_END_VB | VERT_NORM;
  539.    VB->ColorPtr = VB->LitColor[0];
  540.    VB->Color[0] = VB->LitColor[0];
  541.    VB->Color[1] = VB->LitColor[1];
  542.  
  543.    if ( flags[j] & VERT_MATERIAL ) 
  544.       gl_update_material( ctx, new_material[j], new_material_mask[j] );
  545.  
  546.    do {
  547.       do {
  548.      if ( !CULL(*mask) ) 
  549.      {
  550.         struct gl_light *light;
  551.         GLfloat sum[2][3];
  552.         GLfloat spec;
  553.  
  554.         COPY_3V(sum[0], base[0]);
  555.         if (NR_SIDES == 2)  COPY_3V(sum[1], base[1]);
  556.  
  557.         if (MESA_VERBOSE&VERBOSE_LIGHTING)
  558.            fprintf(stderr, "light normal %d/%d, %f %f %f\n",
  559.                j, VB->Start, normal[0], normal[1], normal[2]);
  560.  
  561.  
  562.         foreach (light, &ctx->Light.EnabledList) {
  563.  
  564.            GLfloat n_dot_h;
  565.            GLint side = 0;
  566.            GLfloat n_dot_VP = DOT3(normal, light->VP_inf_norm);
  567.         
  568.            if (n_dot_VP < 0.0F) {
  569.           if ( !LIGHT_REAR(*mask) ) continue;
  570.           ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->MatDiffuse[1]);
  571.           if (!light->IsMatSpecular[1]) continue;
  572.           n_dot_h = -DOT3(normal, light->h_inf_norm);
  573.           side = 1;
  574.            } else {
  575.           if ( !LIGHT_FRONT(*mask) ) continue;
  576.           ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->MatDiffuse[0]);
  577.           if (!light->IsMatSpecular[0]) continue;
  578.           n_dot_h = DOT3(normal, light->h_inf_norm);
  579.            } 
  580.               
  581.            if (n_dot_h > 0.0F) {
  582.           struct gl_shine_tab *tab = ctx->ShineTable[side];
  583.           if (n_dot_h > 1.0) 
  584.              spec = pow( n_dot_h, tab->shininess );
  585.           else 
  586.              GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
  587.  
  588.           ACC_SCALE_SCALAR_3V( sum[side], spec, 
  589.                        light->MatSpecular[side]);
  590.            } 
  591.         }
  592.  
  593.         if (LIGHT_FRONT(*mask)) {
  594.            FLOAT_RGB_TO_UBYTE_RGB( Fcolor[j], sum[0] );
  595.            Fcolor[j][3] = sumA[0];
  596.         }
  597.  
  598.         if (LIGHT_REAR(*mask)) {
  599.            FLOAT_RGB_TO_UBYTE_RGB( Bcolor[j], sum[1] );
  600.            Bcolor[j][3] = sumA[1];
  601.         }
  602.      }     
  603.      j++;
  604.      NEXT_NORMAL;
  605.       } while ((flags[j] & interesting) == VERT_NORM);
  606.  
  607.       
  608.       if (COMPACTED) {
  609.      GLuint last = j-1;
  610.  
  611.      for ( ; !(flags[j] & interesting) ; j++ ) 
  612.      {
  613.         COPY_4UBV(Fcolor[j], Fcolor[last]);
  614.         if (NR_SIDES==2)
  615.            COPY_4UBV(Bcolor[j], Bcolor[last]);
  616.      }
  617.      
  618.      NEXT_NORMAL;
  619.       }
  620.  
  621.       if ( flags[j] & cm_flags ) 
  622.      gl_update_color_material( ctx, CMcolor[j] );
  623.       
  624.       if ( flags[j] & VERT_MATERIAL ) 
  625.      gl_update_material( ctx, new_material[j], new_material_mask[j] );
  626.  
  627.    } while (!(flags[j] & VERT_END_VB));
  628.  
  629.  
  630.  
  631.  
  632.  
  633. /*
  634.  * Use current lighting/material settings to compute the color indexes
  635.  * for an array of vertices.
  636.  * Input:  n - number of vertices to shade
  637.  *         side - 0=use front material, 1=use back material
  638.  *         vertex - array of [n] vertex position in eye coordinates
  639.  *         normal - array of [n] surface normal vector
  640.  * Output:  indexResult - resulting array of [n] color indexes
  641.  */
  642. static void TAG(shade_ci)( struct vertex_buffer *VB )
  643. {
  644.    GLuint j;
  645.  
  646.    GLcontext *ctx = VB->ctx;
  647.    GLuint  vstride = VB->Unprojected->stride;
  648.    const GLfloat *vertex = (GLfloat *)VB->Unprojected->start;
  649.    GLuint vertex_size = VB->Unprojected->size;
  650.  
  651.    GLuint  nstride = VB->NormalPtr->stride; 
  652.    const GLfloat *normal = VB->NormalPtr->start;
  653.    CONST GLfloat (*first_normal)[3] = (CONST GLfloat (*)[3])VB->NormalPtr->start;
  654.  
  655.    GLubyte (*CMcolor)[4] = 0;
  656.    GLubyte *mask = VB->CullMask + VB->Start;
  657.    GLubyte *cullmask = mask;
  658.    GLuint *flags = VB->Flag + VB->Start;
  659.    GLuint cm_flags = 0;
  660.    GLuint  *indexResult[2];
  661.  
  662.    struct gl_material (*new_material)[2] = VB->Material + VB->Start;
  663.    GLuint *new_material_mask = VB->MaterialMask + VB->Start;
  664.    GLuint nr = VB->Count - VB->Start;
  665.  
  666.    (void) cullmask;
  667.    (void) nstride;
  668.    (void) first_normal;
  669.    (void) flags;
  670.  
  671.    VB->IndexPtr = VB->LitIndex[0];
  672.    VB->Index[0] = VB->LitIndex[0];
  673.    VB->Index[1] = VB->LitIndex[1];
  674.  
  675.    indexResult[0] = VB->Index[0]->start;
  676.    indexResult[1] = VB->Index[1]->start;
  677.  
  678.    /* loop over vertices */
  679.  
  680.    if (ctx->Light.ColorMaterialEnabled) {
  681.       cm_flags = VERT_RGBA;
  682.  
  683.       if (VB->ColorPtr->flags & VEC_BAD_STRIDE) 
  684.      gl_clean_color(VB);
  685.  
  686.       CMcolor =  (GLubyte (*)[4])VB->ColorPtr->start;
  687.    }
  688.  
  689.    for ( j=0 ; j<nr ; j++,STRIDE_F(vertex,vstride),NEXT_VERTEX_NORMAL) 
  690.    {
  691.       GLfloat diffuse[2], specular[2];
  692.       GLuint side = 0;
  693.       struct gl_light *light;
  694.      
  695.       if ( flags[j] & cm_flags ) 
  696.      gl_update_color_material( ctx, CMcolor[j] );
  697.      
  698.       if ( flags[j] & VERT_MATERIAL )
  699.      gl_update_material( ctx, new_material[j], new_material_mask[j] );
  700.  
  701.       if ( CULL(*mask) ) 
  702.      continue;      
  703.  
  704.       diffuse[0] = specular[0] = 0.0F;
  705.  
  706.       if ( NR_SIDES == 2 ) {
  707.      diffuse[1] = specular[1] = 0.0F;
  708.       }
  709.  
  710.       /* Accumulate diffuse and specular from each light source */
  711.       foreach (light, &ctx->Light.EnabledList) {
  712.  
  713.      GLfloat attenuation = 1.0F;
  714.      GLfloat VP[3];  /* unit vector from vertex to light */
  715.      GLfloat n_dot_VP;  /* dot product of l and n */
  716.      GLfloat *h, n_dot_h, correction = 1.0;
  717.      GLboolean normalized;
  718.  
  719.      /* compute l and attenuation */
  720.      if (!(light->Flags & LIGHT_POSITIONAL)) {
  721.         /* directional light */
  722.         COPY_3V(VP, light->VP_inf_norm);
  723.      }
  724.      else {
  725.         GLfloat d;     /* distance from vertex to light */
  726.         
  727.         if (vertex_size == 2) {
  728.            SUB_2V(VP, light->Position, vertex);
  729.            VP[2] = light->Position[2];
  730.         } else {
  731.            SUB_3V(VP, light->Position, vertex);
  732.         }
  733.  
  734.         d = (GLfloat) LEN_3FV( VP );
  735.         if ( d > 1e-6) {
  736.            GLfloat invd = 1.0F / d;
  737.            SELF_SCALE_SCALAR_3V(VP, invd);
  738.         }
  739.  
  740.         attenuation = 1.0F / (light->ConstantAttenuation + d * 
  741.                   (light->LinearAttenuation + d * 
  742.                    light->QuadraticAttenuation));
  743.  
  744.         /* spotlight attenuation */
  745.         if (light->Flags & LIGHT_SPOT) 
  746.         {
  747.            GLfloat PV_dot_dir = - DOT3(VP, light->NormDirection);
  748.            if (PV_dot_dir<light->CosCutoff) {
  749.           continue; /* this light makes no contribution */
  750.            }
  751.            else {
  752.           double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  753.           int k = (int) x;
  754.           GLfloat spot = (GLfloat) (light->SpotExpTable[k][0]
  755.                   + (x-k)*light->SpotExpTable[k][1]);
  756.           attenuation *= spot;
  757.            }
  758.         }
  759.      }
  760.  
  761.      if (attenuation < 1e-3) 
  762.         continue;        /* this light makes no contribution */
  763.  
  764.      n_dot_VP = DOT3( normal, VP );
  765.  
  766.      /* which side are we lighting? */
  767.      if (n_dot_VP < 0.0F) {
  768.         if (!LIGHT_REAR(*mask)) 
  769.            continue;
  770.         side = 1;
  771.         correction = -1;
  772.         n_dot_VP = -n_dot_VP;
  773.      } else {
  774.         if (!LIGHT_FRONT(*mask))
  775.            continue;
  776.      }
  777.  
  778.      /* accumulate diffuse term */
  779.      diffuse[side] += n_dot_VP * light->dli * attenuation;
  780.  
  781.      /* specular term */
  782.      if (!(light->Flags & LIGHT_SPECULAR))
  783.         continue;
  784.         
  785.      if (ctx->Light.Model.LocalViewer) {
  786.         GLfloat v[3];
  787.         COPY_3V(v, vertex);
  788.         if (vertex_size == 2) v[2] = 0;
  789.         NORMALIZE_3FV(v);
  790.         SUB_3V(VP, VP, v);                /* h = VP + VPe */
  791.         h = VP;
  792.         normalized = 0;
  793.      }
  794.      else if (light->Flags & LIGHT_POSITIONAL) {
  795.         h = VP;
  796.         ACC_3V(h, ctx->EyeZDir);
  797.         normalized = 0;
  798.      } else {
  799.         h = light->h_inf_norm;
  800.         normalized = 1;
  801.      }
  802.  
  803.      n_dot_h = correction * DOT3(normal, h);
  804.  
  805.      if (n_dot_h > 0.0F) 
  806.      {
  807.         GLfloat spec_coef;
  808.         struct gl_shine_tab *tab = ctx->ShineTable[side];
  809.  
  810.         if (!normalized) {
  811.            n_dot_h *= n_dot_h;
  812.            n_dot_h /= LEN_SQUARED_3FV( h );
  813.            tab = ctx->ShineTable[side+2];
  814.         }
  815.         
  816.         if (n_dot_h>1.0) {
  817.            spec_coef = (GLfloat) pow( n_dot_h, tab->shininess );
  818.         } else {
  819.            GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef);
  820.         }
  821.         specular[side] += spec_coef * light->sli * attenuation;
  822.      }
  823.       } /*loop over lights*/
  824.  
  825.       /* Now compute final color index */
  826.       for (side = 0 ; side < NR_SIDES ; side++)
  827.       {
  828.      GLfloat index;
  829.      struct gl_material *mat;
  830.  
  831.      if (!LIGHT_SIDE(*mask, side))
  832.         continue;
  833.  
  834.      mat = &ctx->Light.Material[side];
  835.      if (specular[side] > 1.0F) {
  836.         index = mat->SpecularIndex;
  837.      }
  838.      else {
  839.         GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex;
  840.         GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex;
  841.            
  842.         index = mat->AmbientIndex
  843.            + diffuse[side] * (1.0F-specular[side]) * d_a
  844.            + specular[side] * s_a;
  845.         if (index > mat->SpecularIndex) {
  846.            index = mat->SpecularIndex;
  847.         }
  848.      }
  849.      indexResult[side][j] = (GLuint) (GLint) index;
  850.       }
  851.    } /*for vertex*/
  852.  
  853.       if ( flags[j] & cm_flags ) 
  854.      gl_update_color_material( ctx, CMcolor[j] );
  855.      
  856.       if ( flags[j] & VERT_MATERIAL )
  857.      gl_update_material( ctx, new_material[j], new_material_mask[j] );
  858.  
  859. }
  860.  
  861.  
  862.  
  863. static void TAG(init_shade_tab)( void )
  864. {
  865.    gl_shade_func_tab[IDX|SHADE_RGBA_VERTICES] = TAG(shade_rgba);
  866.    gl_shade_func_tab[IDX|SHADE_RGBA_NORMALS] = TAG(shade_fast_rgba);
  867.    gl_shade_func_tab[IDX|SHADE_RGBA_SPEC] = TAG(shade_rgba_spec);
  868.    gl_shade_func_tab[IDX] = TAG(shade_ci);
  869. }
  870.  
  871.  
  872. #undef TAG
  873. #undef INVALID
  874. #undef IDX 
  875. #undef LIGHT_FRONT
  876. #undef LIGHT_REAR
  877. #undef LIGHT_SIDE
  878. #undef NR_SIDES 
  879. #undef CULL
  880.