more work on GL_ARB_texture_compression
[mesa.git] / src / mesa / main / light.c
index 966b548082bcb390f3c219c5f1ae792157e9356f..a6696b1e1ae9d4b7d08237026624b3b41f2cce99 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: light.c,v 1.5 1999/10/19 18:37:04 keithw Exp $ */
+/* $Id: light.c,v 1.12 2000/01/31 23:33:53 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.3
  * 
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  */
 
 
-
-
-
 #ifdef PC_HEADER
 #include "all.h"
 #else
-#include <float.h>
-#ifndef XFree86Server
-#include <assert.h>
-#include <float.h>
-#include <math.h>
-#include <stdlib.h>
-#else
-#include "GL/xf86glx.h"
-#endif
-#include <stdio.h>
+#include "glheader.h"
 #include "context.h"
 #include "enums.h"
 #include "light.h"
 #include "macros.h"
 #include "matrix.h"
+#include "mem.h"
 #include "mmath.h"
 #include "simple_list.h"
 #include "types.h"
 #endif
 
 
+/* XXX this is a bit of a hack needed for compilation within XFree86 */
+#ifndef FLT_MIN
+#define FLT_MIN 1e-37
+#endif
+
 
-void gl_ShadeModel( GLcontext *ctx, GLenum mode )
+void
+_mesa_ShadeModel( GLenum mode )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
 
    if (MESA_VERBOSE & VERBOSE_API)
       fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
 
