home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / light.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  37KB  |  1,260 lines

  1. /* $Id: light.c,v 1.8.2.1 1999/11/22 19:01:39 brianp 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.  
  29.  
  30.  
  31. #ifdef PC_HEADER
  32. #include "all.h"
  33. #else
  34. #include <float.h>
  35. #ifndef XFree86Server
  36. #include <assert.h>
  37. #include <float.h>
  38. #include <math.h>
  39. #include <stdlib.h>
  40. #include <stdio.h>
  41. #else
  42. #include "GL/xf86glx.h"
  43. #endif
  44. #include "context.h"
  45. #include "enums.h"
  46. #include "light.h"
  47. #include "macros.h"
  48. #include "matrix.h"
  49. #include "mmath.h"
  50. #include "simple_list.h"
  51. #include "types.h"
  52. #include "vb.h"
  53. #include "xform.h"
  54. #endif
  55.  
  56.  
  57.  
  58. void gl_ShadeModel( GLcontext *ctx, GLenum mode )
  59. {
  60.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
  61.  
  62.    if (MESA_VERBOSE & VERBOSE_API)
  63.       fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
  64.  
  65.    if (mode == GL_FLAT || mode == GL_SMOOTH) {
  66.       if (ctx->Light.ShadeModel != mode) {
  67.      ctx->Light.ShadeModel = mode;
  68.          if (ctx->Light.ShadeModel == GL_FLAT)
  69.             ctx->TriangleCaps |= DD_FLATSHADE;
  70.          else
  71.             ctx->TriangleCaps &= ~DD_FLATSHADE;
  72.      ctx->NewState |= NEW_RASTER_OPS;
  73.          if (ctx->Driver.ShadeModel) 
  74.             (*ctx->Driver.ShadeModel)( ctx, mode );
  75.       }
  76.    }
  77.    else {
  78.       gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
  79.    }
  80. }
  81.  
  82.  
  83.  
  84. void gl_Lightfv( GLcontext *ctx,
  85.                  GLenum light, GLenum pname, const GLfloat *params,
  86.                  GLint nparams )
  87. {
  88.    GLint l;
  89.  
  90.    (void) nparams;
  91.  
  92.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
  93.  
  94.    l = (GLint) (light - GL_LIGHT0);
  95.  
  96.    if (l<0 || l>=MAX_LIGHTS) {
  97.       gl_error( ctx, GL_INVALID_ENUM, "glLight" );
  98.       return;
  99.    }
  100.  
  101.    switch (pname) {
  102.       case GL_AMBIENT:
  103.          COPY_4V( ctx->Light.Light[l].Ambient, params );
  104.          break;
  105.       case GL_DIFFUSE:
  106.          COPY_4V( ctx->Light.Light[l].Diffuse, params );
  107.          break;
  108.       case GL_SPECULAR:
  109.          COPY_4V( ctx->Light.Light[l].Specular, params );
  110.          break;
  111.       case GL_POSITION:
  112.      /* transform position by ModelView matrix */
  113.      TRANSFORM_POINT( ctx->Light.Light[l].EyePosition, 
  114.               ctx->ModelView.m,
  115.                           params );
  116.          break;
  117.       case GL_SPOT_DIRECTION:
  118.      /* transform direction by inverse modelview */
  119.      if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
  120.         gl_matrix_analyze( &ctx->ModelView );
  121.      }
  122.      TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
  123.                params,
  124.                ctx->ModelView.inv );
  125.          break;
  126.       case GL_SPOT_EXPONENT:
  127.          if (params[0]<0.0 || params[0]>128.0) {
  128.             gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  129.             return;
  130.          }
  131.          if (ctx->Light.Light[l].SpotExponent != params[0]) {
  132.             ctx->Light.Light[l].SpotExponent = params[0];
  133.             gl_compute_spot_exp_table( &ctx->Light.Light[l] );
  134.          }
  135.          break;
  136.       case GL_SPOT_CUTOFF:
  137.          if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
  138.             gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  139.             return;
  140.          }
  141.          ctx->Light.Light[l].SpotCutoff = params[0];
  142.          ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
  143.          if (ctx->Light.Light[l].CosCutoff < 0) 
  144.         ctx->Light.Light[l].CosCutoff = 0;
  145.          break;
  146.       case GL_CONSTANT_ATTENUATION:
  147.          if (params[0]<0.0) {
  148.             gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  149.             return;
  150.          }
  151.          ctx->Light.Light[l].ConstantAttenuation = params[0];
  152.          break;
  153.       case GL_LINEAR_ATTENUATION:
  154.          if (params[0]<0.0) {
  155.             gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  156.             return;
  157.          }
  158.          ctx->Light.Light[l].LinearAttenuation = params[0];
  159.          break;
  160.       case GL_QUADRATIC_ATTENUATION:
  161.          if (params[0]<0.0) {
  162.             gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  163.             return;
  164.          }
  165.          ctx->Light.Light[l].QuadraticAttenuation = params[0];
  166.          break;
  167.       default:
  168.          gl_error( ctx, GL_INVALID_ENUM, "glLight" );
  169.          break;
  170.    }
  171.  
  172.    if (ctx->Driver.Lightfv)
  173.       ctx->Driver.Lightfv( ctx, light, pname, params, nparams );
  174.  
  175.    ctx->NewState |= NEW_LIGHTING;
  176. }
  177.  
  178.  
  179.  
  180. void gl_GetLightfv( GLcontext *ctx,
  181.                     GLenum light, GLenum pname, GLfloat *params )
  182. {
  183.    GLint l = (GLint) (light - GL_LIGHT0);
  184.  
  185.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
  186.  
  187.    if (l<0 || l>=MAX_LIGHTS) {
  188.       gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  189.       return;
  190.    }
  191.  
  192.    switch (pname) {
  193.       case GL_AMBIENT:
  194.          COPY_4V( params, ctx->Light.Light[l].Ambient );
  195.          break;
  196.       case GL_DIFFUSE:
  197.          COPY_4V( params, ctx->Light.Light[l].Diffuse );
  198.          break;
  199.       case GL_SPECULAR:
  200.          COPY_4V( params, ctx->Light.Light[l].Specular );
  201.          break;
  202.       case GL_POSITION:
  203.          COPY_4V( params, ctx->Light.Light[l].EyePosition );
  204.          break;
  205.       case GL_SPOT_DIRECTION:
  206.          COPY_3V( params, ctx->Light.Light[l].EyeDirection );
  207.          break;
  208.       case GL_SPOT_EXPONENT:
  209.          params[0] = ctx->Light.Light[l].SpotExponent;
  210.          break;
  211.       case GL_SPOT_CUTOFF:
  212.          params[0] = ctx->Light.Light[l].SpotCutoff;
  213.          break;
  214.       case GL_CONSTANT_ATTENUATION:
  215.          params[0] = ctx->Light.Light[l].ConstantAttenuation;
  216.          break;
  217.       case GL_LINEAR_ATTENUATION:
  218.          params[0] = ctx->Light.Light[l].LinearAttenuation;
  219.          break;
  220.       case GL_QUADRATIC_ATTENUATION:
  221.          params[0] = ctx->Light.Light[l].QuadraticAttenuation;
  222.          break;
  223.       default:
  224.          gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  225.          break;
  226.    }
  227. }
  228.  
  229.  
  230.  
  231. void gl_GetLightiv( GLcontext *ctx, GLenum light, GLenum pname, GLint *params )
  232. {
  233.    GLint l = (GLint) (light - GL_LIGHT0);
  234.  
  235.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
  236.  
  237.    if (l<0 || l>=MAX_LIGHTS) {
  238.       gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  239.       return;
  240.    }
  241.  
  242.    switch (pname) {
  243.       case GL_AMBIENT:
  244.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
  245.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
  246.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
  247.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
  248.          break;
  249.       case GL_DIFFUSE:
  250.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
  251.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
  252.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
  253.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
  254.          break;
  255.       case GL_SPECULAR:
  256.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
  257.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
  258.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
  259.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
  260.          break;
  261.       case GL_POSITION:
  262.          params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
  263.          params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
  264.          params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
  265.          params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
  266.          break;
  267.       case GL_SPOT_DIRECTION:
  268.          params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
  269.          params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
  270.          params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
  271.          break;
  272.       case GL_SPOT_EXPONENT:
  273.          params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
  274.          break;
  275.       case GL_SPOT_CUTOFF:
  276.          params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
  277.          break;
  278.       case GL_CONSTANT_ATTENUATION:
  279.          params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
  280.          break;
  281.       case GL_LINEAR_ATTENUATION:
  282.          params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
  283.          break;
  284.       case GL_QUADRATIC_ATTENUATION:
  285.          params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
  286.          break;
  287.       default:
  288.          gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  289.          break;
  290.    }
  291. }
  292.  
  293.  
  294.  
  295. /**********************************************************************/
  296. /***                        Light Model                             ***/
  297. /**********************************************************************/
  298.  
  299.  
  300. void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
  301. {
  302.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModel");
  303.  
  304.    switch (pname) {
  305.       case GL_LIGHT_MODEL_AMBIENT:
  306.          COPY_4V( ctx->Light.Model.Ambient, params );
  307.          break;
  308.       case GL_LIGHT_MODEL_LOCAL_VIEWER:
  309.          if (params[0]==0.0)
  310.             ctx->Light.Model.LocalViewer = GL_FALSE;
  311.          else
  312.             ctx->Light.Model.LocalViewer = GL_TRUE;
  313.          break;
  314.       case GL_LIGHT_MODEL_TWO_SIDE:
  315.          if (params[0]==0.0) 
  316.             ctx->Light.Model.TwoSide = GL_FALSE;
  317.          else
  318.             ctx->Light.Model.TwoSide = GL_TRUE;
  319.          break;
  320.       case GL_LIGHT_MODEL_COLOR_CONTROL:
  321.          if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
  322.             ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
  323.             ctx->TriangleCaps &= ~DD_SEPERATE_SPECULAR;
  324.          }
  325.          else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
  326.             ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
  327.         ctx->TriangleCaps |= DD_SEPERATE_SPECULAR;
  328.      }
  329.          else {
  330.             gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
  331.          }
  332.      ctx->NewState |= NEW_RASTER_OPS;
  333.          break;
  334.       default:
  335.          gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
  336.          break;
  337.    }
  338.  
  339.    if (ctx->Driver.LightModelfv) 
  340.       ctx->Driver.LightModelfv( ctx, pname, params );
  341.  
  342.    ctx->NewState |= NEW_LIGHTING;
  343. }
  344.  
  345.  
  346.  
  347.  
  348. /********** MATERIAL **********/
  349.  
  350.  
  351. /*
  352.  * Given a face and pname value (ala glColorMaterial), compute a bitmask
  353.  * of the targeted material values.
  354.  */
  355. GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname, 
  356.                 GLuint legal,
  357.                 const char *where )
  358. {
  359.    GLuint bitmask = 0;
  360.  
  361.    /* Make a bitmask indicating what material attribute(s) we're updating */
  362.    switch (pname) {
  363.       case GL_EMISSION:
  364.          bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
  365.          break;
  366.       case GL_AMBIENT:
  367.          bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
  368.          break;
  369.       case GL_DIFFUSE:
  370.          bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
  371.          break;
  372.       case GL_SPECULAR:
  373.          bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
  374.          break;
  375.       case GL_SHININESS:
  376.          bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
  377.          break;
  378.       case GL_AMBIENT_AND_DIFFUSE:
  379.          bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
  380.          bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
  381.          break;
  382.       case GL_COLOR_INDEXES:
  383.          bitmask |= FRONT_INDEXES_BIT  | BACK_INDEXES_BIT;
  384.          break;
  385.       default:
  386.          gl_error( ctx, GL_INVALID_ENUM, where );
  387.          return 0;
  388.    }
  389.  
  390.    if (face==GL_FRONT) {
  391.       bitmask &= FRONT_MATERIAL_BITS;
  392.    }
  393.    else if (face==GL_BACK) {
  394.       bitmask &= BACK_MATERIAL_BITS;
  395.    }
  396.    else if (face != GL_FRONT_AND_BACK) {
  397.       gl_error( ctx, GL_INVALID_ENUM, where );
  398.       return 0;
  399.    }
  400.    
  401.    if (bitmask & ~legal) {
  402.       gl_error( ctx, GL_INVALID_ENUM, where );
  403.       return 0;
  404.    }
  405.  
  406.    return bitmask;
  407. }
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414. /*
  415.  * Check if the global material has to be updated with info that was
  416.  * associated with a vertex via glMaterial.
  417.  * This function is used when any material values get changed between
  418.  * glBegin/glEnd either by calling glMaterial() or by calling glColor()
  419.  * when GL_COLOR_MATERIAL is enabled.
  420.  *
  421.  * KW: Added code here to keep the precomputed variables uptodate.
  422.  *     This means we can use the faster shade functions when using
  423.  *     GL_COLOR_MATERIAL, and we can also now use the precomputed 
  424.  *     values in the slower shading functions, which further offsets
  425.  *     the cost of doing this here.
  426.  */
  427. void gl_update_material( GLcontext *ctx, 
  428.              struct gl_material *src, 
  429.              GLuint bitmask )
  430. {
  431.    struct gl_light *light, *list = &ctx->Light.EnabledList;
  432.    GLfloat tmp[4];
  433.  
  434.    if (ctx->Light.ColorMaterialEnabled)
  435.       bitmask &= ~ctx->Light.ColorMaterialBitmask;
  436.  
  437.    if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  438.       fprintf(stderr, "gl_update_material, mask %x\n", bitmask);
  439.  
  440.    if (!bitmask) 
  441.       return;
  442.  
  443.    if (bitmask & FRONT_AMBIENT_BIT) {
  444.       struct gl_material *mat = &ctx->Light.Material[0];
  445.       SUB_3V( tmp, src[0].Ambient, mat->Ambient );
  446.       ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
  447.       foreach (light, list) {
  448.      ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
  449.       }
  450.       COPY_4FV( mat->Ambient, src[0].Ambient );
  451.    }
  452.    if (bitmask & BACK_AMBIENT_BIT) {
  453.       struct gl_material *mat = &ctx->Light.Material[1];
  454.       SUB_3V( tmp, src[1].Ambient, mat->Ambient );
  455.       ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
  456.       foreach (light, list) {
  457.      ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
  458.       }
  459.       COPY_4FV( mat->Ambient, src[1].Ambient );
  460.    }
  461.    if (bitmask & FRONT_DIFFUSE_BIT) {
  462.       struct gl_material *mat = &ctx->Light.Material[0];
  463.       SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
  464.       foreach (light, list) {
  465.      ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
  466.       }
  467.       COPY_4FV( mat->Diffuse, src[0].Diffuse );
  468.       FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
  469.    }
  470.    if (bitmask & BACK_DIFFUSE_BIT) {
  471.       struct gl_material *mat = &ctx->Light.Material[1];
  472.       SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
  473.       foreach (light, list) {
  474.      ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
  475.       }
  476.       COPY_4FV( mat->Diffuse, src[1].Diffuse );
  477.       FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
  478.    }
  479.    if (bitmask & FRONT_SPECULAR_BIT) {
  480.       struct gl_material *mat = &ctx->Light.Material[0];
  481.       SUB_3V( tmp, src[0].Specular, mat->Specular );
  482.       foreach (light, list) {
  483.      if (light->Flags & LIGHT_SPECULAR) {
  484.         ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
  485.         light->IsMatSpecular[0] = 
  486.            (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
  487.      }
  488.       }
  489.       COPY_4FV( mat->Specular, src[0].Specular );
  490.    }
  491.    if (bitmask & BACK_SPECULAR_BIT) {
  492.       struct gl_material *mat = &ctx->Light.Material[1];
  493.       SUB_3V( tmp, src[1].Specular, mat->Specular );
  494.       foreach (light, list) {
  495.      if (light->Flags & LIGHT_SPECULAR) {
  496.         ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
  497.         light->IsMatSpecular[1] = 
  498.            (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
  499.      }
  500.       }
  501.       COPY_4FV( mat->Specular, src[1].Specular );
  502.    }
  503.    if (bitmask & FRONT_EMISSION_BIT) {
  504.       struct gl_material *mat = &ctx->Light.Material[0];
  505.       SUB_3V( tmp, src[0].Emission, mat->Emission );
  506.       ACC_3V( ctx->Light.BaseColor[0], tmp );
  507.       COPY_4FV( mat->Emission, src[0].Emission );
  508.    }
  509.    if (bitmask & BACK_EMISSION_BIT) {
  510.       struct gl_material *mat = &ctx->Light.Material[1];
  511.       SUB_3V( tmp, src[1].Emission, mat->Emission );
  512.       ACC_3V( ctx->Light.BaseColor[1], tmp );
  513.       COPY_4FV( mat->Emission, src[1].Emission );
  514.    }
  515.    if (bitmask & FRONT_SHININESS_BIT) {
  516.       GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
  517.       gl_compute_shine_table( ctx, 0, shininess );
  518.       gl_compute_shine_table( ctx, 2, shininess * .5 );
  519.    }
  520.    if (bitmask & BACK_SHININESS_BIT) {
  521.       GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
  522.       gl_compute_shine_table( ctx, 1, shininess );
  523.       gl_compute_shine_table( ctx, 3, shininess * .5 );
  524.    }
  525.    if (bitmask & FRONT_INDEXES_BIT) {
  526.       ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
  527.       ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
  528.       ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
  529.    }
  530.    if (bitmask & BACK_INDEXES_BIT) {
  531.       ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
  532.       ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
  533.       ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
  534.    }
  535.  
  536.    if (0)
  537.    {
  538.       struct gl_material *mat = &ctx->Light.Material[0];
  539.       fprintf(stderr, "update_mat  emission : %f %f %f\n",
  540.           mat->Emission[0],
  541.           mat->Emission[1],
  542.           mat->Emission[2]);
  543.       fprintf(stderr, "update_mat  specular : %f %f %f\n",
  544.           mat->Specular[0],
  545.           mat->Specular[1],
  546.           mat->Specular[2]);
  547.       fprintf(stderr, "update_mat  diffuse : %f %f %f\n",
  548.           mat->Diffuse[0],
  549.           mat->Diffuse[1],
  550.           mat->Diffuse[2]);
  551.       fprintf(stderr, "update_mat  ambient : %f %f %f\n",
  552.           mat->Ambient[0],
  553.           mat->Ambient[1],
  554.           mat->Ambient[2]);
  555.    }
  556. }
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563. void gl_update_color_material( GLcontext *ctx, 
  564.                    const GLubyte rgba[4] )
  565. {
  566.    struct gl_light *light, *list = &ctx->Light.EnabledList;
  567.    GLuint bitmask = ctx->Light.ColorMaterialBitmask;
  568.    GLfloat tmp[4], color[4];
  569.  
  570.    UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
  571.  
  572.    if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  573.       fprintf(stderr, "gl_update_color_material, mask %x\n", bitmask);
  574.  
  575.    
  576.    if (bitmask & FRONT_AMBIENT_BIT) {
  577.       struct gl_material *mat = &ctx->Light.Material[0];
  578.       SUB_3V( tmp, color, mat->Ambient );
  579.       ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
  580.       foreach (light, list) {
  581.      ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
  582.       }
  583.       COPY_4FV( mat->Ambient, color );
  584.    }
  585.  
  586.    if (bitmask & BACK_AMBIENT_BIT) {
  587.       struct gl_material *mat = &ctx->Light.Material[1];
  588.       SUB_3V( tmp, color, mat->Ambient );
  589.       ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
  590.       foreach (light, list) {
  591.      ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
  592.       }
  593.       COPY_4FV( mat->Ambient, color );
  594.    }
  595.  
  596.    if (bitmask & FRONT_DIFFUSE_BIT) {
  597.       struct gl_material *mat = &ctx->Light.Material[0];
  598.       SUB_3V( tmp, color, mat->Diffuse );
  599.       foreach (light, list) {
  600.      ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
  601.       }
  602.       COPY_4FV( mat->Diffuse, color );
  603.       FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
  604.    }
  605.  
  606.    if (bitmask & BACK_DIFFUSE_BIT) {
  607.       struct gl_material *mat = &ctx->Light.Material[1];
  608.       SUB_3V( tmp, color, mat->Diffuse );
  609.       foreach (light, list) {
  610.      ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
  611.       }
  612.       COPY_4FV( mat->Diffuse, color );
  613.       FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
  614.    }
  615.  
  616.    if (bitmask & FRONT_SPECULAR_BIT) {
  617.       struct gl_material *mat = &ctx->Light.Material[0];
  618.       SUB_3V( tmp, color, mat->Specular );
  619.       foreach (light, list) {
  620.      if (light->Flags & LIGHT_SPECULAR) {
  621.         ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
  622.         light->IsMatSpecular[0] = 
  623.            (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
  624.      }
  625.       }
  626.       COPY_4FV( mat->Specular, color );
  627.    }
  628.    if (bitmask & BACK_SPECULAR_BIT) {
  629.       struct gl_material *mat = &ctx->Light.Material[1];
  630.       SUB_3V( tmp, color, mat->Specular );
  631.       foreach (light, list) {
  632.      if (light->Flags & LIGHT_SPECULAR) {
  633.         ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
  634.         light->IsMatSpecular[1] = 
  635.            (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
  636.      }
  637.       }
  638.       COPY_4FV( mat->Specular, color );
  639.    }
  640.    if (bitmask & FRONT_EMISSION_BIT) {
  641.       struct gl_material *mat = &ctx->Light.Material[0];
  642.       SUB_3V( tmp, color, mat->Emission );
  643.       ACC_3V( ctx->Light.BaseColor[0], tmp );
  644.       COPY_4FV( mat->Emission, color );
  645.    }
  646.    if (bitmask & BACK_EMISSION_BIT) {
  647.       struct gl_material *mat = &ctx->Light.Material[1];
  648.       SUB_3V( tmp, color, mat->Emission );
  649.       ACC_3V( ctx->Light.BaseColor[1], tmp );
  650.       COPY_4FV( mat->Emission, color );
  651.    }
  652.  
  653.    if (0)
  654.    {
  655.       struct gl_material *mat = &ctx->Light.Material[0];
  656.       fprintf(stderr, "update_color_mat  emission : %f %f %f\n",
  657.           mat->Emission[0],
  658.           mat->Emission[1],
  659.           mat->Emission[2]);
  660.       fprintf(stderr, "update_color_mat  specular : %f %f %f\n",
  661.           mat->Specular[0],
  662.           mat->Specular[1],
  663.           mat->Specular[2]);
  664.       fprintf(stderr, "update_color_mat  diffuse : %f %f %f\n",
  665.           mat->Diffuse[0],
  666.           mat->Diffuse[1],
  667.           mat->Diffuse[2]);
  668.       fprintf(stderr, "update_color_mat  ambient : %f %f %f\n",
  669.           mat->Ambient[0],
  670.           mat->Ambient[1],
  671.           mat->Ambient[2]);
  672.    }
  673. }
  674.  
  675.  
  676.  
  677.  
  678. void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
  679. {
  680.    GLuint bitmask;
  681.    GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
  682.            FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
  683.            FRONT_DIFFUSE_BIT  | BACK_DIFFUSE_BIT  |
  684.            FRONT_AMBIENT_BIT  | BACK_AMBIENT_BIT);
  685.  
  686.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
  687.  
  688.    if (MESA_VERBOSE&VERBOSE_API) 
  689.       fprintf(stderr, "glColorMaterial %s %s\n", 
  690.           gl_lookup_enum_by_nr(face),
  691.           gl_lookup_enum_by_nr(mode));
  692.  
  693.    bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
  694.  
  695.    if (bitmask != 0) {
  696.       ctx->Light.ColorMaterialBitmask = bitmask;
  697.       ctx->Light.ColorMaterialFace = face;
  698.       ctx->Light.ColorMaterialMode = mode;
  699.    }
  700.  
  701.    if (ctx->Light.ColorMaterialEnabled)
  702.       gl_update_color_material( ctx, ctx->Current.ByteColor );
  703. }
  704.  
  705.  
  706.  
  707. /* KW:  This is now called directly (ie by name) from the glMaterial* 
  708.  *      API functions.
  709.  */
  710. void gl_Materialfv( GLcontext *ctx,
  711.                     GLenum face, GLenum pname, const GLfloat *params )
  712. {
  713.    struct immediate *IM;
  714.    struct gl_material *mat;
  715.    GLuint bitmask;
  716.    GLuint count;
  717.  
  718.    bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
  719.    if (bitmask == 0)
  720.       return;
  721.  
  722.    IM = ctx->input;
  723.    count = IM->Count;
  724.  
  725.    if (!IM->Material) {
  726.       IM->Material = 
  727.      (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) * 
  728.                          VB_SIZE * 2 );
  729.       IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
  730.    }
  731.  
  732.  
  733.    if (!(IM->Flag[count] & VERT_MATERIAL)) {
  734.       IM->Flag[count] |= VERT_MATERIAL;
  735.       IM->MaterialMask[count] = 0;      
  736.    }
  737.  
  738.    IM->MaterialMask[count] |= bitmask;
  739.    mat = IM->Material[count];
  740.  
  741.    if (bitmask & FRONT_AMBIENT_BIT) {
  742.       COPY_4FV( mat[0].Ambient, params );
  743.    }
  744.    if (bitmask & BACK_AMBIENT_BIT) {
  745.       COPY_4FV( mat[1].Ambient, params );
  746.    }
  747.    if (bitmask & FRONT_DIFFUSE_BIT) {
  748.       COPY_4FV( mat[0].Diffuse, params );
  749.    }
  750.    if (bitmask & BACK_DIFFUSE_BIT) {
  751.       COPY_4FV( mat[1].Diffuse, params );
  752.    }
  753.    if (bitmask & FRONT_SPECULAR_BIT) {
  754.       COPY_4FV( mat[0].Specular, params );
  755.    }
  756.    if (bitmask & BACK_SPECULAR_BIT) {
  757.       COPY_4FV( mat[1].Specular, params );
  758.    }
  759.    if (bitmask & FRONT_EMISSION_BIT) {
  760.       COPY_4FV( mat[0].Emission, params );
  761.    }
  762.    if (bitmask & BACK_EMISSION_BIT) {
  763.       COPY_4FV( mat[1].Emission, params );
  764.    }
  765.    if (bitmask & FRONT_SHININESS_BIT) {
  766.       GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
  767.       mat[0].Shininess = shininess;
  768.    }
  769.    if (bitmask & BACK_SHININESS_BIT) {
  770.       GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
  771.       mat[1].Shininess = shininess;
  772.    }
  773.    if (bitmask & FRONT_INDEXES_BIT) {
  774.       mat[0].AmbientIndex = params[0];
  775.       mat[0].DiffuseIndex = params[1];
  776.       mat[0].SpecularIndex = params[2];
  777.    }
  778.    if (bitmask & BACK_INDEXES_BIT) {
  779.       mat[1].AmbientIndex = params[0];
  780.       mat[1].DiffuseIndex = params[1];
  781.       mat[1].SpecularIndex = params[2];
  782.    }
  783. }
  784.  
  785.  
  786.  
  787.  
  788. void gl_GetMaterialfv( GLcontext *ctx,
  789.                        GLenum face, GLenum pname, GLfloat *params )
  790. {
  791.    GLuint f;
  792.  
  793.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
  794.  
  795.    if (face==GL_FRONT) {
  796.       f = 0;
  797.    }
  798.    else if (face==GL_BACK) {
  799.       f = 1;
  800.    }
  801.    else {
  802.       gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
  803.       return;
  804.    }
  805.    switch (pname) {
  806.       case GL_AMBIENT:
  807.          COPY_4FV( params, ctx->Light.Material[f].Ambient );
  808.          break;
  809.       case GL_DIFFUSE:
  810.          COPY_4FV( params, ctx->Light.Material[f].Diffuse );
  811.      break;
  812.       case GL_SPECULAR:
  813.          COPY_4FV( params, ctx->Light.Material[f].Specular );
  814.      break;
  815.       case GL_EMISSION:
  816.      COPY_4FV( params, ctx->Light.Material[f].Emission );
  817.      break;
  818.       case GL_SHININESS:
  819.      *params = ctx->Light.Material[f].Shininess;
  820.      break;
  821.       case GL_COLOR_INDEXES:
  822.      params[0] = ctx->Light.Material[f].AmbientIndex;
  823.      params[1] = ctx->Light.Material[f].DiffuseIndex;
  824.      params[2] = ctx->Light.Material[f].SpecularIndex;
  825.      break;
  826.       default:
  827.          gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  828.    }
  829. }
  830.  
  831.  
  832.  
  833. void gl_GetMaterialiv( GLcontext *ctx,
  834.                        GLenum face, GLenum pname, GLint *params )
  835. {
  836.    GLuint f;
  837.  
  838.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
  839.  
  840.    if (face==GL_FRONT) {
  841.       f = 0;
  842.    }
  843.    else if (face==GL_BACK) {
  844.       f = 1;
  845.    }
  846.    else {
  847.       gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
  848.       return;
  849.    }
  850.    switch (pname) {
  851.       case GL_AMBIENT:
  852.          params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
  853.          params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
  854.          params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
  855.          params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
  856.          break;
  857.       case GL_DIFFUSE:
  858.          params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
  859.          params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
  860.          params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
  861.          params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
  862.      break;
  863.       case GL_SPECULAR:
  864.          params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
  865.          params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
  866.          params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
  867.          params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
  868.      break;
  869.       case GL_EMISSION:
  870.          params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
  871.          params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
  872.          params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
  873.          params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
  874.      break;
  875.       case GL_SHININESS:
  876.          *params = ROUNDF( ctx->Light.Material[f].Shininess );
  877.      break;
  878.       case GL_COLOR_INDEXES:
  879.      params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
  880.      params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
  881.      params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
  882.      break;
  883.       default:
  884.          gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  885.    }
  886. }
  887.  
  888.  
  889.  
  890.  
  891. /**********************************************************************/
  892. /*****                  Lighting computation                      *****/
  893. /**********************************************************************/
  894.  
  895.  
  896. /*
  897.  * Notes:
  898.  *   When two-sided lighting is enabled we compute the color (or index)
  899.  *   for both the front and back side of the primitive.  Then, when the
  900.  *   orientation of the facet is later learned, we can determine which
  901.  *   color (or index) to use for rendering.
  902.  *
  903.  *   KW: We now know orientation in advance and only shade for 
  904.  *       the side or sides which are actually required.
  905.  *
  906.  * Variables:
  907.  *   n = normal vector
  908.  *   V = vertex position
  909.  *   P = light source position
  910.  *   Pe = (0,0,0,1)
  911.  *
  912.  * Precomputed:
  913.  *   IF P[3]==0 THEN
  914.  *       // light at infinity
  915.  *       IF local_viewer THEN
  916.  *           VP_inf_norm = unit vector from V to P      // Precompute
  917.  *       ELSE 
  918.  *           // eye at infinity
  919.  *           h_inf_norm = Normalize( VP + <0,0,1> )     // Precompute
  920.  *       ENDIF
  921.  *   ENDIF
  922.  *
  923.  * Functions:
  924.  *   Normalize( v ) = normalized vector v
  925.  *   Magnitude( v ) = length of vector v
  926.  */
  927.  
  928.  
  929.  
  930. /*
  931.  * Whenever the spotlight exponent for a light changes we must call
  932.  * this function to recompute the exponent lookup table.
  933.  */
  934. void gl_compute_spot_exp_table( struct gl_light *l )
  935. {
  936.    int i;
  937.    double exponent = l->SpotExponent;
  938.    double tmp = 0;
  939.    int clamp = 0;
  940.  
  941.    l->SpotExpTable[0][0] = 0.0;
  942.  
  943.    for (i=EXP_TABLE_SIZE-1;i>0;i--) {
  944.       if (clamp == 0) {
  945.          tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
  946.          if (tmp < FLT_MIN*100.0) {
  947.             tmp = 0.0;
  948.             clamp = 1;
  949.          }
  950.       }
  951.       l->SpotExpTable[i][0] = tmp;
  952.    }
  953.    for (i=0;i<EXP_TABLE_SIZE-1;i++) {
  954.       l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
  955.    }
  956.    l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
  957. }
  958.  
  959.  
  960.  
  961.  
  962. /* Calculate a new shine table.  Doing this here saves a branch in
  963.  * lighting, and the cost of doing it early may be partially offset
  964.  * by keeping a MRU cache of shine tables for various shine values.
  965.  */
  966. static void compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
  967. {
  968.    int i;
  969.    GLfloat *m = tab->tab;
  970.  
  971.    m[0] = 0;
  972.    if (shininess == 0) {
  973.       for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
  974.      m[i] = 1;
  975.    } else {
  976.       for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) {
  977.      double t = pow( i/(GLfloat)SHINE_TABLE_SIZE, shininess );
  978.      m[i] = 0;
  979.      if (t > 1e-20) m[i] = t;
  980.       }      
  981.    }
  982.  
  983.    tab->shininess = shininess;
  984. }
  985.  
  986. #define DISTSQR(a,b) ((a-b)*(a-b))
  987.  
  988. void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
  989. {
  990.    struct gl_shine_tab *list = ctx->ShineTabList;
  991.    struct gl_shine_tab *s;
  992.  
  993.    foreach(s, list) 
  994.       if ( DISTSQR(s->shininess, shininess) < 1e-4 ) 
  995.      break;
  996.  
  997.    if (s == list) 
  998.    {
  999.       foreach(s, list) 
  1000.      if (s->refcount == 0) break;
  1001.  
  1002.       compute_shine_table( s, shininess );
  1003.    }
  1004.  
  1005.    ctx->ShineTable[i]->refcount--;
  1006.    ctx->ShineTable[i] = s;
  1007.    move_to_tail( list, s );
  1008.    s->refcount++;
  1009. }
  1010.  
  1011.  
  1012.  
  1013.  
  1014. void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
  1015. {
  1016.    GLuint i;
  1017.  
  1018.    if (ctx->ShineTable[0]->shininess != l->Material[0].Shininess) {
  1019.       gl_compute_shine_table( ctx, 0, l->Material[0].Shininess );
  1020.       gl_compute_shine_table( ctx, 2, l->Material[0].Shininess * .5 );
  1021.    }
  1022.  
  1023.    if (ctx->ShineTable[1]->shininess != l->Material[1].Shininess) {
  1024.       gl_compute_shine_table( ctx, 1, l->Material[1].Shininess );
  1025.       gl_compute_shine_table( ctx, 3, l->Material[1].Shininess * .5 );
  1026.    }
  1027.  
  1028.    make_empty_list( &l->EnabledList );
  1029.    for (i = 0 ; i < MAX_LIGHTS ; i++) {
  1030.       if (l->Light[i].Enabled) 
  1031.      insert_at_tail( &l->EnabledList, &l->Light[i] );
  1032.    }
  1033. }
  1034.  
  1035.  
  1036.  
  1037. /*
  1038.  * Examine current lighting parameters to determine if the optimized lighting
  1039.  * function can be used.
  1040.  * Also, precompute some lighting values such as the products of light
  1041.  * source and material ambient, diffuse and specular coefficients.
  1042.  */
  1043. void gl_update_lighting( GLcontext *ctx )
  1044. {
  1045.    struct gl_light *light;
  1046.  
  1047.    ctx->Light.Flags = 0;
  1048.  
  1049.    foreach(light, &ctx->Light.EnabledList) {
  1050.  
  1051.       light->Flags = 0;
  1052.  
  1053.       if (light->EyePosition[3] != 0.0F) 
  1054.      light->Flags |= LIGHT_POSITIONAL;
  1055.       
  1056.       if (LEN_SQUARED_3FV(light->Specular) > 1e-16) 
  1057.      light->Flags |= LIGHT_SPECULAR;
  1058.       
  1059.       if (light->SpotCutoff != 180.0F)
  1060.      light->Flags |= LIGHT_SPOT;
  1061.  
  1062.       ctx->Light.Flags |= light->Flags;
  1063.    }
  1064.  
  1065.    ctx->Light.NeedVertices = 
  1066.       ((ctx->Light.Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
  1067.        (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
  1068.        (ctx->Light.Model.LocalViewer && (ctx->Light.Flags & LIGHT_SPECULAR)));
  1069.  
  1070.  
  1071.    /* Precompute some shading values.
  1072.     */
  1073.    if (ctx->Visual->RGBAflag) 
  1074.    {
  1075.       GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
  1076.       GLuint side;
  1077.       for (side=0; side < sides; side++) {
  1078.      struct gl_material *mat = &ctx->Light.Material[side];
  1079.      
  1080.      COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
  1081.      ACC_SCALE_3V(ctx->Light.BaseColor[side], 
  1082.               ctx->Light.Model.Ambient,
  1083.               mat->Ambient);
  1084.  
  1085.      FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[side],
  1086.                     ctx->Light.Material[side].Diffuse[3] );
  1087.       }
  1088.       
  1089.       foreach (light, &ctx->Light.EnabledList) {     
  1090.      for (side=0; side< sides; side++) {
  1091.         struct gl_material *mat = &ctx->Light.Material[side];
  1092.         SCALE_3V( light->MatDiffuse[side],  light->Diffuse, mat->Diffuse );
  1093.         SCALE_3V( light->MatAmbient[side],  light->Ambient, mat->Ambient );
  1094.         ACC_3V( ctx->Light.BaseColor[side], light->MatAmbient[side] ); 
  1095.         if (light->Flags & LIGHT_SPECULAR)
  1096.         {
  1097.            SCALE_3V( light->MatSpecular[side], light->Specular,
  1098.              mat->Specular);
  1099.            light->IsMatSpecular[side] = 
  1100.           (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
  1101.         } 
  1102.         else 
  1103.            light->IsMatSpecular[side] = 0;
  1104.      }
  1105.       }
  1106.    } 
  1107.    else
  1108.    {
  1109.       static GLfloat ci[3] = { .30, .59, .11 };
  1110.  
  1111.       foreach(light, &ctx->Light.EnabledList) {
  1112.      light->dli = DOT3(ci, light->Diffuse);
  1113.      light->sli = DOT3(ci, light->Specular);
  1114.       }
  1115.    }
  1116. }
  1117.  
  1118. /* Need to seriously restrict the circumstances under which these
  1119.  * calc's are performed.
  1120.  */
  1121. void gl_compute_light_positions( GLcontext *ctx )
  1122. {
  1123.    struct gl_light *light;
  1124.  
  1125.    if (ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer) {
  1126.       GLfloat eye_z[3] = { 0, 0, 1 };
  1127.       if (!ctx->NeedEyeCoords) {
  1128.      TRANSFORM_NORMAL( ctx->EyeZDir, eye_z, ctx->ModelView.m );
  1129.       } else {
  1130.      COPY_3V( ctx->EyeZDir, eye_z );
  1131.       }
  1132.    }
  1133.  
  1134.    foreach (light, &ctx->Light.EnabledList) {
  1135.  
  1136.       if (!ctx->NeedEyeCoords) {
  1137.      TRANSFORM_POINT( light->Position, ctx->ModelView.inv, 
  1138.               light->EyePosition );
  1139.       } else {
  1140.      COPY_4FV( light->Position, light->EyePosition );
  1141.       }
  1142.  
  1143.       if (!(light->Flags & LIGHT_POSITIONAL))
  1144.       {
  1145.      /* VP (VP) = Normalize( Position ) */
  1146.      COPY_3V( light->VP_inf_norm, light->Position );
  1147.      NORMALIZE_3FV( light->VP_inf_norm );
  1148.  
  1149.      if (!ctx->Light.Model.LocalViewer)
  1150.      {
  1151.         /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
  1152.         ADD_3V( light->h_inf_norm, light->VP_inf_norm, ctx->EyeZDir);
  1153.         NORMALIZE_3FV( light->h_inf_norm );
  1154.      }
  1155.  
  1156.      light->VP_inf_spot_attenuation = 1.0;
  1157.       }
  1158.       
  1159.       if (light->Flags & LIGHT_SPOT) 
  1160.       {
  1161.      if (ctx->NeedEyeNormals) {
  1162.         COPY_3V( light->NormDirection, light->EyeDirection );
  1163.      } else {
  1164.         TRANSFORM_NORMAL( light->NormDirection, 
  1165.                   light->EyeDirection,
  1166.                   ctx->ModelView.m);
  1167.      }
  1168.  
  1169.      NORMALIZE_3FV( light->NormDirection );
  1170.  
  1171.  
  1172.      /* Unlikely occurrance?
  1173.       */
  1174.      if (!(light->Flags & LIGHT_POSITIONAL)) {
  1175.         GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm, 
  1176.                     light->NormDirection);
  1177.  
  1178.         if (PV_dot_dir > light->CosCutoff) {
  1179.            double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  1180.            int k = (int) x;
  1181.            light->VP_inf_spot_attenuation = 
  1182.           (light->SpotExpTable[k][0] + 
  1183.            (x-k)*light->SpotExpTable[k][1]);
  1184.         }
  1185.         else 
  1186.            light->VP_inf_spot_attenuation = 0;
  1187.      }
  1188.       }
  1189.    }
  1190. }
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196. void gl_update_normal_transform( GLcontext *ctx )
  1197. {
  1198.    GLuint new_flag = 0;
  1199.    normal_func *last = ctx->NormalTransform;
  1200.    
  1201.    ctx->vb_rescale_factor = 1.0;
  1202.  
  1203.    if (ctx->NeedEyeCoords) {
  1204.       if (ctx->NeedNormals) {
  1205.      GLuint transform = NORM_TRANSFORM_NO_ROT;
  1206.  
  1207.      if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
  1208.                      MAT_FLAG_ROTATION |
  1209.                      MAT_FLAG_GENERAL_3D |
  1210.                      MAT_FLAG_PERSPECTIVE)) 
  1211.         transform = NORM_TRANSFORM;
  1212.  
  1213.         
  1214.      new_flag = ctx->NewState & NEW_MODELVIEW;
  1215.      ctx->vb_rescale_factor = ctx->rescale_factor;
  1216.            
  1217.      if (ctx->Transform.Normalize) 
  1218.      {
  1219.         ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
  1220.      } 
  1221.      else if (ctx->Transform.RescaleNormals &&
  1222.           ctx->rescale_factor != 1.0)
  1223.      {
  1224.         ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
  1225.      }
  1226.      else 
  1227.      {
  1228.         ctx->NormalTransform = gl_normal_tab[transform];
  1229.      }
  1230.       } else {
  1231.      ctx->NormalTransform = 0;
  1232.       }
  1233.    }
  1234.    else {
  1235.       if (ctx->NeedNormals) {
  1236.      ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
  1237.  
  1238.      if (ctx->Transform.Normalize) 
  1239.      {
  1240.         ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
  1241.      }
  1242.      else if (!ctx->Transform.RescaleNormals &&
  1243.           ctx->rescale_factor != 1.0)
  1244.      {
  1245.         ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
  1246.      }
  1247.      else
  1248.      {
  1249.         ctx->NormalTransform = 0;
  1250.      }
  1251.       } else {
  1252.      ctx->NormalTransform = 0;
  1253.       }
  1254.    }
  1255.  
  1256.    if (last != ctx->NormalTransform || new_flag)
  1257.       ctx->NewState |= NEW_NORMAL_TRANSFORM;
  1258. }
  1259.  
  1260.