Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  5.  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23.  * OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26.  
  27. #include "glheader.h"
  28. #include "imports.h"
  29. #include "context.h"
  30. #include "enums.h"
  31. #include "light.h"
  32. #include "macros.h"
  33. #include "simple_list.h"
  34. #include "mtypes.h"
  35. #include "math/m_matrix.h"
  36.  
  37.  
  38. void GLAPIENTRY
  39. _mesa_ShadeModel( GLenum mode )
  40. {
  41.    GET_CURRENT_CONTEXT(ctx);
  42.  
  43.    if (MESA_VERBOSE & VERBOSE_API)
  44.       _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode));
  45.  
  46.    if (mode != GL_FLAT && mode != GL_SMOOTH) {
  47.       _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel");
  48.       return;
  49.    }
  50.  
  51.    if (ctx->Light.ShadeModel == mode)
  52.       return;
  53.  
  54.    FLUSH_VERTICES(ctx, _NEW_LIGHT);
  55.    ctx->Light.ShadeModel = mode;
  56.  
  57.    if (ctx->Driver.ShadeModel)
  58.       ctx->Driver.ShadeModel( ctx, mode );
  59. }
  60.  
  61.  
  62. /**
  63.  * Set the provoking vertex (the vertex which specifies the prim's
  64.  * color when flat shading) to either the first or last vertex of the
  65.  * triangle or line.
  66.  */
  67. void GLAPIENTRY
  68. _mesa_ProvokingVertex(GLenum mode)
  69. {
  70.    GET_CURRENT_CONTEXT(ctx);
  71.  
  72.    if (MESA_VERBOSE&VERBOSE_API)
  73.       _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode);
  74.  
  75.    switch (mode) {
  76.    case GL_FIRST_VERTEX_CONVENTION_EXT:
  77.    case GL_LAST_VERTEX_CONVENTION_EXT:
  78.       break;
  79.    default:
  80.       _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode);
  81.       return;
  82.    }
  83.  
  84.    if (ctx->Light.ProvokingVertex == mode)
  85.       return;
  86.  
  87.    FLUSH_VERTICES(ctx, _NEW_LIGHT);
  88.    ctx->Light.ProvokingVertex = mode;
  89. }
  90.  
  91.  
  92. /**
  93.  * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
  94.  * per-light state.
  95.  * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
  96.  * will have already been transformed by the modelview matrix!
  97.  * Also, all error checking should have already been done.
  98.  */
  99. void
  100. _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
  101. {
  102.    struct gl_light *light;
  103.  
  104.    ASSERT(lnum < MAX_LIGHTS);
  105.    light = &ctx->Light.Light[lnum];
  106.  
  107.    switch (pname) {
  108.    case GL_AMBIENT:
  109.       if (TEST_EQ_4V(light->Ambient, params))
  110.          return;
  111.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  112.       COPY_4V( light->Ambient, params );
  113.       break;
  114.    case GL_DIFFUSE:
  115.       if (TEST_EQ_4V(light->Diffuse, params))
  116.          return;
  117.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  118.       COPY_4V( light->Diffuse, params );
  119.       break;
  120.    case GL_SPECULAR:
  121.       if (TEST_EQ_4V(light->Specular, params))
  122.          return;
  123.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  124.       COPY_4V( light->Specular, params );
  125.       break;
  126.    case GL_POSITION:
  127.       /* NOTE: position has already been transformed by ModelView! */
  128.       if (TEST_EQ_4V(light->EyePosition, params))
  129.          return;
  130.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  131.       COPY_4V(light->EyePosition, params);
  132.       if (light->EyePosition[3] != 0.0F)
  133.          light->_Flags |= LIGHT_POSITIONAL;
  134.       else
  135.          light->_Flags &= ~LIGHT_POSITIONAL;
  136.       break;
  137.    case GL_SPOT_DIRECTION:
  138.       /* NOTE: Direction already transformed by inverse ModelView! */
  139.       if (TEST_EQ_3V(light->SpotDirection, params))
  140.          return;
  141.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  142.       COPY_3V(light->SpotDirection, params);
  143.       break;
  144.    case GL_SPOT_EXPONENT:
  145.       ASSERT(params[0] >= 0.0);
  146.       ASSERT(params[0] <= ctx->Const.MaxSpotExponent);
  147.       if (light->SpotExponent == params[0])
  148.          return;
  149.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  150.       light->SpotExponent = params[0];
  151.       break;
  152.    case GL_SPOT_CUTOFF:
  153.       ASSERT(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0));
  154.       if (light->SpotCutoff == params[0])
  155.          return;
  156.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  157.       light->SpotCutoff = params[0];
  158.       light->_CosCutoff = (GLfloat) (cos(light->SpotCutoff * DEG2RAD));
  159.       if (light->_CosCutoff < 0)
  160.          light->_CosCutoff = 0;
  161.       if (light->SpotCutoff != 180.0F)
  162.          light->_Flags |= LIGHT_SPOT;
  163.       else
  164.          light->_Flags &= ~LIGHT_SPOT;
  165.       break;
  166.    case GL_CONSTANT_ATTENUATION:
  167.       ASSERT(params[0] >= 0.0);
  168.       if (light->ConstantAttenuation == params[0])
  169.          return;
  170.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  171.       light->ConstantAttenuation = params[0];
  172.       break;
  173.    case GL_LINEAR_ATTENUATION:
  174.       ASSERT(params[0] >= 0.0);
  175.       if (light->LinearAttenuation == params[0])
  176.          return;
  177.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  178.       light->LinearAttenuation = params[0];
  179.       break;
  180.    case GL_QUADRATIC_ATTENUATION:
  181.       ASSERT(params[0] >= 0.0);
  182.       if (light->QuadraticAttenuation == params[0])
  183.          return;
  184.       FLUSH_VERTICES(ctx, _NEW_LIGHT);
  185.       light->QuadraticAttenuation = params[0];
  186.       break;
  187.    default:
  188.       _mesa_problem(ctx, "Unexpected pname in _mesa_light()");
  189.       return;
  190.    }
  191.  
  192.    if (ctx->Driver.Lightfv)
  193.       ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params );
  194. }
  195.  
  196.  
  197. void GLAPIENTRY
  198. _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
  199. {
  200.    GLfloat fparam[4];
  201.    fparam[0] = param;
  202.    fparam[1] = fparam[2] = fparam[3] = 0.0F;
  203.    _mesa_Lightfv( light, pname, fparam );
  204. }
  205.  
  206.  
  207. void GLAPIENTRY
  208. _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
  209. {
  210.    GET_CURRENT_CONTEXT(ctx);
  211.    GLint i = (GLint) (light - GL_LIGHT0);
  212.    GLfloat temp[4];
  213.  
  214.    if (i < 0 || i >= (GLint) ctx->Const.MaxLights) {
  215.       _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light );
  216.       return;
  217.    }
  218.  
  219.    /* do particular error checks, transformations */
  220.    switch (pname) {
  221.    case GL_AMBIENT:
  222.    case GL_DIFFUSE:
  223.    case GL_SPECULAR:
  224.       /* nothing */
  225.       break;
  226.    case GL_POSITION:
  227.       /* transform position by ModelView matrix */
  228.       TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params);
  229.       params = temp;
  230.       break;
  231.    case GL_SPOT_DIRECTION:
  232.       /* transform direction by inverse modelview */
  233.       if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
  234.          _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
  235.       }
  236.       TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m);
  237.       params = temp;
  238.       break;
  239.    case GL_SPOT_EXPONENT:
  240.       if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) {
  241.          _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
  242.          return;
  243.       }
  244.       break;
  245.    case GL_SPOT_CUTOFF:
  246.       if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) {
  247.          _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
  248.          return;
  249.       }
  250.       break;
  251.    case GL_CONSTANT_ATTENUATION:
  252.       if (params[0] < 0.0) {
  253.          _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
  254.          return;
  255.       }
  256.       break;
  257.    case GL_LINEAR_ATTENUATION:
  258.       if (params[0] < 0.0) {
  259.          _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
  260.          return;
  261.       }
  262.       break;
  263.    case GL_QUADRATIC_ATTENUATION:
  264.       if (params[0] < 0.0) {
  265.          _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
  266.          return;
  267.       }
  268.       break;
  269.    default:
  270.       _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname);
  271.       return;
  272.    }
  273.  
  274.    _mesa_light(ctx, i, pname, params);
  275. }
  276.  
  277.  
  278. void GLAPIENTRY
  279. _mesa_Lighti( GLenum light, GLenum pname, GLint param )
  280. {
  281.    GLint iparam[4];
  282.    iparam[0] = param;
  283.    iparam[1] = iparam[2] = iparam[3] = 0;
  284.    _mesa_Lightiv( light, pname, iparam );
  285. }
  286.  
  287.  
  288. void GLAPIENTRY
  289. _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
  290. {
  291.    GLfloat fparam[4];
  292.  
  293.    switch (pname) {
  294.       case GL_AMBIENT:
  295.       case GL_DIFFUSE:
  296.       case GL_SPECULAR:
  297.          fparam[0] = INT_TO_FLOAT( params[0] );
  298.          fparam[1] = INT_TO_FLOAT( params[1] );
  299.          fparam[2] = INT_TO_FLOAT( params[2] );
  300.          fparam[3] = INT_TO_FLOAT( params[3] );
  301.          break;
  302.       case GL_POSITION:
  303.          fparam[0] = (GLfloat) params[0];
  304.          fparam[1] = (GLfloat) params[1];
  305.          fparam[2] = (GLfloat) params[2];
  306.          fparam[3] = (GLfloat) params[3];
  307.          break;
  308.       case GL_SPOT_DIRECTION:
  309.          fparam[0] = (GLfloat) params[0];
  310.          fparam[1] = (GLfloat) params[1];
  311.          fparam[2] = (GLfloat) params[2];
  312.          break;
  313.       case GL_SPOT_EXPONENT:
  314.       case GL_SPOT_CUTOFF:
  315.       case GL_CONSTANT_ATTENUATION:
  316.       case GL_LINEAR_ATTENUATION:
  317.       case GL_QUADRATIC_ATTENUATION:
  318.          fparam[0] = (GLfloat) params[0];
  319.          break;
  320.       default:
  321.          /* error will be caught later in gl_Lightfv */
  322.          ;
  323.    }
  324.  
  325.    _mesa_Lightfv( light, pname, fparam );
  326. }
  327.  
  328.  
  329.  
  330. void GLAPIENTRY
  331. _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
  332. {
  333.    GET_CURRENT_CONTEXT(ctx);
  334.    GLint l = (GLint) (light - GL_LIGHT0);
  335.  
  336.    if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
  337.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  338.       return;
  339.    }
  340.  
  341.    switch (pname) {
  342.       case GL_AMBIENT:
  343.          COPY_4V( params, ctx->Light.Light[l].Ambient );
  344.          break;
  345.       case GL_DIFFUSE:
  346.          COPY_4V( params, ctx->Light.Light[l].Diffuse );
  347.          break;
  348.       case GL_SPECULAR:
  349.          COPY_4V( params, ctx->Light.Light[l].Specular );
  350.          break;
  351.       case GL_POSITION:
  352.          COPY_4V( params, ctx->Light.Light[l].EyePosition );
  353.          break;
  354.       case GL_SPOT_DIRECTION:
  355.          COPY_3V( params, ctx->Light.Light[l].SpotDirection );
  356.          break;
  357.       case GL_SPOT_EXPONENT:
  358.          params[0] = ctx->Light.Light[l].SpotExponent;
  359.          break;
  360.       case GL_SPOT_CUTOFF:
  361.          params[0] = ctx->Light.Light[l].SpotCutoff;
  362.          break;
  363.       case GL_CONSTANT_ATTENUATION:
  364.          params[0] = ctx->Light.Light[l].ConstantAttenuation;
  365.          break;
  366.       case GL_LINEAR_ATTENUATION:
  367.          params[0] = ctx->Light.Light[l].LinearAttenuation;
  368.          break;
  369.       case GL_QUADRATIC_ATTENUATION:
  370.          params[0] = ctx->Light.Light[l].QuadraticAttenuation;
  371.          break;
  372.       default:
  373.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  374.          break;
  375.    }
  376. }
  377.  
  378.  
  379. void GLAPIENTRY
  380. _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
  381. {
  382.    GET_CURRENT_CONTEXT(ctx);
  383.    GLint l = (GLint) (light - GL_LIGHT0);
  384.  
  385.    if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
  386.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  387.       return;
  388.    }
  389.  
  390.    switch (pname) {
  391.       case GL_AMBIENT:
  392.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
  393.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
  394.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
  395.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
  396.          break;
  397.       case GL_DIFFUSE:
  398.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
  399.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
  400.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
  401.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
  402.          break;
  403.       case GL_SPECULAR:
  404.          params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
  405.          params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
  406.          params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
  407.          params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
  408.          break;
  409.       case GL_POSITION:
  410.          params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
  411.          params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
  412.          params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
  413.          params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
  414.          break;
  415.       case GL_SPOT_DIRECTION:
  416.          params[0] = (GLint) ctx->Light.Light[l].SpotDirection[0];
  417.          params[1] = (GLint) ctx->Light.Light[l].SpotDirection[1];
  418.          params[2] = (GLint) ctx->Light.Light[l].SpotDirection[2];
  419.          break;
  420.       case GL_SPOT_EXPONENT:
  421.          params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
  422.          break;
  423.       case GL_SPOT_CUTOFF:
  424.          params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
  425.          break;
  426.       case GL_CONSTANT_ATTENUATION:
  427.          params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
  428.          break;
  429.       case GL_LINEAR_ATTENUATION:
  430.          params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
  431.          break;
  432.       case GL_QUADRATIC_ATTENUATION:
  433.          params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
  434.          break;
  435.       default:
  436.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  437.          break;
  438.    }
  439. }
  440.  
  441.  
  442.  
  443. /**********************************************************************/
  444. /***                        Light Model                             ***/
  445. /**********************************************************************/
  446.  
  447.  
  448. void GLAPIENTRY
  449. _mesa_LightModelfv( GLenum pname, const GLfloat *params )
  450. {
  451.    GLenum newenum;
  452.    GLboolean newbool;
  453.    GET_CURRENT_CONTEXT(ctx);
  454.  
  455.    switch (pname) {
  456.       case GL_LIGHT_MODEL_AMBIENT:
  457.          if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
  458.             return;
  459.          FLUSH_VERTICES(ctx, _NEW_LIGHT);
  460.          COPY_4V( ctx->Light.Model.Ambient, params );
  461.          break;
  462.       case GL_LIGHT_MODEL_LOCAL_VIEWER:
  463.          if (ctx->API != API_OPENGL_COMPAT)
  464.             goto invalid_pname;
  465.          newbool = (params[0]!=0.0);
  466.          if (ctx->Light.Model.LocalViewer == newbool)
  467.             return;
  468.          FLUSH_VERTICES(ctx, _NEW_LIGHT);
  469.          ctx->Light.Model.LocalViewer = newbool;
  470.          break;
  471.       case GL_LIGHT_MODEL_TWO_SIDE:
  472.          newbool = (params[0]!=0.0);
  473.          if (ctx->Light.Model.TwoSide == newbool)
  474.             return;
  475.          FLUSH_VERTICES(ctx, _NEW_LIGHT);
  476.          ctx->Light.Model.TwoSide = newbool;
  477.          break;
  478.       case GL_LIGHT_MODEL_COLOR_CONTROL:
  479.          if (ctx->API != API_OPENGL_COMPAT)
  480.             goto invalid_pname;
  481.          if (params[0] == (GLfloat) GL_SINGLE_COLOR)
  482.             newenum = GL_SINGLE_COLOR;
  483.          else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
  484.             newenum = GL_SEPARATE_SPECULAR_COLOR;
  485.          else {
  486.             _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)",
  487.                          (GLint) params[0] );
  488.             return;
  489.          }
  490.          if (ctx->Light.Model.ColorControl == newenum)
  491.             return;
  492.          FLUSH_VERTICES(ctx, _NEW_LIGHT);
  493.          ctx->Light.Model.ColorControl = newenum;
  494.          break;
  495.       default:
  496.          goto invalid_pname;
  497.    }
  498.  
  499.    if (ctx->Driver.LightModelfv)
  500.       ctx->Driver.LightModelfv( ctx, pname, params );
  501.  
  502.    return;
  503.  
  504. invalid_pname:
  505.    _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );
  506.    return;
  507. }
  508.  
  509.  
  510. void GLAPIENTRY
  511. _mesa_LightModeliv( GLenum pname, const GLint *params )
  512. {
  513.    GLfloat fparam[4];
  514.  
  515.    switch (pname) {
  516.       case GL_LIGHT_MODEL_AMBIENT:
  517.          fparam[0] = INT_TO_FLOAT( params[0] );
  518.          fparam[1] = INT_TO_FLOAT( params[1] );
  519.          fparam[2] = INT_TO_FLOAT( params[2] );
  520.          fparam[3] = INT_TO_FLOAT( params[3] );
  521.          break;
  522.       case GL_LIGHT_MODEL_LOCAL_VIEWER:
  523.       case GL_LIGHT_MODEL_TWO_SIDE:
  524.       case GL_LIGHT_MODEL_COLOR_CONTROL:
  525.          fparam[0] = (GLfloat) params[0];
  526.          break;
  527.       default:
  528.          /* Error will be caught later in gl_LightModelfv */
  529.          ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
  530.    }
  531.    _mesa_LightModelfv( pname, fparam );
  532. }
  533.  
  534.  
  535. void GLAPIENTRY
  536. _mesa_LightModeli( GLenum pname, GLint param )
  537. {
  538.    GLint iparam[4];
  539.    iparam[0] = param;
  540.    iparam[1] = iparam[2] = iparam[3] = 0;
  541.    _mesa_LightModeliv( pname, iparam );
  542. }
  543.  
  544.  
  545. void GLAPIENTRY
  546. _mesa_LightModelf( GLenum pname, GLfloat param )
  547. {
  548.    GLfloat fparam[4];
  549.    fparam[0] = param;
  550.    fparam[1] = fparam[2] = fparam[3] = 0.0F;
  551.    _mesa_LightModelfv( pname, fparam );
  552. }
  553.  
  554.  
  555.  
  556. /********** MATERIAL **********/
  557.  
  558.  
  559. /*
  560.  * Given a face and pname value (ala glColorMaterial), compute a bitmask
  561.  * of the targeted material values.
  562.  */
  563. GLuint
  564. _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname,
  565.                         GLuint legal, const char *where )
  566. {
  567.    GLuint bitmask = 0;
  568.  
  569.    /* Make a bitmask indicating what material attribute(s) we're updating */
  570.    switch (pname) {
  571.       case GL_EMISSION:
  572.          bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;
  573.          break;
  574.       case GL_AMBIENT:
  575.          bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
  576.          break;
  577.       case GL_DIFFUSE:
  578.          bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
  579.          break;
  580.       case GL_SPECULAR:
  581.          bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;
  582.          break;
  583.       case GL_SHININESS:
  584.          bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;
  585.          break;
  586.       case GL_AMBIENT_AND_DIFFUSE:
  587.          bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
  588.          bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
  589.          break;
  590.       case GL_COLOR_INDEXES:
  591.          bitmask |= MAT_BIT_FRONT_INDEXES  | MAT_BIT_BACK_INDEXES;
  592.          break;
  593.       default:
  594.          _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
  595.          return 0;
  596.    }
  597.  
  598.    if (face==GL_FRONT) {
  599.       bitmask &= FRONT_MATERIAL_BITS;
  600.    }
  601.    else if (face==GL_BACK) {
  602.       bitmask &= BACK_MATERIAL_BITS;
  603.    }
  604.    else if (face != GL_FRONT_AND_BACK) {
  605.       _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
  606.       return 0;
  607.    }
  608.  
  609.    if (bitmask & ~legal) {
  610.       _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
  611.       return 0;
  612.    }
  613.  
  614.    return bitmask;
  615. }
  616.  
  617.  
  618.  
  619. /* Update derived values following a change in ctx->Light.Material
  620.  */
  621. void
  622. _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
  623. {
  624.    struct gl_light *light, *list = &ctx->Light.EnabledList;
  625.    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
  626.  
  627.    if (MESA_VERBOSE & VERBOSE_MATERIAL)
  628.       _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);
  629.  
  630.    if (!bitmask)
  631.       return;
  632.  
  633.    /* update material ambience */
  634.    if (bitmask & MAT_BIT_FRONT_AMBIENT) {
  635.       foreach (light, list) {
  636.          SCALE_3V( light->_MatAmbient[0], light->Ambient,
  637.                    mat[MAT_ATTRIB_FRONT_AMBIENT]);
  638.       }
  639.    }
  640.  
  641.    if (bitmask & MAT_BIT_BACK_AMBIENT) {
  642.       foreach (light, list) {
  643.          SCALE_3V( light->_MatAmbient[1], light->Ambient,
  644.                    mat[MAT_ATTRIB_BACK_AMBIENT]);
  645.       }
  646.    }
  647.  
  648.    /* update BaseColor = emission + scene's ambience * material's ambience */
  649.    if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {
  650.       COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );
  651.       ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],
  652.                     ctx->Light.Model.Ambient );
  653.    }
  654.  
  655.    if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {
  656.       COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );
  657.       ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],
  658.                     ctx->Light.Model.Ambient );
  659.    }
  660.  
  661.    /* update material diffuse values */
  662.    if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
  663.       foreach (light, list) {
  664.          SCALE_3V( light->_MatDiffuse[0], light->Diffuse,
  665.                    mat[MAT_ATTRIB_FRONT_DIFFUSE] );
  666.       }
  667.    }
  668.  
  669.    if (bitmask & MAT_BIT_BACK_DIFFUSE) {
  670.       foreach (light, list) {
  671.          SCALE_3V( light->_MatDiffuse[1], light->Diffuse,
  672.                    mat[MAT_ATTRIB_BACK_DIFFUSE] );
  673.       }
  674.    }
  675.  
  676.    /* update material specular values */
  677.    if (bitmask & MAT_BIT_FRONT_SPECULAR) {
  678.       foreach (light, list) {
  679.          SCALE_3V( light->_MatSpecular[0], light->Specular,
  680.                    mat[MAT_ATTRIB_FRONT_SPECULAR]);
  681.       }
  682.    }
  683.  
  684.    if (bitmask & MAT_BIT_BACK_SPECULAR) {
  685.       foreach (light, list) {
  686.          SCALE_3V( light->_MatSpecular[1], light->Specular,
  687.                    mat[MAT_ATTRIB_BACK_SPECULAR]);
  688.       }
  689.    }
  690. }
  691.  
  692.  
  693. /*
  694.  * Update the current materials from the given rgba color
  695.  * according to the bitmask in _ColorMaterialBitmask, which is
  696.  * set by glColorMaterial().
  697.  */
  698. void
  699. _mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] )
  700. {
  701.    const GLbitfield bitmask = ctx->Light._ColorMaterialBitmask;
  702.    struct gl_material *mat = &ctx->Light.Material;
  703.    int i;
  704.  
  705.    for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
  706.       if (bitmask & (1<<i))
  707.          COPY_4FV( mat->Attrib[i], color );
  708.  
  709.    _mesa_update_material( ctx, bitmask );
  710. }
  711.  
  712.  
  713. void GLAPIENTRY
  714. _mesa_ColorMaterial( GLenum face, GLenum mode )
  715. {
  716.    GET_CURRENT_CONTEXT(ctx);
  717.    GLuint bitmask;
  718.    GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |
  719.                    MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |
  720.                    MAT_BIT_FRONT_DIFFUSE  | MAT_BIT_BACK_DIFFUSE  |
  721.                    MAT_BIT_FRONT_AMBIENT  | MAT_BIT_BACK_AMBIENT);
  722.  
  723.    if (MESA_VERBOSE&VERBOSE_API)
  724.       _mesa_debug(ctx, "glColorMaterial %s %s\n",
  725.                   _mesa_lookup_enum_by_nr(face),
  726.                   _mesa_lookup_enum_by_nr(mode));
  727.  
  728.    bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
  729.    if (bitmask == 0)
  730.       return; /* error was recorded */
  731.  
  732.    if (ctx->Light._ColorMaterialBitmask == bitmask &&
  733.        ctx->Light.ColorMaterialFace == face &&
  734.        ctx->Light.ColorMaterialMode == mode)
  735.       return;
  736.  
  737.    FLUSH_VERTICES(ctx, _NEW_LIGHT);
  738.    ctx->Light._ColorMaterialBitmask = bitmask;
  739.    ctx->Light.ColorMaterialFace = face;
  740.    ctx->Light.ColorMaterialMode = mode;
  741.  
  742.    if (ctx->Light.ColorMaterialEnabled) {
  743.       FLUSH_CURRENT( ctx, 0 );
  744.       _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
  745.    }
  746.  
  747.    if (ctx->Driver.ColorMaterial)
  748.       ctx->Driver.ColorMaterial( ctx, face, mode );
  749. }
  750.  
  751.  
  752. void GLAPIENTRY
  753. _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
  754. {
  755.    GET_CURRENT_CONTEXT(ctx);
  756.    GLuint f;
  757.    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
  758.    FLUSH_VERTICES(ctx, 0); /* update materials */
  759.  
  760.    FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
  761.  
  762.    if (face==GL_FRONT) {
  763.       f = 0;
  764.    }
  765.    else if (face==GL_BACK) {
  766.       f = 1;
  767.    }
  768.    else {
  769.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
  770.       return;
  771.    }
  772.  
  773.    switch (pname) {
  774.       case GL_AMBIENT:
  775.          COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );
  776.          break;
  777.       case GL_DIFFUSE:
  778.          COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );
  779.          break;
  780.       case GL_SPECULAR:
  781.          COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );
  782.          break;
  783.       case GL_EMISSION:
  784.          COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );
  785.          break;
  786.       case GL_SHININESS:
  787.          *params = mat[MAT_ATTRIB_SHININESS(f)][0];
  788.          break;
  789.       case GL_COLOR_INDEXES:
  790.          if (ctx->API != API_OPENGL_COMPAT) {
  791.             _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  792.             return;
  793.          }
  794.          params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];
  795.          params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];
  796.          params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];
  797.          break;
  798.       default:
  799.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  800.    }
  801. }
  802.  
  803.  
  804. void GLAPIENTRY
  805. _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
  806. {
  807.    GET_CURRENT_CONTEXT(ctx);
  808.    GLuint f;
  809.    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
  810.  
  811.    ASSERT(ctx->API == API_OPENGL_COMPAT);
  812.  
  813.    FLUSH_VERTICES(ctx, 0); /* update materials */
  814.    FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
  815.  
  816.    if (face==GL_FRONT) {
  817.       f = 0;
  818.    }
  819.    else if (face==GL_BACK) {
  820.       f = 1;
  821.    }
  822.    else {
  823.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
  824.       return;
  825.    }
  826.    switch (pname) {
  827.       case GL_AMBIENT:
  828.          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );
  829.          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );
  830.          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );
  831.          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );
  832.          break;
  833.       case GL_DIFFUSE:
  834.          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );
  835.          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );
  836.          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );
  837.          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );
  838.          break;
  839.       case GL_SPECULAR:
  840.          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );
  841.          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );
  842.          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );
  843.          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );
  844.          break;
  845.       case GL_EMISSION:
  846.          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );
  847.          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );
  848.          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );
  849.          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );
  850.          break;
  851.       case GL_SHININESS:
  852.          *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] );
  853.          break;
  854.       case GL_COLOR_INDEXES:
  855.          params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] );
  856.          params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] );
  857.          params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] );
  858.          break;
  859.       default:
  860.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  861.    }
  862. }
  863.  
  864.  
  865.  
  866. /**
  867.  * Examine current lighting parameters to determine if the optimized lighting
  868.  * function can be used.
  869.  * Also, precompute some lighting values such as the products of light
  870.  * source and material ambient, diffuse and specular coefficients.
  871.  */
  872. void
  873. _mesa_update_lighting( struct gl_context *ctx )
  874. {
  875.    GLbitfield flags = 0;
  876.    struct gl_light *light;
  877.    ctx->Light._NeedEyeCoords = GL_FALSE;
  878.  
  879.    if (!ctx->Light.Enabled)
  880.       return;
  881.  
  882.    foreach(light, &ctx->Light.EnabledList) {
  883.       flags |= light->_Flags;
  884.    }
  885.  
  886.    ctx->Light._NeedVertices =
  887.       ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
  888.        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
  889.        ctx->Light.Model.LocalViewer);
  890.  
  891.    ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) ||
  892.                                 ctx->Light.Model.LocalViewer);
  893.  
  894.    /* XXX: This test is overkill & needs to be fixed both for software and
  895.     * hardware t&l drivers.  The above should be sufficient & should
  896.     * be tested to verify this.
  897.     */
  898.    if (ctx->Light._NeedVertices)
  899.       ctx->Light._NeedEyeCoords = GL_TRUE;
  900.  
  901.    /* Precompute some shading values.  Although we reference
  902.     * Light.Material here, we can get away without flushing
  903.     * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
  904.     * are flushed, they will update the derived state at that time.
  905.     */
  906.    if (ctx->Light.Model.TwoSide)
  907.       _mesa_update_material(ctx,
  908.                             MAT_BIT_FRONT_EMISSION |
  909.                             MAT_BIT_FRONT_AMBIENT |
  910.                             MAT_BIT_FRONT_DIFFUSE |
  911.                             MAT_BIT_FRONT_SPECULAR |
  912.                             MAT_BIT_BACK_EMISSION |
  913.                             MAT_BIT_BACK_AMBIENT |
  914.                             MAT_BIT_BACK_DIFFUSE |
  915.                             MAT_BIT_BACK_SPECULAR);
  916.    else
  917.       _mesa_update_material(ctx,
  918.                             MAT_BIT_FRONT_EMISSION |
  919.                             MAT_BIT_FRONT_AMBIENT |
  920.                             MAT_BIT_FRONT_DIFFUSE |
  921.                             MAT_BIT_FRONT_SPECULAR);
  922. }
  923.  
  924.  
  925. /**
  926.  * Update state derived from light position, spot direction.
  927.  * Called upon:
  928.  *   _NEW_MODELVIEW
  929.  *   _NEW_LIGHT
  930.  *   _TNL_NEW_NEED_EYE_COORDS
  931.  *
  932.  * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
  933.  * Also update on lighting space changes.
  934.  */
  935. static void
  936. compute_light_positions( struct gl_context *ctx )
  937. {
  938.    struct gl_light *light;
  939.    static const GLfloat eye_z[3] = { 0, 0, 1 };
  940.  
  941.    if (!ctx->Light.Enabled)
  942.       return;
  943.  
  944.    if (ctx->_NeedEyeCoords) {
  945.       COPY_3V( ctx->_EyeZDir, eye_z );
  946.    }
  947.    else {
  948.       TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
  949.    }
  950.  
  951.    foreach (light, &ctx->Light.EnabledList) {
  952.  
  953.       if (ctx->_NeedEyeCoords) {
  954.          /* _Position is in eye coordinate space */
  955.          COPY_4FV( light->_Position, light->EyePosition );
  956.       }
  957.       else {
  958.          /* _Position is in object coordinate space */
  959.          TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
  960.                           light->EyePosition );
  961.       }
  962.  
  963.       if (!(light->_Flags & LIGHT_POSITIONAL)) {
  964.          /* VP (VP) = Normalize( Position ) */
  965.          COPY_3V( light->_VP_inf_norm, light->_Position );
  966.          NORMALIZE_3FV( light->_VP_inf_norm );
  967.  
  968.          if (!ctx->Light.Model.LocalViewer) {
  969.             /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
  970.             ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
  971.             NORMALIZE_3FV( light->_h_inf_norm );
  972.          }
  973.          light->_VP_inf_spot_attenuation = 1.0;
  974.       }
  975.       else {
  976.          /* positional light w/ homogeneous coordinate, divide by W */
  977.          GLfloat wInv = (GLfloat)1.0 / light->_Position[3];
  978.          light->_Position[0] *= wInv;
  979.          light->_Position[1] *= wInv;
  980.          light->_Position[2] *= wInv;
  981.       }
  982.  
  983.       if (light->_Flags & LIGHT_SPOT) {
  984.          /* Note: we normalize the spot direction now */
  985.  
  986.          if (ctx->_NeedEyeCoords) {
  987.             COPY_3V( light->_NormSpotDirection, light->SpotDirection );
  988.             NORMALIZE_3FV( light->_NormSpotDirection );
  989.          }
  990.          else {
  991.             GLfloat spotDir[3];
  992.             COPY_3V(spotDir, light->SpotDirection);
  993.             NORMALIZE_3FV(spotDir);
  994.             TRANSFORM_NORMAL( light->_NormSpotDirection,
  995.                               spotDir,
  996.                               ctx->ModelviewMatrixStack.Top->m);
  997.          }
  998.  
  999.          NORMALIZE_3FV( light->_NormSpotDirection );
  1000.  
  1001.          if (!(light->_Flags & LIGHT_POSITIONAL)) {
  1002.             GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
  1003.                                         light->_NormSpotDirection);
  1004.  
  1005.             if (PV_dot_dir > light->_CosCutoff) {
  1006.                light->_VP_inf_spot_attenuation =
  1007.                   powf(PV_dot_dir, light->SpotExponent);
  1008.             }
  1009.             else {
  1010.                light->_VP_inf_spot_attenuation = 0;
  1011.             }
  1012.          }
  1013.       }
  1014.    }
  1015. }
  1016.  
  1017.  
  1018.  
  1019. static void
  1020. update_modelview_scale( struct gl_context *ctx )
  1021. {
  1022.    ctx->_ModelViewInvScale = 1.0F;
  1023.    if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
  1024.       const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
  1025.       GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
  1026.       if (f < 1e-12) f = 1.0;
  1027.       if (ctx->_NeedEyeCoords)
  1028.          ctx->_ModelViewInvScale = (GLfloat) INV_SQRTF(f);
  1029.       else
  1030.          ctx->_ModelViewInvScale = (GLfloat) sqrtf(f);
  1031.    }
  1032. }
  1033.  
  1034.  
  1035. /**
  1036.  * Bring up to date any state that relies on _NeedEyeCoords.
  1037.  */
  1038. void
  1039. _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state )
  1040. {
  1041.    const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
  1042.  
  1043.    (void) new_state;
  1044.    ctx->_NeedEyeCoords = GL_FALSE;
  1045.  
  1046.    if (ctx->_ForceEyeCoords ||
  1047.        (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) ||
  1048.        ctx->Point._Attenuated ||
  1049.        ctx->Light._NeedEyeCoords)
  1050.       ctx->_NeedEyeCoords = GL_TRUE;
  1051.  
  1052.    if (ctx->Light.Enabled &&
  1053.        !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top))
  1054.       ctx->_NeedEyeCoords = GL_TRUE;
  1055.  
  1056.    /* Check if the truth-value interpretations of the bitfields have
  1057.     * changed:
  1058.     */
  1059.    if (oldneedeyecoords != ctx->_NeedEyeCoords) {
  1060.       /* Recalculate all state that depends on _NeedEyeCoords.
  1061.        */
  1062.       update_modelview_scale(ctx);
  1063.       compute_light_positions( ctx );
  1064.  
  1065.       if (ctx->Driver.LightingSpaceChange)
  1066.          ctx->Driver.LightingSpaceChange( ctx );
  1067.    }
  1068.    else {
  1069.       GLuint new_state2 = ctx->NewState;
  1070.  
  1071.       /* Recalculate that same state only if it has been invalidated
  1072.        * by other statechanges.
  1073.        */
  1074.       if (new_state2 & _NEW_MODELVIEW)
  1075.          update_modelview_scale(ctx);
  1076.  
  1077.       if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
  1078.          compute_light_positions( ctx );
  1079.    }
  1080. }
  1081.  
  1082.  
  1083. /**
  1084.  * Drivers may need this if the hardware tnl unit doesn't support the
  1085.  * light-in-modelspace optimization.  It's also useful for debugging.
  1086.  */
  1087. void
  1088. _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag )
  1089. {
  1090.    ctx->_ForceEyeCoords = !flag;
  1091.    ctx->NewState |= _NEW_POINT; /* one of the bits from
  1092.                                  * _MESA_NEW_NEED_EYE_COORDS.
  1093.                                  */
  1094. }
  1095.  
  1096.  
  1097.  
  1098. /**********************************************************************/
  1099. /*****                      Initialization                        *****/
  1100. /**********************************************************************/
  1101.  
  1102. /**
  1103.  * Initialize the n-th light data structure.
  1104.  *
  1105.  * \param l pointer to the gl_light structure to be initialized.
  1106.  * \param n number of the light.
  1107.  * \note The defaults for light 0 are different than the other lights.
  1108.  */
  1109. static void
  1110. init_light( struct gl_light *l, GLuint n )
  1111. {
  1112.    make_empty_list( l );
  1113.  
  1114.    ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
  1115.    if (n==0) {
  1116.       ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
  1117.       ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
  1118.    }
  1119.    else {
  1120.       ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
  1121.       ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
  1122.    }
  1123.    ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
  1124.    ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 );
  1125.    l->SpotExponent = 0.0;
  1126.    l->SpotCutoff = 180.0;
  1127.    l->_CosCutoff = 0.0;         /* KW: -ve values not admitted */
  1128.    l->ConstantAttenuation = 1.0;
  1129.    l->LinearAttenuation = 0.0;
  1130.    l->QuadraticAttenuation = 0.0;
  1131.    l->Enabled = GL_FALSE;
  1132. }
  1133.  
  1134.  
  1135. /**
  1136.  * Initialize the light model data structure.
  1137.  *
  1138.  * \param lm pointer to the gl_lightmodel structure to be initialized.
  1139.  */
  1140. static void
  1141. init_lightmodel( struct gl_lightmodel *lm )
  1142. {
  1143.    ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F );
  1144.    lm->LocalViewer = GL_FALSE;
  1145.    lm->TwoSide = GL_FALSE;
  1146.    lm->ColorControl = GL_SINGLE_COLOR;
  1147. }
  1148.  
  1149.  
  1150. /**
  1151.  * Initialize the material data structure.
  1152.  *
  1153.  * \param m pointer to the gl_material structure to be initialized.
  1154.  */
  1155. static void
  1156. init_material( struct gl_material *m )
  1157. {
  1158.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
  1159.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
  1160.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
  1161.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
  1162.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
  1163.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
  1164.  
  1165.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
  1166.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
  1167.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
  1168.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
  1169.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
  1170.    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
  1171. }
  1172.  
  1173.  
  1174. /**
  1175.  * Initialize all lighting state for the given context.
  1176.  */
  1177. void
  1178. _mesa_init_lighting( struct gl_context *ctx )
  1179. {
  1180.    GLuint i;
  1181.  
  1182.    /* Lighting group */
  1183.    for (i = 0; i < MAX_LIGHTS; i++) {
  1184.       init_light( &ctx->Light.Light[i], i );
  1185.    }
  1186.    make_empty_list( &ctx->Light.EnabledList );
  1187.  
  1188.    init_lightmodel( &ctx->Light.Model );
  1189.    init_material( &ctx->Light.Material );
  1190.    ctx->Light.ShadeModel = GL_SMOOTH;
  1191.    ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
  1192.    ctx->Light.Enabled = GL_FALSE;
  1193.    ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
  1194.    ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
  1195.    ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx,
  1196.                                                GL_FRONT_AND_BACK,
  1197.                                                GL_AMBIENT_AND_DIFFUSE, ~0,
  1198.                                                NULL );
  1199.  
  1200.    ctx->Light.ColorMaterialEnabled = GL_FALSE;
  1201.    ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
  1202.    ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
  1203.  
  1204.    /* Miscellaneous */
  1205.    ctx->Light._NeedEyeCoords = GL_FALSE;
  1206.    ctx->_NeedEyeCoords = GL_FALSE;
  1207.    ctx->_ForceEyeCoords = GL_FALSE;
  1208.    ctx->_ModelViewInvScale = 1.0;
  1209. }
  1210.  
  1211.  
  1212. /**
  1213.  * Deallocate malloc'd lighting state attached to given context.
  1214.  */
  1215. void
  1216. _mesa_free_lighting_data( struct gl_context *ctx )
  1217. {
  1218. }
  1219.