-
-   switch (mode) {
-   case GL_FLAT:
-   case GL_SMOOTH:
-      if (ctx->Light.ShadeModel!=mode) {
-        ctx->Light.ShadeModel = mode;
-        ctx->TriangleCaps ^= DD_FLATSHADE;
-        ctx->NewState |= NEW_RASTER_OPS;
+   if (mode == GL_FLAT || mode == GL_SMOOTH) {
+      if (ctx->Light.ShadeModel != mode) {
+         ctx->Light.ShadeModel = mode;
+         if (ctx->Light.ShadeModel == GL_FLAT)
+            SET_BITS(ctx->TriangleCaps, DD_FLATSHADE);
+         else
+            CLEAR_BITS(ctx->TriangleCaps, DD_FLATSHADE);
+         ctx->NewState |= NEW_RASTER_OPS;
+         if (ctx->Driver.ShadeModel) 
+            (*ctx->Driver.ShadeModel)( ctx, mode );
       }
-      break;
-   default:
+   }
+   else {
       gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
    }
-
-   if (ctx->Driver.ShadeModel) 
-      (*ctx->Driver.ShadeModel)( ctx, mode );
 }
 
 
 
-void gl_Lightfv( GLcontext *ctx,
-                 GLenum light, GLenum pname, const GLfloat *params,
-                 GLint nparams )
+void
+_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
 {
-   GLint l;
+   _mesa_Lightfv( light, pname, &param );
+}
 
-   (void) nparams;
+
+void
+_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint l;
+   GLint nParams;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
 
    l = (GLint) (light - GL_LIGHT0);
 
-   if (l<0 || l>=MAX_LIGHTS) {
+   if (l < 0 || l >= MAX_LIGHTS) {
       gl_error( ctx, GL_INVALID_ENUM, "glLight" );
       return;
    }
@@ -102,18 +103,22 @@ void gl_Lightfv( GLcontext *ctx,
    switch (pname) {
       case GL_AMBIENT:
          COPY_4V( ctx->Light.Light[l].Ambient, params );
+         nParams = 4;
          break;
       case GL_DIFFUSE:
          COPY_4V( ctx->Light.Light[l].Diffuse, params );
+         nParams = 4;
          break;
       case GL_SPECULAR:
          COPY_4V( ctx->Light.Light[l].Specular, params );
+         nParams = 4;
          break;
       case GL_POSITION:
         /* transform position by ModelView matrix */
         TRANSFORM_POINT( ctx->Light.Light[l].EyePosition, 
                          ctx->ModelView.m,
                           params );
+         nParams = 4;
          break;
       case GL_SPOT_DIRECTION:
         /* transform direction by inverse modelview */
@@ -123,6 +128,7 @@ void gl_Lightfv( GLcontext *ctx,
         TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
                           params,
                           ctx->ModelView.inv );
+         nParams = 3;
          break;
       case GL_SPOT_EXPONENT:
          if (params[0]<0.0 || params[0]>128.0) {
@@ -133,6 +139,7 @@ void gl_Lightfv( GLcontext *ctx,
             ctx->Light.Light[l].SpotExponent = params[0];
             gl_compute_spot_exp_table( &ctx->Light.Light[l] );
          }
+         nParams = 1;
          break;
       case GL_SPOT_CUTOFF:
          if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
@@ -143,6 +150,7 @@ void gl_Lightfv( GLcontext *ctx,
          ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
          if (ctx->Light.Light[l].CosCutoff < 0) 
            ctx->Light.Light[l].CosCutoff = 0;
+         nParams = 1;
          break;
       case GL_CONSTANT_ATTENUATION:
          if (params[0]<0.0) {
@@ -150,6 +158,7 @@ void gl_Lightfv( GLcontext *ctx,
             return;
          }
          ctx->Light.Light[l].ConstantAttenuation = params[0];
+         nParams = 1;
          break;
       case GL_LINEAR_ATTENUATION:
          if (params[0]<0.0) {
@@ -157,6 +166,7 @@ void gl_Lightfv( GLcontext *ctx,
             return;
          }
          ctx->Light.Light[l].LinearAttenuation = params[0];
+         nParams = 1;
          break;
       case GL_QUADRATIC_ATTENUATION:
          if (params[0]<0.0) {
@@ -164,23 +174,73 @@ void gl_Lightfv( GLcontext *ctx,
             return;
          }
          ctx->Light.Light[l].QuadraticAttenuation = params[0];
+         nParams = 1;
          break;
       default:
          gl_error( ctx, GL_INVALID_ENUM, "glLight" );
-         break;
+         return;
    }
 
    if (ctx->Driver.Lightfv)
-      ctx->Driver.Lightfv( ctx, light, pname, params, nparams );
+      ctx->Driver.Lightfv( ctx, light, pname, params, nParams );
 
    ctx->NewState |= NEW_LIGHTING;
 }
 
 
+void
+_mesa_Lighti( GLenum light, GLenum pname, GLint param )
+{
+   _mesa_Lightiv( light, pname, &param );
+}
+
 
-void gl_GetLightfv( GLcontext *ctx,
-                    GLenum light, GLenum pname, GLfloat *params )
+void
+_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
 {
+   GLfloat fparam[4];
+
+   switch (pname) {
+      case GL_AMBIENT:
+      case GL_DIFFUSE:
+      case GL_SPECULAR:
+         fparam[0] = INT_TO_FLOAT( params[0] );
+         fparam[1] = INT_TO_FLOAT( params[1] );
+         fparam[2] = INT_TO_FLOAT( params[2] );
+         fparam[3] = INT_TO_FLOAT( params[3] );
+         break;
+      case GL_POSITION:
+         fparam[0] = (GLfloat) params[0];
+         fparam[1] = (GLfloat) params[1];
+         fparam[2] = (GLfloat) params[2];
+         fparam[3] = (GLfloat) params[3];
+         break;
+      case GL_SPOT_DIRECTION:
+         fparam[0] = (GLfloat) params[0];
+         fparam[1] = (GLfloat) params[1];
+         fparam[2] = (GLfloat) params[2];
+         break;
+      case GL_SPOT_EXPONENT:
+      case GL_SPOT_CUTOFF:
+      case GL_CONSTANT_ATTENUATION:
+      case GL_LINEAR_ATTENUATION:
+      case GL_QUADRATIC_ATTENUATION:
+         fparam[0] = (GLfloat) params[0];
+         break;
+      default:
+         /* error will be caught later in gl_Lightfv */
+         ;
+   }
+
+   _mesa_Lightfv( light, pname, fparam );
+}
+
+
+
+void
+_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
+{
+   GET_CURRENT_CONTEXT(ctx);
    GLint l = (GLint) (light - GL_LIGHT0);
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
@@ -229,8 +289,10 @@ void gl_GetLightfv( GLcontext *ctx,
 
 
 
-void gl_GetLightiv( GLcontext *ctx, GLenum light, GLenum pname, GLint *params )
+void
+_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint l = (GLint) (light - GL_LIGHT0);
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
@@ -298,9 +360,11 @@ void gl_GetLightiv( GLcontext *ctx, GLenum light, GLenum pname, GLint *params )
 /**********************************************************************/
 
 
-void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+void
+_mesa_LightModelfv( GLenum pname, const GLfloat *params )
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModel");
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
 
    switch (pname) {
       case GL_LIGHT_MODEL_AMBIENT:
@@ -319,15 +383,18 @@ void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
             ctx->Light.Model.TwoSide = GL_TRUE;
          break;
       case GL_LIGHT_MODEL_COLOR_CONTROL:
-        ctx->TriangleCaps &= ~DD_SEPERATE_SPECULAR;
-        ctx->NewState |= NEW_RASTER_OPS;
-         if (params[0] == (GLfloat) GL_SINGLE_COLOR) 
+         if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
             ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
+            CLEAR_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
+         }
          else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
             ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
-           ctx->TriangleCaps |= DD_SEPERATE_SPECULAR;
-        } else
+           SET_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
+        }
+         else {
             gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
+         }
+        ctx->NewState |= NEW_RASTER_OPS;
          break;
       default:
          gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
@@ -341,6 +408,46 @@ void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
 }
 
 
+void
+_mesa_LightModeliv( GLenum pname, const GLint *params )
+{
+   GLfloat fparam[4];
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
+
+   switch (pname) {
+      case GL_LIGHT_MODEL_AMBIENT:
+         fparam[0] = INT_TO_FLOAT( params[0] );
+         fparam[1] = INT_TO_FLOAT( params[1] );
+         fparam[2] = INT_TO_FLOAT( params[2] );
+         fparam[3] = INT_TO_FLOAT( params[3] );
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+      case GL_LIGHT_MODEL_TWO_SIDE:
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+         fparam[0] = (GLfloat) params[0];
+         break;
+      default:
+         /* Error will be caught later in gl_LightModelfv */
+         ;
+   }
+   _mesa_LightModelfv( pname, fparam );
+}
+
+
+void
+_mesa_LightModeli( GLenum pname, GLint param )
+{
+   _mesa_LightModeliv( pname, &param );
+}
+
+
+void
+_mesa_LightModelf( GLenum pname, GLfloat param )
+{
+   _mesa_LightModelfv( pname, &param );
+}
+
 
 
 /********** MATERIAL **********/
@@ -432,6 +539,9 @@ void gl_update_material( GLcontext *ctx,
    if (ctx->Light.ColorMaterialEnabled)
       bitmask &= ~ctx->Light.ColorMaterialBitmask;
 
+   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
+      fprintf(stderr, "gl_update_material, mask %x\n", bitmask);
+
    if (!bitmask) 
       return;
 
@@ -528,6 +638,26 @@ void gl_update_material( GLcontext *ctx,
       ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
    }
 
+   if (0)
+   {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      fprintf(stderr, "update_mat  emission : %f %f %f\n",
+             mat->Emission[0],
+             mat->Emission[1],
+             mat->Emission[2]);
+      fprintf(stderr, "update_mat  specular : %f %f %f\n",
+             mat->Specular[0],
+             mat->Specular[1],
+             mat->Specular[2]);
+      fprintf(stderr, "update_mat  diffuse : %f %f %f\n",
+             mat->Diffuse[0],
+             mat->Diffuse[1],
+             mat->Diffuse[2]);
+      fprintf(stderr, "update_mat  ambient : %f %f %f\n",
+             mat->Ambient[0],
+             mat->Ambient[1],
+             mat->Ambient[2]);
+   }
 }
 
 
@@ -544,6 +674,10 @@ void gl_update_color_material( GLcontext *ctx,
 
    UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
    
+   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
+      fprintf(stderr, "gl_update_color_material, mask %x\n", bitmask);
+
+
    if (bitmask & FRONT_AMBIENT_BIT) {
       struct gl_material *mat = &ctx->Light.Material[0];
       SUB_3V( tmp, color, mat->Ambient );
@@ -620,13 +754,36 @@ void gl_update_color_material( GLcontext *ctx,
       ACC_3V( ctx->Light.BaseColor[1], tmp );
       COPY_4FV( mat->Emission, color );
    }
+
+   if (0)
+   {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      fprintf(stderr, "update_color_mat  emission : %f %f %f\n",
+             mat->Emission[0],
+             mat->Emission[1],
+             mat->Emission[2]);
+      fprintf(stderr, "update_color_mat  specular : %f %f %f\n",
+             mat->Specular[0],
+             mat->Specular[1],
+             mat->Specular[2]);
+      fprintf(stderr, "update_color_mat  diffuse : %f %f %f\n",
+             mat->Diffuse[0],
+             mat->Diffuse[1],
+             mat->Diffuse[2]);
+      fprintf(stderr, "update_color_mat  ambient : %f %f %f\n",
+             mat->Ambient[0],
+             mat->Ambient[1],
+             mat->Ambient[2]);
+   }
 }
 
 
 
 
-void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
+void
+_mesa_ColorMaterial( GLenum face, GLenum mode )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLuint bitmask;
    GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
                   FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
@@ -635,6 +792,11 @@ void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
 
+   if (MESA_VERBOSE&VERBOSE_API) 
+      fprintf(stderr, "glColorMaterial %s %s\n", 
+             gl_lookup_enum_by_nr(face),
+             gl_lookup_enum_by_nr(mode));
+
    bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
 
    if (bitmask != 0) {
@@ -642,16 +804,28 @@ void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
       ctx->Light.ColorMaterialFace = face;
       ctx->Light.ColorMaterialMode = mode;
    }
+
+   if (ctx->Light.ColorMaterialEnabled)
+      gl_update_color_material( ctx, ctx->Current.ByteColor );
 }
 
 
 
+
+void
+_mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
+{
+   _mesa_Materialfv( face, pname, &param );
+}
+
+
 /* KW:  This is now called directly (ie by name) from the glMaterial* 
  *      API functions.
  */
-void gl_Materialfv( GLcontext *ctx,
-                    GLenum face, GLenum pname, const GLfloat *params )
+void
+_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
 {
+   GET_CURRENT_CONTEXT(ctx);
    struct immediate *IM;
    struct gl_material *mat;
    GLuint bitmask;
@@ -726,11 +900,48 @@ void gl_Materialfv( GLcontext *ctx,
 }
 
 
+void
+_mesa_Materiali(GLenum face, GLenum pname, GLint param )
+{
+   _mesa_Materialiv(face, pname, &param);
+}
+
+
+void
+_mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
+{
+   GLfloat fparam[4];
+   switch (pname) {
+      case GL_AMBIENT:
+      case GL_DIFFUSE:
+      case GL_SPECULAR:
+      case GL_EMISSION:
+      case GL_AMBIENT_AND_DIFFUSE:
+         fparam[0] = INT_TO_FLOAT( params[0] );
+         fparam[1] = INT_TO_FLOAT( params[1] );
+         fparam[2] = INT_TO_FLOAT( params[2] );
+         fparam[3] = INT_TO_FLOAT( params[3] );
+         break;
+      case GL_SHININESS:
+         fparam[0] = (GLfloat) params[0];
+         break;
+      case GL_COLOR_INDEXES:
+         fparam[0] = (GLfloat) params[0];
+         fparam[1] = (GLfloat) params[1];
+         fparam[2] = (GLfloat) params[2];
+         break;
+      default:
+         /* Error will be caught later in gl_Materialfv */
+         ;
+   }
+   _mesa_Materialfv(face, pname, fparam);
+}
 
 
-void gl_GetMaterialfv( GLcontext *ctx,
-                       GLenum face, GLenum pname, GLfloat *params )
+void
+_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLuint f;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
@@ -773,9 +984,10 @@ void gl_GetMaterialfv( GLcontext *ctx,
 
 
 
-void gl_GetMaterialiv( GLcontext *ctx,
-                       GLenum face, GLenum pname, GLint *params )
+void
+_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLuint f;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
@@ -953,8 +1165,8 @@ void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
 
 
 
-
-void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
+#if 0
+static void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
 {
    GLuint i;
 
@@ -974,7 +1186,7 @@ void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
         insert_at_tail( &l->EnabledList, &l->Light[i] );
    }
 }
-
+#endif
 
 
 /*