summaryrefslogtreecommitdiff
path: root/src/mesa/main/light.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/light.c')
-rw-r--r--src/mesa/main/light.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index ce50224d30..10c89f4368 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 7.0
+ * Version: 7.5
*
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. 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"),
@@ -64,6 +65,37 @@ _mesa_ShadeModel( GLenum mode )
/**
+ * Set the provoking vertex (the vertex which specifies the prim's
+ * color when flat shading) to either the first or last vertex of the
+ * triangle or line.
+ */
+void GLAPIENTRY
+_mesa_ProvokingVertexEXT(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode);
+
+ switch (mode) {
+ case GL_FIRST_VERTEX_CONVENTION_EXT:
+ case GL_LAST_VERTEX_CONVENTION_EXT:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode);
+ return;
+ }
+
+ if (ctx->Light.ProvokingVertex == mode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.ProvokingVertex = mode;
+}
+
+
+/**
* Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
* per-light state.
* For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
@@ -110,10 +142,10 @@ _mesa_light(GLcontext *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
break;
case GL_SPOT_DIRECTION:
/* NOTE: Direction already transformed by inverse ModelView! */
- if (TEST_EQ_3V(light->EyeDirection, params))
+ if (TEST_EQ_3V(light->SpotDirection, params))
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
- COPY_3V(light->EyeDirection, params);
+ COPY_3V(light->SpotDirection, params);
break;
case GL_SPOT_EXPONENT:
ASSERT(params[0] >= 0.0);
@@ -209,7 +241,6 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
_math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
}
TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m);
- NORMALIZE_3FV(temp);
params = temp;
break;
case GL_SPOT_EXPONENT:
@@ -326,7 +357,7 @@ _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
COPY_4V( params, ctx->Light.Light[l].EyePosition );
break;
case GL_SPOT_DIRECTION:
- COPY_3V( params, ctx->Light.Light[l].EyeDirection );
+ COPY_3V( params, ctx->Light.Light[l].SpotDirection );
break;
case GL_SPOT_EXPONENT:
params[0] = ctx->Light.Light[l].SpotExponent;
@@ -388,9 +419,9 @@ _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
break;
case GL_SPOT_DIRECTION:
- params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
- params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
- params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
+ params[0] = (GLint) ctx->Light.Light[l].SpotDirection[0];
+ params[1] = (GLint) ctx->Light.Light[l].SpotDirection[1];
+ params[2] = (GLint) ctx->Light.Light[l].SpotDirection[2];
break;
case GL_SPOT_EXPONENT:
params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
@@ -497,7 +528,7 @@ _mesa_LightModeliv( GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_LightModelfv( pname, fparam );
}
@@ -1137,20 +1168,26 @@ compute_light_positions( GLcontext *ctx )
}
if (light->_Flags & LIGHT_SPOT) {
+ /* Note: we normalize the spot direction now */
+
if (ctx->_NeedEyeCoords) {
- COPY_3V( light->_NormDirection, light->EyeDirection );
+ COPY_3V( light->_NormSpotDirection, light->SpotDirection );
+ NORMALIZE_3FV( light->_NormSpotDirection );
}
else {
- TRANSFORM_NORMAL( light->_NormDirection,
- light->EyeDirection,
+ GLfloat spotDir[3];
+ COPY_3V(spotDir, light->SpotDirection);
+ NORMALIZE_3FV(spotDir);
+ TRANSFORM_NORMAL( light->_NormSpotDirection,
+ spotDir,
ctx->ModelviewMatrixStack.Top->m);
}
- NORMALIZE_3FV( light->_NormDirection );
+ NORMALIZE_3FV( light->_NormSpotDirection );
if (!(light->_Flags & LIGHT_POSITIONAL)) {
GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
- light->_NormDirection);
+ light->_NormSpotDirection);
if (PV_dot_dir > light->_CosCutoff) {
double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
@@ -1219,15 +1256,15 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state )
ctx->Driver.LightingSpaceChange( ctx );
}
else {
- GLuint new_state = ctx->NewState;
+ GLuint new_state2 = ctx->NewState;
/* Recalculate that same state only if it has been invalidated
* by other statechanges.
*/
- if (new_state & _NEW_MODELVIEW)
+ if (new_state2 & _NEW_MODELVIEW)
update_modelview_scale(ctx);
- if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
compute_light_positions( ctx );
}
}
@@ -1274,7 +1311,7 @@ init_light( struct gl_light *l, GLuint n )
ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
}
ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
- ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
+ ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 );
l->SpotExponent = 0.0;
_mesa_invalidate_spot_exp_table( l );
l->SpotCutoff = 180.0;
@@ -1343,6 +1380,7 @@ _mesa_init_lighting( GLcontext *ctx )
init_lightmodel( &ctx->Light.Model );
init_material( &ctx->Light.Material );
ctx->Light.ShadeModel = GL_SMOOTH;
+ ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
ctx->Light.Enabled = GL_FALSE;
ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
@@ -1368,6 +1406,7 @@ _mesa_init_lighting( GLcontext *ctx )
/* Miscellaneous */
ctx->Light._NeedEyeCoords = GL_FALSE;
ctx->_NeedEyeCoords = GL_FALSE;
+ ctx->_ForceEyeCoords = GL_FALSE;
ctx->_ModelViewInvScale = 1.0;
}