home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / shade.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  19.7 KB  |  605 lines

  1. /* $Id: shade.c,v 1.9 1997/07/24 01:21:56 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.4
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: shade.c,v $
  26.  * Revision 1.9  1997/07/24 01:21:56  brianp
  27.  * changed precompiled header symbol from PCH to PC_HEADER
  28.  *
  29.  * Revision 1.8  1997/07/09 03:04:44  brianp
  30.  * fixed bug in gl_color_shade_vertices() with GL_COLOR_MATERIAL
  31.  *
  32.  * Revision 1.7  1997/07/05 16:24:26  brianp
  33.  * fixed FP underflow problem in pow().  Renamed h[xyz] to h_[xyz].
  34.  *
  35.  * Revision 1.6  1997/06/20 04:15:43  brianp
  36.  * optimized changing of SHININESS (Henk Kok)
  37.  *
  38.  * Revision 1.5  1997/06/20 02:28:40  brianp
  39.  * changed color components from GLfixed to GLubyte
  40.  *
  41.  * Revision 1.4  1997/05/28 03:26:29  brianp
  42.  * added precompiled header (PCH) support
  43.  *
  44.  * Revision 1.3  1997/05/23 03:01:18  brianp
  45.  * commented out a few const keywords because IRIX cc chokes on them
  46.  *
  47.  * Revision 1.2  1997/05/09 02:41:08  brianp
  48.  * call GL_SQRT() instead of sqrt()
  49.  *
  50.  * Revision 1.1  1997/04/01 04:11:04  brianp
  51.  * Initial revision
  52.  *
  53.  */
  54.  
  55.  
  56. #ifdef PC_HEADER
  57. #include "all.h"
  58. #else
  59. #include <math.h>
  60. #include "macros.h"
  61. #include "mmath.h"
  62. #include "shade.h"
  63. #include "types.h"
  64. #endif
  65.  
  66.  
  67.  
  68. /*
  69.  * Return x^y.
  70.  */
  71. static GLfloat gl_pow( GLfloat x, GLfloat y )
  72. {
  73.    GLdouble z = pow(x, y);
  74.    if (z<1.0e-10)
  75.       return 0.0F;
  76.    else
  77.       return (GLfloat) z;
  78. }
  79.  
  80.  
  81.  
  82. /*
  83.  * Use current lighting/material settings to compute the RGBA colors of
  84.  * an array of vertexes.
  85.  * Input:  side - 0=use front material, 1=use back material
  86.  *         n - number of vertexes to process
  87.  *         vertex - array of vertex positions in eye coordinates
  88.  *         normal - array of surface normal vectors
  89.  * Output:  color - array of resulting colors
  90.  */
  91. void gl_color_shade_vertices( GLcontext *ctx,
  92.                               GLuint side,
  93.                               GLuint n,
  94.                               /*const*/ GLfloat vertex[][4],
  95.                               /*const*/ GLfloat normal[][3],
  96.                               GLubyte color[][4] )
  97. {
  98.    GLint j;
  99.    GLfloat rscale, gscale, bscale, ascale;
  100.    GLfloat baseR, baseG, baseB, baseA;
  101.    GLint sumA;
  102.    struct gl_light *light;
  103.    struct gl_material *mat;
  104.  
  105.    /* Compute scale factor to go from floats in [0,1] to integers or fixed
  106.     * point values:
  107.     */
  108.    rscale = ctx->Visual->RedScale;
  109.    gscale = ctx->Visual->GreenScale;
  110.    bscale = ctx->Visual->BlueScale;
  111.    ascale = ctx->Visual->AlphaScale;
  112.  
  113.    mat = &ctx->Light.Material[side];
  114.  
  115.    /*** Compute color contribution from global lighting ***/
  116.    baseR = mat->Emission[0] + ctx->Light.Model.Ambient[0] * mat->Ambient[0];
  117.    baseG = mat->Emission[1] + ctx->Light.Model.Ambient[1] * mat->Ambient[1];
  118.    baseB = mat->Emission[2] + ctx->Light.Model.Ambient[2] * mat->Ambient[2];
  119.    baseA = mat->Diffuse[3];  /* Alpha is simple, same for all vertices */
  120.  
  121.    sumA = (GLint) (CLAMP( baseA, 0.0F, 1.0F ) * ascale);
  122.  
  123.    for (j=0;j<n;j++) {
  124.       GLfloat sumR, sumG, sumB;
  125.       GLfloat nx, ny, nz;
  126.  
  127.       if (side==0) {
  128.          /* shade frontside */
  129.          nx = normal[j][0];
  130.          ny = normal[j][1];
  131.          nz = normal[j][2];
  132.       }
  133.       else {
  134.          /* shade backside */
  135.          nx = -normal[j][0];
  136.          ny = -normal[j][1];
  137.          nz = -normal[j][2];
  138.       }
  139.  
  140.       sumR = baseR;
  141.       sumG = baseG;
  142.       sumB = baseB;
  143.  
  144.       /* Add contribution from each enabled light source */
  145.       for (light=ctx->Light.FirstEnabled; light; light=light->NextEnabled) {
  146.          GLfloat ambientR, ambientG, ambientB;
  147.          GLfloat attenuation, spot;
  148.          GLfloat VPx, VPy, VPz;  /* unit vector from vertex to light */
  149.          GLfloat n_dot_VP;       /* n dot VP */
  150.  
  151.          /* compute VP and attenuation */
  152.          if (light->Position[3]==0.0) {
  153.             /* directional light */
  154.             VPx = light->VP_inf_norm[0];
  155.             VPy = light->VP_inf_norm[1];
  156.             VPz = light->VP_inf_norm[2];
  157.             attenuation = 1.0F;
  158.          }
  159.          else {
  160.             /* positional light */
  161.             GLfloat d;     /* distance from vertex to light */
  162.             VPx = light->Position[0] - vertex[j][0];
  163.             VPy = light->Position[1] - vertex[j][1];
  164.             VPz = light->Position[2] - vertex[j][2];
  165.             d = (GLfloat) GL_SQRT( VPx*VPx + VPy*VPy + VPz*VPz );
  166.             if (d>0.001F) {
  167.                GLfloat invd = 1.0F / d;
  168.                VPx *= invd;
  169.                VPy *= invd;
  170.                VPz *= invd;
  171.             }
  172.             attenuation = 1.0F / (light->ConstantAttenuation
  173.                         + d * (light->LinearAttenuation
  174.                         + d * light->QuadraticAttenuation));
  175.          }
  176.  
  177.          /* spotlight factor */
  178.          if (light->SpotCutoff==180.0F) {
  179.             /* not a spot light */
  180.             spot = 1.0F;
  181.          }
  182.          else {
  183.             GLfloat PVx, PVy, PVz, PV_dot_dir;
  184.             PVx = -VPx;
  185.             PVy = -VPy;
  186.             PVz = -VPz;
  187.             PV_dot_dir = PVx*light->NormDirection[0]
  188.                        + PVy*light->NormDirection[1]
  189.                        + PVz*light->NormDirection[2];
  190.             if (PV_dot_dir<=0.0F || PV_dot_dir<light->CosCutoff) {
  191.                /* outside of cone */
  192.                spot = 0.0F;
  193.             }
  194.             else {
  195.                double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  196.                int k = (int) x;
  197.                spot = light->SpotExpTable[k][0]
  198.                     + (x-k)*light->SpotExpTable[k][1];
  199.             }
  200.          }
  201.  
  202.          ambientR = mat->Ambient[0] * light->Ambient[0];
  203.          ambientG = mat->Ambient[1] * light->Ambient[1];
  204.          ambientB = mat->Ambient[2] * light->Ambient[2];
  205.  
  206.          /* Compute dot product or normal and vector from V to light pos */
  207.          n_dot_VP = nx * VPx + ny * VPy + nz * VPz;
  208.  
  209.          /* diffuse and specular terms */
  210.          if (n_dot_VP<=0.0F) {
  211.             /* surface face away from light, no diffuse or specular */
  212.             GLfloat t = attenuation * spot;
  213.             sumR += t * ambientR;
  214.             sumG += t * ambientG;
  215.             sumB += t * ambientB;
  216.             /* done with this light */
  217.          }
  218.          else {
  219.             GLfloat diffuseR, diffuseG, diffuseB;
  220.             GLfloat specularR, specularG, specularB;
  221.             GLfloat h_x, h_y, h_z, n_dot_h, t;
  222.                   
  223.             /* diffuse term */
  224.             diffuseR = n_dot_VP * mat->Diffuse[0] * light->Diffuse[0];
  225.             diffuseG = n_dot_VP * mat->Diffuse[1] * light->Diffuse[1];
  226.             diffuseB = n_dot_VP * mat->Diffuse[2] * light->Diffuse[2];
  227.  
  228.             /* specular term */
  229.             if (ctx->Light.Model.LocalViewer) {
  230.                GLfloat vx, vy, vz, vlen;
  231.                vx = vertex[j][0];
  232.                vy = vertex[j][1];
  233.                vz = vertex[j][2];
  234.                vlen = GL_SQRT( vx*vx + vy*vy + vz*vz );
  235.                if (vlen>0.0001F) {
  236.                   GLfloat invlen = 1.0F / vlen;
  237.                   vx *= invlen;
  238.                   vy *= invlen;
  239.                   vz *= invlen;
  240.                }
  241.                /* h = VP + VPe */
  242.                h_x = VPx - vx;
  243.                h_y = VPy - vy;
  244.                h_z = VPz - vz;
  245.             }
  246.             else {
  247.                /* h = VP + <0,0,1> */
  248.                h_x = VPx;
  249.                h_y = VPy;
  250.                h_z = VPz + 1.0F;
  251.             }
  252.  
  253.             /* attention: h is not normalized, done later if needed */
  254.             n_dot_h = nx*h_x + ny*h_y + nz*h_z;
  255.  
  256.             if (n_dot_h<=0.0F) {
  257.                specularR = 0.0F;
  258.                specularG = 0.0F;
  259.                specularB = 0.0F;
  260.             }
  261.             else {
  262.                GLfloat spec_coef;
  263.                /* now `correct' the dot product */
  264.                n_dot_h = n_dot_h / GL_SQRT( h_x*h_x + h_y*h_y + h_z*h_z );
  265.                if (n_dot_h>1.0F) {
  266.                   /* only happens if normal vector length > 1.0 */
  267.                   spec_coef = pow( n_dot_h, mat->Shininess );
  268.                }
  269.                else {
  270.                   /* use table lookup approximation */
  271.                   int k = (int) (n_dot_h * (GLfloat) (SHINE_TABLE_SIZE-1));
  272.                   if (mat->ShineTable[k] < 0.0F)
  273.                      mat->ShineTable[k] = gl_pow( n_dot_h, mat->Shininess );
  274.                   spec_coef = mat->ShineTable[k];
  275.                }
  276.                if (spec_coef<1.0e-10) {
  277.                   specularR = 0.0F;
  278.                   specularG = 0.0F;
  279.                   specularB = 0.0F;
  280.                }
  281.                else {
  282.                   specularR = spec_coef * mat->Specular[0]*light->Specular[0];
  283.                   specularG = spec_coef * mat->Specular[1]*light->Specular[1];
  284.                   specularB = spec_coef * mat->Specular[2]*light->Specular[2];
  285.                }
  286.             }
  287.  
  288.             t = attenuation * spot;
  289.             sumR += t * (ambientR + diffuseR + specularR);
  290.             sumG += t * (ambientG + diffuseG + specularG);
  291.             sumB += t * (ambientB + diffuseB + specularB);
  292.          }
  293.  
  294.       } /*loop over lights*/
  295.  
  296.       /* clamp and convert to integer or fixed point */
  297.       color[j][0] = (GLint) (CLAMP( sumR, 0.0F, 1.0F ) * rscale);
  298.       color[j][1] = (GLint) (CLAMP( sumG, 0.0F, 1.0F ) * gscale);
  299.       color[j][2] = (GLint) (CLAMP( sumB, 0.0F, 1.0F ) * bscale);
  300.       color[j][3] = sumA;
  301.  
  302.    } /*loop over vertices*/
  303. }
  304.  
  305.  
  306.  
  307. /*
  308.  * This is an optimized version of the above function.
  309.  */
  310. void gl_color_shade_vertices_fast( GLcontext *ctx,
  311.                                    GLuint side,
  312.                                    GLuint n,
  313.                                    /*const*/ GLfloat normal[][3],
  314.                                    GLubyte color[][4] )
  315. {
  316.    GLint j;
  317.    GLfloat rscale, gscale, bscale, ascale;
  318.    GLint sumA;
  319.    GLfloat *baseColor = ctx->Light.BaseColor[side];
  320.  
  321.    /* Compute scale factor to go from floats in [0,1] to integers or fixed
  322.     * point values:
  323.     */
  324.    rscale = ctx->Visual->RedScale;
  325.    gscale = ctx->Visual->GreenScale;
  326.    bscale = ctx->Visual->BlueScale;
  327.    ascale = ctx->Visual->AlphaScale;
  328.  
  329.    /* Alpha is easy to compute, same for all vertices */
  330.    sumA = (GLint) (baseColor[3] * ascale);
  331.  
  332.    /* Loop over vertices */
  333.    for (j=0;j<n;j++) {
  334.       GLfloat sumR, sumG, sumB;
  335.       GLfloat nx, ny, nz;
  336.       struct gl_light *light;
  337.  
  338.       /* the normal vector */
  339.       if (side==0) {
  340.          nx = normal[j][0];
  341.          ny = normal[j][1];
  342.          nz = normal[j][2];
  343.       }
  344.       else {
  345.          nx = -normal[j][0];
  346.          ny = -normal[j][1];
  347.          nz = -normal[j][2];
  348.       }
  349.  
  350. #ifdef SPEED_HACK
  351.       if (nz<0.0F) {
  352.          color[j][0] = 0.0F;
  353.          color[j][1] = 0.0F;
  354.          color[j][2] = 0.0F;
  355.          color[j][3] = A;
  356.          continue;
  357.       }
  358. #endif
  359.  
  360.       /* base color from global illumination and enabled light's ambient */
  361.       sumR = baseColor[0];
  362.       sumG = baseColor[1];
  363.       sumB = baseColor[2];
  364.  
  365.       /* Add contribution from each light source */
  366.       for (light=ctx->Light.FirstEnabled; light; light=light->NextEnabled) {
  367.          GLfloat n_dot_VP;     /* n dot VP */
  368.  
  369.          n_dot_VP = nx * light->VP_inf_norm[0]
  370.                   + ny * light->VP_inf_norm[1]
  371.                   + nz * light->VP_inf_norm[2];
  372.  
  373.          /* diffuse and specular terms */
  374.          if (n_dot_VP>0.0F) {
  375.             GLfloat n_dot_h;
  376.             GLfloat *lightMatDiffuse = light->MatDiffuse[side];
  377.  
  378.             /** add diffuse term **/
  379.             sumR += n_dot_VP * lightMatDiffuse[0];
  380.             sumG += n_dot_VP * lightMatDiffuse[1];
  381.             sumB += n_dot_VP * lightMatDiffuse[2];
  382.  
  383.             /** specular term **/
  384.             /* dot product of n and h_inf_norm */
  385.             n_dot_h = nx * light->h_inf_norm[0]
  386.                     + ny * light->h_inf_norm[1]
  387.                     + nz * light->h_inf_norm[2];
  388.             if (n_dot_h>0.0F) {
  389.                if (n_dot_h>1.0F) {
  390.                   /* only happens if Magnitude(n) > 1.0 */
  391.                   GLfloat spec_coef = pow( n_dot_h,
  392.                                         ctx->Light.Material[side].Shininess );
  393.                   if (spec_coef>1.0e-10F) {
  394.                      sumR += spec_coef * light->MatSpecular[side][0];
  395.                      sumG += spec_coef * light->MatSpecular[side][1];
  396.                      sumB += spec_coef * light->MatSpecular[side][2];
  397.                   }
  398.                }
  399.                else {
  400.                   /* use table lookup approximation */
  401.                   int k = (int) (n_dot_h * (GLfloat) (SHINE_TABLE_SIZE-1));
  402.                   struct gl_material *m = &ctx->Light.Material[side];
  403.                   GLfloat spec_coef;
  404.                   if (m->ShineTable[k] < 0.0F)
  405.                      m->ShineTable[k] = gl_pow( n_dot_h, m->Shininess );
  406.                   spec_coef = m->ShineTable[k];
  407.                   sumR += spec_coef * light->MatSpecular[side][0];
  408.                   sumG += spec_coef * light->MatSpecular[side][1];
  409.                   sumB += spec_coef * light->MatSpecular[side][2];
  410.                }
  411.             }
  412.          }
  413.  
  414.       } /*loop over lights*/
  415.  
  416.       /* clamp and convert to integer or fixed point */
  417.       color[j][0] = (GLint) (MIN2( sumR, 1.0F ) * rscale);
  418.       color[j][1] = (GLint) (MIN2( sumG, 1.0F ) * gscale);
  419.       color[j][2] = (GLint) (MIN2( sumB, 1.0F ) * bscale);
  420.       color[j][3] = sumA;
  421.  
  422.    } /*loop over vertices*/
  423. }
  424.  
  425.  
  426.  
  427. /*
  428.  * Use current lighting/material settings to compute the color indexes
  429.  * for an array of vertices.
  430.  * Input:  n - number of vertices to shade
  431.  *         side - 0=use front material, 1=use back material
  432.  *         vertex - array of [n] vertex position in eye coordinates
  433.  *         normal - array of [n] surface normal vector
  434.  * Output:  indexResult - resulting array of [n] color indexes
  435.  */
  436. void gl_index_shade_vertices( GLcontext *ctx,
  437.                               GLuint side,
  438.                               GLuint n,
  439.                               GLfloat vertex[][4],
  440.                               GLfloat normal[][3],
  441.                               GLuint indexResult[] )
  442. {
  443.    struct gl_material *mat = &ctx->Light.Material[side];
  444.    GLint j;
  445.  
  446.    /* loop over vertices */
  447.    for (j=0;j<n;j++) {
  448.       GLfloat index;
  449.       GLfloat diffuse, specular;  /* accumulated diffuse and specular */
  450.       GLfloat nx, ny, nz;  /* normal vector */
  451.       struct gl_light *light;
  452.  
  453.       if (side==0) {
  454.          /* shade frontside */
  455.          nx = normal[j][0];
  456.          ny = normal[j][1];
  457.          nz = normal[j][2];
  458.       }
  459.       else {
  460.          /* shade backside */
  461.          nx = -normal[j][0];
  462.          ny = -normal[j][1];
  463.          nz = -normal[j][2];
  464.       }
  465.  
  466.       diffuse = specular = 0.0F;
  467.  
  468.       /* Accumulate diffuse and specular from each light source */
  469.       for (light=ctx->Light.FirstEnabled; light; light=light->NextEnabled) {
  470.          GLfloat attenuation;
  471.          GLfloat lx, ly, lz;  /* unit vector from vertex to light */
  472.          GLfloat l_dot_norm;  /* dot product of l and n */
  473.  
  474.          /* compute l and attenuation */
  475.          if (light->Position[3]==0.0) {
  476.             /* directional light */
  477.             /* Effectively, l is a vector from the origin to the light. */
  478.             lx = light->VP_inf_norm[0];
  479.             ly = light->VP_inf_norm[1];
  480.             lz = light->VP_inf_norm[2];
  481.             attenuation = 1.0F;
  482.          }
  483.          else {
  484.             /* positional light */
  485.             GLfloat d;     /* distance from vertex to light */
  486.             lx = light->Position[0] - vertex[j][0];
  487.             ly = light->Position[1] - vertex[j][1];
  488.             lz = light->Position[2] - vertex[j][2];
  489.             d = (GLfloat) GL_SQRT( lx*lx + ly*ly + lz*lz );
  490.             if (d>0.001F) {
  491.                GLfloat invd = 1.0F / d;
  492.                lx *= invd;
  493.                ly *= invd;
  494.                lz *= invd;
  495.             }
  496.             attenuation = 1.0F / (light->ConstantAttenuation
  497.                         + d * (light->LinearAttenuation
  498.                         + d * light->QuadraticAttenuation));
  499.          }
  500.  
  501.          l_dot_norm = lx*nx + ly*ny + lz*nz;
  502.  
  503.          if (l_dot_norm>0.0F) {
  504.             GLfloat spot_times_atten;
  505.  
  506.             /* spotlight factor */
  507.             if (light->SpotCutoff==180.0F) {
  508.                /* not a spot light */
  509.                spot_times_atten = attenuation;
  510.             }
  511.             else {
  512.                GLfloat v[3], dot;
  513.                v[0] = -lx;  /* v points from light to vertex */
  514.                v[1] = -ly;
  515.                v[2] = -lz;
  516.                dot = DOT3( v, light->NormDirection );
  517.                if (dot<=0.0F || dot<light->CosCutoff) {
  518.                   /* outside of cone */
  519.                   spot_times_atten = 0.0F;
  520.                }
  521.                else {
  522.                   double x = dot * (EXP_TABLE_SIZE-1);
  523.                   int k = (int) x;
  524.                   GLfloat spot = light->SpotExpTable[k][0]
  525.                                + (x-k)*light->SpotExpTable[k][1];
  526.                   spot_times_atten = spot * attenuation;
  527.                }
  528.             }
  529.  
  530.             /* accumulate diffuse term */
  531.             diffuse += l_dot_norm * light->dli * spot_times_atten;
  532.  
  533.             /* accumulate specular term */
  534.             {
  535.                GLfloat h_x, h_y, h_z, n_dot_h, spec_coef;
  536.  
  537.                /* specular term */
  538.                if (ctx->Light.Model.LocalViewer) {
  539.                   GLfloat vx, vy, vz, vlen;
  540.                   vx = vertex[j][0];
  541.                   vy = vertex[j][1];
  542.                   vz = vertex[j][2];
  543.                   vlen = GL_SQRT( vx*vx + vy*vy + vz*vz );
  544.                   if (vlen>0.0001F) {
  545.                      GLfloat invlen = 1.0F / vlen;
  546.                      vx *= invlen;
  547.                      vy *= invlen;
  548.                      vz *= invlen;
  549.                   }
  550.                   h_x = lx - vx;
  551.                   h_y = ly - vy;
  552.                   h_z = lz - vz;
  553.                }
  554.                else {
  555.                   h_x = lx;
  556.                   h_y = ly;
  557.                   h_z = lz + 1.0F;
  558.                }
  559.                /* attention: s is not normalized, done later if necessary */
  560.                n_dot_h = h_x*nx + h_y*ny + h_z*nz;
  561.  
  562.                if (n_dot_h <= 0.0F) {
  563.                   spec_coef = 0.0F;
  564.                }
  565.                else {
  566.                   /* now `correct' the dot product */
  567.                   n_dot_h = n_dot_h / GL_SQRT(h_x*h_x + h_y*h_y + h_z*h_z);
  568.                   if (n_dot_h>1.0F) {
  569.                      spec_coef = pow( n_dot_h, mat->Shininess );
  570.                   }
  571.                   else {
  572.                      int k = (int) (n_dot_h * (GLfloat)(SHINE_TABLE_SIZE-1));
  573.                      if (mat->ShineTable[k] < 0.0F)
  574.                         mat->ShineTable[k] = gl_pow( n_dot_h, mat->Shininess );
  575.                      spec_coef = mat->ShineTable[k];
  576.                   }
  577.                }
  578.                specular += spec_coef * light->sli * spot_times_atten;
  579.             }
  580.          }
  581.  
  582.       } /*loop over lights*/
  583.  
  584.       /* Now compute final color index */
  585.       if (specular>1.0F) {
  586.          index = mat->SpecularIndex;
  587.       }
  588.       else {
  589.          GLfloat d_a, s_a;
  590.          d_a = mat->DiffuseIndex - mat->AmbientIndex;
  591.          s_a = mat->SpecularIndex - mat->AmbientIndex;
  592.  
  593.          index = mat->AmbientIndex
  594.                + diffuse * (1.0F-specular) * d_a
  595.                + specular * s_a;
  596.          if (index>mat->SpecularIndex) {
  597.             index = mat->SpecularIndex;
  598.          }
  599.       }
  600.       indexResult[j] = (GLuint) (GLint) index;
  601.  
  602.    } /*for vertex*/
  603. }
  604.  
  605.