diff options
35 files changed, 899 insertions, 642 deletions
diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 0305a2740be..24dd9946a36 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -766,6 +766,10 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) _swrast_CreateContext( fxMesa->glCtx ); _swsetup_CreateContext( fxMesa->glCtx ); + /* Tell the software rasterizer to use pixel fog always. + */ + _swrast_allow_vertex_fog( fxMesa->glCtx, GL_FALSE ); + _swrast_allow_pixel_fog( fxMesa->glCtx, GL_TRUE ); fxSetupDDPointers(fxMesa->glCtx); fxDDInitExtensions(fxMesa->glCtx); @@ -992,7 +996,7 @@ void fxSetupDDPointers(GLcontext *ctx) ctx->Driver.Flush=NULL; ctx->Driver.RenderStart=NULL; - ctx->Driver.RenderFinish=NULL; + ctx->Driver.RenderFinish=_swrast_flush; ctx->Driver.TexImage2D = fxDDTexImage2D; ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 79adf4e014f..179178e2581 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,4 +1,4 @@ -/* $Id: xm_dd.c,v 1.3 2000/11/05 18:26:12 keithw Exp $ */ +/* $Id: xm_dd.c,v 1.4 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -947,7 +947,7 @@ void xmesa_init_pointers( GLcontext *ctx ) ctx->Driver.Finish = finish; ctx->Driver.RenderStart = 0; - ctx->Driver.RenderFinish = 0; + ctx->Driver.RenderFinish = _swrast_flush; ctx->Driver.SetDrawBuffer = set_draw_buffer; ctx->Driver.SetReadBuffer = set_read_buffer; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index fe0382dfe9a..513f0f69a01 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -1,4 +1,4 @@ -/* $Id: buffers.c,v 1.18 2000/10/31 18:09:44 keithw Exp $ */ +/* $Id: buffers.c,v 1.19 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -98,14 +98,14 @@ _mesa_Clear( GLbitfield mask ) fprintf(stderr, "glClear 0x%x\n", mask); if (ctx->NewState) { - gl_update_state( ctx ); + gl_update_state( ctx ); /* update _Xmin, etc */ } if (ctx->RenderMode==GL_RENDER) { - const GLint x = ctx->DrawBuffer->Xmin; - const GLint y = ctx->DrawBuffer->Ymin; - const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; - const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; GLbitfield ddMask; GLbitfield newMask; diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c index 19675552ab4..244753020b1 100644 --- a/src/mesa/main/clip.c +++ b/src/mesa/main/clip.c @@ -1,4 +1,4 @@ -/* $Id: clip.c,v 1.13 2000/11/05 18:40:57 keithw Exp $ */ +/* $Id: clip.c,v 1.14 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -215,19 +215,6 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) } -void gl_update_userclip( GLcontext *ctx ) -{ - GLuint p; - - for (p = 0 ; p < MAX_CLIP_PLANES ; p++) { - if (ctx->Transform.ClipEnabled[p]) { - gl_transform_vector( ctx->Transform._ClipUserPlane[p], - ctx->Transform.EyeUserPlane[p], - ctx->ProjectionMatrix.inv ); - } - } -} - void _mesa_GetClipPlane( GLenum plane, GLdouble *equation ) { diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 363793a574c..f8efa207961 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.103 2000/11/05 18:40:57 keithw Exp $ */ +/* $Id: context.c,v 1.104 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -1308,10 +1308,6 @@ init_attrib_groups( GLcontext *ctx ) ctx->Select.Hits = 0; ctx->Select.NameStackDepth = 0; - /* Optimized Accum buffer */ - ctx->IntegerAccumMode = GL_TRUE; - ctx->IntegerAccumScaler = 0.0; - /* Renderer and client attribute stacks */ ctx->AttribStackDepth = 0; ctx->ClientAttribStackDepth = 0; @@ -1336,12 +1332,11 @@ init_attrib_groups( GLcontext *ctx ) /* Miscellaneous */ ctx->NewState = _NEW_ALL; ctx->RenderMode = GL_RENDER; - ctx->_NeedNormals = GL_FALSE; ctx->_ImageTransferState = 0; - ctx->_NeedEyeCoords = GL_FALSE; - ctx->_NeedEyeNormals = GL_FALSE; - ctx->_vb_proj_matrix = &ctx->_ModelProjectMatrix; + ctx->_NeedNormals = 0; + ctx->_NeedEyeCoords = 0; + ctx->_ModelViewInvScale = 1.0; ctx->ErrorValue = (GLenum) GL_NO_ERROR; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 8505baeebd8..da6aefbdca9 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.39 2000/11/10 17:36:42 brianp Exp $ */ +/* $Id: dd.h,v 1.40 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -799,13 +799,6 @@ struct dd_function_table { * gl_render_vb() function in vbrender.c for more details. */ - void (*ReducedPrimitiveChange)( GLcontext *ctx, GLenum primitive ); - /* If registered, this will be called when rendering transitions between - * points, lines and triangles. It is not called on transitions between - * primtives such as GL_TRIANGLES and GL_TRIANGLE_STRIPS, or between - * triangles and quads or triangles and polygons. - */ - GLboolean (*MultipassFunc)( struct vertex_buffer *VB, GLuint passno ); /* Driver may request additional render passes by returning GL_TRUE * when this function is called. This function will be called @@ -819,6 +812,11 @@ struct dd_function_table { /*** *** NEW in Mesa 3.x ***/ + void (*LightingSpaceChange)( GLcontext *ctx ); + /* Notify driver that the special derived value _NeedEyeCoords has + * changed. + */ + void (*RegisterVB)( struct vertex_buffer *VB ); void (*UnregisterVB)( struct vertex_buffer *VB ); @@ -890,7 +888,7 @@ struct dd_function_table { void (*Hint)(GLcontext *ctx, GLenum target, GLenum mode); void (*IndexMask)(GLcontext *ctx, GLuint mask); void (*Lightfv)(GLcontext *ctx, GLenum light, - GLenum pname, const GLfloat *params, GLint nparams ); + GLenum pname, const GLfloat *params ); void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); void (*LineStipple)(GLcontext *ctx, GLint factor, GLushort pattern ); void (*LineWidth)(GLcontext *ctx, GLfloat width); diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 123ae89adee..e5159253e6a 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,4 +1,4 @@ -/* $Id: light.c,v 1.23 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: light.c,v 1.24 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -91,93 +91,85 @@ void _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); - GLint l; - GLint nParams; + GLint i = (GLint) (light - GL_LIGHT0); + struct gl_light *l = &ctx->Light.Light[i]; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight"); - l = (GLint) (light - GL_LIGHT0); - - if (l < 0 || l >= MAX_LIGHTS) { + if (i < 0 || i >= MAX_LIGHTS) { gl_error( ctx, GL_INVALID_ENUM, "glLight" ); return; } switch (pname) { case GL_AMBIENT: - COPY_4V( ctx->Light.Light[l].Ambient, params ); - nParams = 4; + COPY_4V( l->Ambient, params ); break; case GL_DIFFUSE: - COPY_4V( ctx->Light.Light[l].Diffuse, params ); - nParams = 4; + COPY_4V( l->Diffuse, params ); break; case GL_SPECULAR: - COPY_4V( ctx->Light.Light[l].Specular, params ); - nParams = 4; + COPY_4V( l->Specular, params ); break; case GL_POSITION: /* transform position by ModelView matrix */ - TRANSFORM_POINT( ctx->Light.Light[l].EyePosition, - ctx->ModelView.m, - params ); - nParams = 4; + TRANSFORM_POINT( l->EyePosition, ctx->ModelView.m, params ); + if (l->EyePosition[3] != 0.0F) + l->_Flags |= LIGHT_POSITIONAL; + else + l->_Flags &= ~LIGHT_POSITIONAL; break; case GL_SPOT_DIRECTION: /* transform direction by inverse modelview */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { gl_matrix_analyze( &ctx->ModelView ); } - TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection, - params, - ctx->ModelView.inv ); - nParams = 3; + TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv ); break; case GL_SPOT_EXPONENT: if (params[0]<0.0 || params[0]>128.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - if (ctx->Light.Light[l].SpotExponent != params[0]) { - ctx->Light.Light[l].SpotExponent = params[0]; - gl_compute_spot_exp_table( &ctx->Light.Light[l] ); + if (l->SpotExponent != params[0]) { + l->SpotExponent = params[0]; + gl_compute_spot_exp_table( l ); } - nParams = 1; break; case GL_SPOT_CUTOFF: if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].SpotCutoff = params[0]; - ctx->Light.Light[l]._CosCutoff = cos(params[0]*DEG2RAD); - if (ctx->Light.Light[l]._CosCutoff < 0) - ctx->Light.Light[l]._CosCutoff = 0; - nParams = 1; + l->SpotCutoff = params[0]; + l->_CosCutoff = cos(params[0]*DEG2RAD); + if (l->_CosCutoff < 0) + l->_CosCutoff = 0; + if (l->SpotCutoff != 180.0F) + l->_Flags |= LIGHT_SPOT; + else + l->_Flags &= ~LIGHT_SPOT; break; case GL_CONSTANT_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].ConstantAttenuation = params[0]; - nParams = 1; + l->ConstantAttenuation = params[0]; break; case GL_LINEAR_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].LinearAttenuation = params[0]; - nParams = 1; + l->LinearAttenuation = params[0]; break; case GL_QUADRATIC_ATTENUATION: if (params[0]<0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } - ctx->Light.Light[l].QuadraticAttenuation = params[0]; - nParams = 1; + l->QuadraticAttenuation = params[0]; break; default: gl_error( ctx, GL_INVALID_ENUM, "glLight" ); @@ -185,7 +177,7 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) } if (ctx->Driver.Lightfv) - ctx->Driver.Lightfv( ctx, light, pname, params, nParams ); + ctx->Driver.Lightfv( ctx, light, pname, params ); ctx->NewState |= _NEW_LIGHT; } @@ -612,11 +604,9 @@ void gl_update_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, src[0].Specular, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); - light->_IsMatSpecular[0] = - (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); + light->_IsMatSpecular[0] = + (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); } COPY_4FV( mat->Specular, src[0].Specular ); } @@ -625,11 +615,9 @@ void gl_update_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, src[1].Specular, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); - light->_IsMatSpecular[1] = - (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); + light->_IsMatSpecular[1] = + (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); } COPY_4FV( mat->Specular, src[1].Specular ); } @@ -771,11 +759,9 @@ void gl_update_color_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, color, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); - light->_IsMatSpecular[0] = - (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp ); + light->_IsMatSpecular[0] = + (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16); } COPY_4FV( mat->Specular, color ); } @@ -785,11 +771,9 @@ void gl_update_color_material( GLcontext *ctx, GLfloat tmp[4]; SUB_3V( tmp, color, mat->Specular ); foreach (light, list) { - if (light->_Flags & LIGHT_SPECULAR) { - ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); - light->_IsMatSpecular[1] = - (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); - } + ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp ); + light->_IsMatSpecular[1] = + (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16); } COPY_4FV( mat->Specular, color ); } @@ -1225,35 +1209,45 @@ void gl_update_lighting( GLcontext *ctx ) { struct gl_light *light; - + ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); + ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT; + ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT; ctx->Light._Flags = 0; + + if (!ctx->Light.Enabled) + return; - foreach(light, &ctx->Light.EnabledList) { - - light->_Flags = 0; + ctx->_NeedNormals |= NEED_NORMALS_LIGHT; - if (light->EyePosition[3] != 0.0F) - light->_Flags |= LIGHT_POSITIONAL; - - if (LEN_SQUARED_3FV(light->Specular) > 1e-16) - light->_Flags |= LIGHT_SPECULAR; - - if (light->SpotCutoff != 180.0F) - light->_Flags |= LIGHT_SPOT; + if (ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); + foreach(light, &ctx->Light.EnabledList) { ctx->Light._Flags |= light->_Flags; } ctx->Light._NeedVertices = ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || - (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) || - (ctx->Light.Model.LocalViewer && (ctx->Light._Flags & LIGHT_SPECULAR))); - + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || + ctx->Light.Model.LocalViewer); + + if ((ctx->Light._Flags & LIGHT_POSITIONAL) || + ctx->Light.Model.LocalViewer) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + + + /* XXX: This test is overkill & needs to be fixed both for software and + * hardware t&l drivers. The above should be sufficient & should + * be tested to verify this. + */ + if (ctx->Light._NeedVertices) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + /* Precompute some shading values. */ if (ctx->Visual.RGBAflag) { - GLuint sides = ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1); + GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1; GLuint side; for (side=0; side < sides; side++) { struct gl_material *mat = &ctx->Light.Material[side]; @@ -1272,14 +1266,10 @@ gl_update_lighting( GLcontext *ctx ) const struct gl_material *mat = &ctx->Light.Material[side]; SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse ); SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient ); - if (light->_Flags & LIGHT_SPECULAR) { - SCALE_3V( light->_MatSpecular[side], light->Specular, - mat->Specular); - light->_IsMatSpecular[side] = - (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16); - } - else - light->_IsMatSpecular[side] = 0; + SCALE_3V( light->_MatSpecular[side], light->Specular, + mat->Specular); + light->_IsMatSpecular[side] = + (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16); } } } @@ -1290,28 +1280,34 @@ gl_update_lighting( GLcontext *ctx ) light->_sli = DOT3(ci, light->Specular); } } -} + gl_update_lighting_function(ctx); +} -/* Need to seriously restrict the circumstances under which these - * calc's are performed. +/* _NEW_MODELVIEW + * _NEW_LIGHT + * _TNL_NEW_NEED_EYE_COORDS + * + * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled. + * Also update on lighting space changes. */ void gl_compute_light_positions( GLcontext *ctx ) { struct gl_light *light; - - if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) { - static const GLfloat eye_z[3] = { 0, 0, 1 }; - if (ctx->_NeedEyeCoords) { - COPY_3V( ctx->_EyeZDir, eye_z ); - } - else { - TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m ); - } - } + static const GLfloat eye_z[3] = { 0, 0, 1 }; + + if (!ctx->Light.Enabled) + return; + if (ctx->_NeedEyeCoords) { + COPY_3V( ctx->_EyeZDir, eye_z ); + } + else { + TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m ); + } + foreach (light, &ctx->Light.EnabledList) { if (ctx->_NeedEyeCoords) { @@ -1336,7 +1332,7 @@ gl_compute_light_positions( GLcontext *ctx ) } if (light->_Flags & LIGHT_SPOT) { - if (ctx->_NeedEyeNormals) { + if (ctx->_NeedEyeCoords) { COPY_3V( light->_NormDirection, light->EyeDirection ); } else { @@ -1347,9 +1343,6 @@ gl_compute_light_positions( GLcontext *ctx ) NORMALIZE_3FV( light->_NormDirection ); - - /* Unlikely occurrance? - */ if (!(light->_Flags & LIGHT_POSITIONAL)) { GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm, light->_NormDirection); @@ -1370,52 +1363,51 @@ gl_compute_light_positions( GLcontext *ctx ) } +/* _NEW_TRANSFORM + * _NEW_MODELVIEW + * _TNL_NEW_NEED_NORMALS + * _TNL_NEW_NEED_EYE_COORDS + * + * Update on (_NEW_TRANSFORM|_NEW_MODELVIEW) + * And also on NewLightingSpaces() callback. + */ void gl_update_normal_transform( GLcontext *ctx ) { - ctx->_vb_rescale_factor = 1.0; + + if (!ctx->_NeedNormals) { + ctx->_NormalTransform = 0; + return; + } if (ctx->_NeedEyeCoords) { - if (ctx->_NeedNormals) { - GLuint transform = NORM_TRANSFORM_NO_ROT; - - if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) - transform = NORM_TRANSFORM; + GLuint transform = NORM_TRANSFORM_NO_ROT; + + if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | + MAT_FLAG_ROTATION | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_PERSPECTIVE)) + transform = NORM_TRANSFORM; - ctx->_vb_rescale_factor = ctx->_rescale_factor; - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE]; - } - else if (ctx->Transform.RescaleNormals && - ctx->_rescale_factor != 1.0) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE]; - } - else { - ctx->_NormalTransform = gl_normal_tab[transform]; - } + if (ctx->Transform.Normalize) { + ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE]; + } + else if (ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE]; } else { - ctx->_NormalTransform = 0; + ctx->_NormalTransform = gl_normal_tab[transform]; } } else { - if (ctx->_NeedNormals) { - ctx->_vb_rescale_factor = 1.0/ctx->_rescale_factor; - - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE]; - } - else if (!ctx->Transform.RescaleNormals && - ctx->_rescale_factor != 1.0) { - ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE]; - } - else { - ctx->_NormalTransform = 0; - } + if (ctx->Transform.Normalize) { + ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE]; + } + else if (!ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE]; } else { ctx->_NormalTransform = 0; diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index c161e847eb3..7cf464e07bf 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -1,4 +1,4 @@ -/* $Id: matrix.c,v 1.24 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: matrix.c,v 1.25 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -930,16 +930,6 @@ static void mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags ) } -void gl_calculate_model_project_matrix( GLcontext *ctx ) -{ - gl_matrix_mul( &ctx->_ModelProjectMatrix, - &ctx->ProjectionMatrix, - &ctx->ModelView ); - - gl_matrix_analyze( &ctx->_ModelProjectMatrix ); -} - - void gl_matrix_ctr( GLmatrix *m ) { if ( m->m == 0 ) { diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 27b9d8d77da..f5923374b7e 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -1,4 +1,4 @@ -/* $Id: points.c,v 1.20 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: points.c,v 1.21 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -89,6 +89,7 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) if (tmp != ctx->Point._Attenuated) { ctx->_Enabled ^= ENABLE_POINT_ATTEN; ctx->_TriangleCaps ^= DD_POINT_ATTEN; + ctx->_NeedEyeCoords ^= NEED_EYE_POINT_ATTEN; } } break; diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index 1610b025748..e8d36a3ba00 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -1,4 +1,4 @@ -/* $Id: rastpos.c,v 1.12 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: rastpos.c,v 1.13 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -68,15 +68,10 @@ static void raster_pos4f( GLcontext *ctx, /* raster color */ if (ctx->Light.Enabled) { - /*GLfloat *vert;*/ GLfloat *norm, eyenorm[3]; GLfloat *objnorm = ctx->Current.Normal; - /* Not needed??? - vert = (ctx->_NeedEyeCoords ? eye : v); - */ - - if (ctx->_NeedEyeNormals) { + if (ctx->_NeedEyeCoords) { GLfloat *inv = ctx->ModelView.inv; TRANSFORM_NORMAL( eyenorm, objnorm, inv ); norm = eyenorm; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 1cd88a7b734..7071c0ad6fb 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,4 +1,4 @@ -/* $Id: state.c,v 1.42 2000/11/10 18:31:04 brianp Exp $ */ +/* $Id: state.c,v 1.43 2000/11/13 20:02:56 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -747,264 +747,348 @@ void gl_print_enable_flags( const char *msg, GLuint flags ) } -/* - * If ctx->NewState is non-zero then this function MUST be called before - * rendering any primitive. Basically, function pointers and miscellaneous - * flags are updated to reflect the current state of the state machine. +/* Note: This routine refers to derived texture attribute values to + * compute the ENABLE_TEXMAT flags, but is only called on + * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT + * flags are updated by _mesa_update_textures(), below. + * + * If both TEXTURE and TEXTURE_MATRIX change at once, these values + * will be computed twice. */ -void gl_update_state( GLcontext *ctx ) +static void +_mesa_update_texture_matrices( GLcontext *ctx ) { GLuint i; - if (MESA_VERBOSE & VERBOSE_STATE) - gl_print_state("", ctx->NewState); + ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2); - if (ctx->NewState & (_NEW_PIXEL|_NEW_COLOR_MATRIX)) - _mesa_update_image_transfer_state(ctx); + for (i=0; i < ctx->Const.MaxTextureUnits; i++) { + if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) { + gl_matrix_analyze( &ctx->TextureMatrix[i] ); + ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS; - if (ctx->NewState & _NEW_ARRAY) - gl_update_client_state( ctx ); + if (ctx->Texture.Unit[i]._ReallyEnabled && + ctx->TextureMatrix[i].type != MATRIX_IDENTITY) + ctx->_Enabled |= ENABLE_TEXMAT0 << i; + } + } +} - if (ctx->NewState & _NEW_TEXTURE_MATRIX) { - ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2); - for (i=0; i < ctx->Const.MaxTextureUnits; i++) { - if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) { - gl_matrix_analyze( &ctx->TextureMatrix[i] ); - ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS; +/* Note: This routine refers to derived texture matrix values to + * compute the ENABLE_TEXMAT flags, but is only called on + * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT + * flags are updated by _mesa_update_texture_matrices, above. + * + * If both TEXTURE and TEXTURE_MATRIX change at once, these values + * will be computed twice. + */ +static void +_mesa_update_textures( GLcontext *ctx ) +{ + GLuint i; + + ctx->Texture._ReallyEnabled = 0; + ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2 | + ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2 | + ENABLE_TEX0 | ENABLE_TEX1 | ENABLE_TEX2); - if (ctx->Texture.Unit[i].Enabled && - ctx->TextureMatrix[i].type != MATRIX_IDENTITY) - ctx->_Enabled |= ENABLE_TEXMAT0 << i; - } - } - } + gl_update_dirty_texobjs(ctx); - if (ctx->NewState & _NEW_TEXTURE) { - ctx->Texture._MultiTextureEnabled = GL_FALSE; - ctx->Texture._NeedNormals = GL_FALSE; - gl_update_dirty_texobjs(ctx); - ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2); - ctx->Texture._ReallyEnabled = 0; + for (i=0; i < ctx->Const.MaxTextureUnits; i++) { + + ctx->Texture.Unit[i]._ReallyEnabled = 0; - for (i=0; i < ctx->Const.MaxTextureUnits; i++) { - if (ctx->Texture.Unit[i].Enabled) { - gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] ); + if (ctx->Texture.Unit[i].Enabled) { - ctx->Texture._ReallyEnabled |= - ctx->Texture.Unit[i]._ReallyEnabled << (i * 4); + gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] ); - if (ctx->Texture.Unit[i]._GenFlags != 0) { - ctx->_Enabled |= ENABLE_TEXGEN0 << i; + if (ctx->Texture.Unit[i]._ReallyEnabled) { + GLuint flag = ctx->Texture.Unit[i]._ReallyEnabled << (i * 4); - if (ctx->Texture.Unit[i]._GenFlags & TEXGEN_NEED_NORMALS) { - ctx->Texture._NeedNormals = GL_TRUE; - ctx->Texture._NeedEyeCoords = GL_TRUE; - } + ctx->Texture._ReallyEnabled |= flag; + ctx->_Enabled |= flag; - if (ctx->Texture.Unit[i]._GenFlags & TEXGEN_NEED_EYE_COORD) { - ctx->Texture._NeedEyeCoords = GL_TRUE; - } + if (ctx->Texture.Unit[i]._GenFlags) { + ctx->_Enabled |= ENABLE_TEXGEN0 << i; + ctx->Texture._GenFlags |= ctx->Texture.Unit[i]._GenFlags; } - if (i > 0 && ctx->Texture.Unit[i]._ReallyEnabled) { - ctx->Texture._MultiTextureEnabled = GL_TRUE; - } + if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY) + ctx->_Enabled |= ENABLE_TEXMAT0 << i; } - else { - ctx->Texture.Unit[i]._ReallyEnabled = 0; - } } - ctx->_Enabled = ((ctx->_Enabled & ~ENABLE_TEX_ANY) | - ctx->Texture._ReallyEnabled); - ctx->_NeedNormals = (ctx->Light.Enabled || ctx->Texture._NeedNormals); } + ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN; + ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN; - if (ctx->NewState & (_NEW_BUFFERS|_NEW_SCISSOR)) { - /* update scissor region */ - ctx->DrawBuffer->Xmin = 0; - ctx->DrawBuffer->Ymin = 0; - ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width; - ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height; - if (ctx->Scissor.Enabled) { - if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) { - ctx->DrawBuffer->Xmin = ctx->Scissor.X; - } - if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) { - ctx->DrawBuffer->Ymin = ctx->Scissor.Y; - } - if (ctx->Scissor.X + ctx->Scissor.Width < ctx->DrawBuffer->Xmax) { - ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width; - } - if (ctx->Scissor.Y + ctx->Scissor.Height < ctx->DrawBuffer->Ymax) { - ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height; - } - } + if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) { + ctx->_NeedNormals |= NEED_NORMALS_TEXGEN; + ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; + } + + if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) { + ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; } +} - if (ctx->NewState & _NEW_LIGHT) { - ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); - if (ctx->Light.Enabled) { - if (ctx->Light.Model.TwoSide) - ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL); - gl_update_lighting(ctx); +static void +_mesa_update_polygon( GLcontext *ctx ) +{ + ctx->_TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK; + + /* Setup CullBits bitmask */ + if (ctx->Polygon.CullFlag) { + switch(ctx->Polygon.CullFaceMode) { + case GL_BACK: + ctx->Polygon._CullBits = 1; + break; + case GL_FRONT: + ctx->Polygon._CullBits = 2; + break; + default: + case GL_FRONT_AND_BACK: + ctx->Polygon._CullBits = 0; + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + break; } } + else { + ctx->Polygon._CullBits = 3; + } - if (ctx->NewState & (_NEW_POLYGON | _NEW_LIGHT)) { - - - if (ctx->NewState & _NEW_POLYGON) { - ctx->_TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK; - - /* Setup CullBits bitmask */ - if (ctx->Polygon.CullFlag) { - ctx->_backface_sign = 1; - switch(ctx->Polygon.CullFaceMode) { - case GL_BACK: - if(ctx->Polygon.FrontFace==GL_CCW) - ctx->_backface_sign = -1; - ctx->Polygon._CullBits = 1; - break; - case GL_FRONT: - if(ctx->Polygon.FrontFace!=GL_CCW) - ctx->_backface_sign = -1; - ctx->Polygon._CullBits = 2; - break; - default: - case GL_FRONT_AND_BACK: - ctx->_backface_sign = 0; - ctx->Polygon._CullBits = 0; - ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; - break; - } - } - else { - ctx->Polygon._CullBits = 3; - ctx->_backface_sign = 0; - } + /* Any Polygon offsets enabled? */ + ctx->_TriangleCaps &= ~DD_TRI_OFFSET; - /* Any Polygon offsets enabled? */ - ctx->_TriangleCaps &= ~DD_TRI_OFFSET; + if (ctx->Polygon.OffsetPoint || + ctx->Polygon.OffsetLine || + ctx->Polygon.OffsetFill) + ctx->_TriangleCaps |= DD_TRI_OFFSET; +} - if (ctx->Polygon.OffsetPoint || - ctx->Polygon.OffsetLine || - ctx->Polygon.OffsetFill) - ctx->_TriangleCaps |= DD_TRI_OFFSET; - } +static void +_mesa_calculate_model_project_matrix( GLcontext *ctx ) +{ + if (!ctx->_NeedEyeCoords) { + gl_matrix_mul( &ctx->_ModelProjectMatrix, + &ctx->ProjectionMatrix, + &ctx->ModelView ); + + gl_matrix_analyze( &ctx->_ModelProjectMatrix ); } +} - if (ctx->NewState & (_NEW_LIGHT| - _NEW_TEXTURE| - _NEW_FOG| - _NEW_POLYGON)) - gl_update_clipmask(ctx); +static void +_mesa_update_modelview_scale( GLcontext *ctx ) +{ + ctx->_ModelViewInvScale = 1.0F; + if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE | + MAT_FLAG_GENERAL_SCALE | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_GENERAL) ) { + const GLfloat *m = ctx->ModelView.inv; + GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; + if (f < 1e-12) f = 1.0; + if (ctx->_NeedEyeCoords) + ctx->_ModelViewInvScale = 1.0/GL_SQRT(f); + else + ctx->_ModelViewInvScale = GL_SQRT(f); + } +} - if (ctx->NewState & ctx->Driver.UpdateStateNotify) + +/* Bring uptodate any state that relies on _NeedEyeCoords. + */ +static void +_mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords ) +{ + /* Check if the truth-value interpretations of the bitfields have + * changed: + */ + if ((oldneedeyecoords == 0) != (ctx->_NeedEyeCoords == 0)) { - /* - * Here the driver sets up all the ctx->Driver function pointers to - * it's specific, private functions. + /* Recalculate all state that depends on _NeedEyeCoords. */ - ctx->Driver.UpdateState(ctx); - gl_set_render_vb_function(ctx); /* fix me */ + _mesa_update_modelview_scale(ctx); + _mesa_calculate_model_project_matrix(ctx); + gl_update_normal_transform( ctx ); + gl_compute_light_positions( ctx ); + + if (ctx->Driver.LightingSpaceChange) + ctx->Driver.LightingSpaceChange( ctx ); } + else + { + GLuint new_state = ctx->NewState; - /* Should only be calc'd when !need_eye_coords and not culling. - */ - if (ctx->NewState & (_NEW_MODELVIEW|_NEW_PROJECTION)) { - if (ctx->NewState & _NEW_MODELVIEW) { - gl_matrix_analyze( &ctx->ModelView ); - ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS; + /* Recalculate that same state if and only if it has been + * invalidated by other statechanges. + */ + if (new_state & _NEW_MODELVIEW) + _mesa_update_modelview_scale(ctx); + + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) + _mesa_calculate_model_project_matrix(ctx); + + if (new_state & _TNL_NEW_NORMAL_TRANSFORM) + gl_update_normal_transform( ctx ); /* references _ModelViewInvScale */ + + if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW)) + gl_compute_light_positions( ctx ); + } +} + + +static void +_mesa_update_drawbuffer( GLcontext *ctx ) +{ + ctx->DrawBuffer->_Xmin = 0; + ctx->DrawBuffer->_Ymin = 0; + ctx->DrawBuffer->_Xmax = ctx->DrawBuffer->Width; + ctx->DrawBuffer->_Ymax = ctx->DrawBuffer->Height; + if (ctx->Scissor.Enabled) { + if (ctx->Scissor.X > ctx->DrawBuffer->_Xmin) { + ctx->DrawBuffer->_Xmin = ctx->Scissor.X; + } + if (ctx->Scissor.Y > ctx->DrawBuffer->_Ymin) { + ctx->DrawBuffer->_Ymin = ctx->Scissor.Y; + } + if (ctx->Scissor.X + ctx->Scissor.Width < ctx->DrawBuffer->_Xmax) { + ctx->DrawBuffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width; } + if (ctx->Scissor.Y + ctx->Scissor.Height < ctx->DrawBuffer->_Ymax) { + ctx->DrawBuffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height; + } + } +} - if (ctx->NewState & _NEW_PROJECTION) { - gl_matrix_analyze( &ctx->ProjectionMatrix ); - ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS; - if (ctx->Transform._AnyClip) { - gl_update_userclip( ctx ); +/* NOTE: This routine references Tranform attribute values to compute + * userclip positions in clip space, but is only called on + * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values + * uptodate across changes to the Transform attributes. + */ +static void +_mesa_update_projection( GLcontext *ctx ) +{ + gl_matrix_analyze( &ctx->ProjectionMatrix ); + + /* Recompute clip plane positions in clipspace. This is also done + * in _mesa_ClipPlane(). + */ + if (ctx->Transform._AnyClip) { + GLuint p; + for (p = 0 ; p < MAX_CLIP_PLANES ; p++) { + if (ctx->Transform.ClipEnabled[p]) { + gl_transform_vector( ctx->Transform._ClipUserPlane[p], + ctx->Transform.EyeUserPlane[p], + ctx->ProjectionMatrix.inv ); } } - - gl_calculate_model_project_matrix( ctx ); } +} + + + + +/* + * If ctx->NewState is non-zero then this function MUST be called before + * rendering any primitive. Basically, function pointers and miscellaneous + * flags are updated to reflect the current state of the state machine. + * + * Special care is taken with the derived value _NeedEyeCoords. These + * is a bitflag which is updated with information from a number of + * attribute groups (MODELVIEW, LIGHT, TEXTURE). A lot of derived + * state references this value, and must be treated with care to + * ensure that updates are done correctly. All state dependent on + * _NeedEyeCoords is calculated from within _mesa_update_tnl_spaces(), + * and from nowhere else. + */ +void gl_update_state( GLcontext *ctx ) +{ + GLuint new_state = ctx->NewState; + GLuint oldneedeyecoords = ctx->_NeedEyeCoords; + + if (MESA_VERBOSE & VERBOSE_STATE) + gl_print_state("", new_state); + + if (new_state & _NEW_MODELVIEW) + gl_matrix_analyze( &ctx->ModelView ); + + if (new_state & _NEW_PROJECTION) + _mesa_update_projection( ctx ); - if (ctx->NewState & _NEW_COLOR_MATRIX) { + if (new_state & _NEW_TEXTURE_MATRIX) + _mesa_update_texture_matrices( ctx ); + + if (new_state & _NEW_COLOR_MATRIX) gl_matrix_analyze( &ctx->ColorMatrix ); - } + + /* References ColorMatrix.type (derived above). + */ + if (new_state & (_NEW_PIXEL|_NEW_COLOR_MATRIX)) + _mesa_update_image_transfer_state(ctx); + + if (new_state & _NEW_ARRAY) + gl_update_client_state( ctx ); - /* Figure out whether we can light in object space or not. If we - * can, find the current positions of the lights in object space + /* Contributes to NeedEyeCoords, NeedNormals. */ - if ((ctx->_Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG | - ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2)) && - (ctx->NewState & (_NEW_LIGHT | - _NEW_TEXTURE | - _NEW_FOG | - _NEW_TRANSFORM | - _NEW_MODELVIEW | - _NEW_PROJECTION | - _NEW_POINT | - _NEW_RENDERMODE | - _NEW_TRANSFORM))) - { - GLboolean oldcoord, oldnorm; - - oldcoord = ctx->_NeedEyeCoords; - oldnorm = ctx->_NeedEyeNormals; - - ctx->_NeedNormals = (ctx->Light.Enabled || ctx->Texture._NeedNormals); - ctx->_NeedEyeCoords = (ctx->Fog.Enabled || ctx->Point._Attenuated); - ctx->_NeedEyeNormals = GL_FALSE; - - if (ctx->Light.Enabled) { - if ((ctx->Light._Flags & LIGHT_POSITIONAL) || - ctx->Light._NeedVertices || - !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING)) { - /* Need length for attenuation or need angle for spotlights - * or non-uniform scale matrix - */ - ctx->_NeedEyeCoords = GL_TRUE; - } - ctx->_NeedEyeNormals = ctx->_NeedEyeCoords; - } - if (ctx->Texture._ReallyEnabled || ctx->RenderMode==GL_FEEDBACK) { - if (ctx->Texture._NeedEyeCoords) ctx->_NeedEyeCoords = GL_TRUE; - if (ctx->Texture._NeedNormals) - ctx->_NeedNormals = ctx->_NeedEyeNormals = GL_TRUE; - } + if (new_state & _NEW_TEXTURE) + _mesa_update_textures( ctx ); - if (ctx->_NeedEyeCoords) - ctx->_vb_proj_matrix = &ctx->ProjectionMatrix; - else - ctx->_vb_proj_matrix = &ctx->_ModelProjectMatrix; + if (new_state & (_NEW_BUFFERS|_NEW_SCISSOR)) + _mesa_update_drawbuffer( ctx ); - if (ctx->Light.Enabled) { - gl_update_lighting_function(ctx); + if (new_state & _NEW_POLYGON) + _mesa_update_polygon( ctx ); - if ( (ctx->NewState & _NEW_LIGHT) || - ((ctx->NewState & (_NEW_MODELVIEW|_NEW_PROJECTION)) && - !ctx->_NeedEyeCoords) || - oldcoord != ctx->_NeedEyeCoords || - oldnorm != ctx->_NeedEyeNormals) { - gl_compute_light_positions(ctx); - } + /* Contributes to NeedEyeCoords, NeedNormals. + */ + if (new_state & _NEW_LIGHT) + gl_update_lighting( ctx ); - ctx->_rescale_factor = 1.0F; - if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE | - MAT_FLAG_GENERAL_SCALE | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_GENERAL) ) { - const GLfloat *m = ctx->ModelView.inv; - const GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; - if (f > 1e-12 && (f - 1.0) * (f - 1.0) > 1e-12) - ctx->_rescale_factor = 1.0 / GL_SQRT(f); - } - } + if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG| + _DD_NEW_TRI_LIGHT_TWOSIDE | + _DD_NEW_SEPERATE_SPECULAR | + _DD_NEW_TRI_UNFILLED )) + gl_update_clipmask(ctx); + + /* We can light in object space if the modelview matrix preserves + * lengths and relative angles. + */ + if (new_state & (_NEW_MODELVIEW|_NEW_LIGHT)) { + ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT_MODELVIEW; + if (ctx->Light.Enabled && + !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING)) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT_MODELVIEW; + } - gl_update_normal_transform( ctx ); + /* ctx->_NeedEyeCoords and ctx->_NeedEyeNormals are now uptodate. + * + * If the truth value of either has changed, update for the new + * lighting space and recompute the positions of lights and the + * normal transform. + * + * If the lighting space hasn't changed, may still need to recompute + * light positions & normal transforms for other reasons. + */ + if (new_state & (_NEW_MODELVIEW | + _NEW_PROJECTION | + _TNL_NEW_NORMAL_TRANSFORM | + _NEW_LIGHT | + _TNL_NEW_NEED_EYE_COORDS)) + _mesa_update_tnl_spaces( ctx, oldneedeyecoords ); + + if (new_state & ctx->Driver.UpdateStateNotify) + { + /* + * Here the driver sets up all the ctx->Driver function pointers to + * it's specific, private functions. + */ + ctx->Driver.UpdateState(ctx); + gl_set_render_vb_function(ctx); /* XXX: remove this mechanism */ } gl_update_pipelines(ctx); diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c index 377e6072c72..48bb2f61094 100644 --- a/src/mesa/swrast/s_aaline.c +++ b/src/mesa/swrast/s_aaline.c @@ -1,4 +1,4 @@ -/* $Id: s_aaline.c,v 1.1 2000/11/05 23:15:16 brianp Exp $ */ +/* $Id: s_aaline.c,v 1.2 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -489,7 +489,7 @@ _swrast_choose_aa_line_function(GLcontext *ctx) if (ctx->Visual.RGBAflag) { /* RGBA */ if (ctx->Texture._ReallyEnabled) { - if (ctx->Texture._MultiTextureEnabled + if (swrast->_MultiTextureEnabled || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled) /* Multitextured! */ diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c index c8f321c0c60..a261f5dc826 100644 --- a/src/mesa/swrast/s_aatriangle.c +++ b/src/mesa/swrast/s_aatriangle.c @@ -1,4 +1,4 @@ -/* $Id: s_aatriangle.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_aatriangle.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -400,13 +400,14 @@ spec_multitex_aa_tri(GLcontext *ctx, void _mesa_set_aa_triangle_function(GLcontext *ctx) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); ASSERT(ctx->Polygon.SmoothFlag); if (ctx->Texture._ReallyEnabled) { if (ctx->Light.Enabled && (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled)) { - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri; } else { @@ -414,7 +415,7 @@ _mesa_set_aa_triangle_function(GLcontext *ctx) } } else { - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri; } else { diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index bc4fe744976..ccece6cab80 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_aatritemp.h,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_aatritemp.h,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -86,7 +86,7 @@ GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH]; GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH]; #endif - GLfloat bf = ctx->_backface_sign; + GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign; /* determine bottom to top order of vertices */ { diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c index ff12c530503..dd47e198abc 100644 --- a/src/mesa/swrast/s_accum.c +++ b/src/mesa/swrast/s_accum.c @@ -1,4 +1,4 @@ -/* $Id: s_accum.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_accum.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -68,6 +68,7 @@ void _mesa_alloc_accum_buffer( GLcontext *ctx ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint n; if (ctx->DrawBuffer->Accum) { @@ -83,11 +84,11 @@ _mesa_alloc_accum_buffer( GLcontext *ctx ) gl_error( ctx, GL_OUT_OF_MEMORY, "glAccum" ); } #ifdef USE_OPTIMIZED_ACCUM - ctx->IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumMode = GL_TRUE; #else - ctx->IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; #endif - ctx->IntegerAccumScaler = 0.0; + swrast->_IntegerAccumScaler = 0.0; } @@ -102,20 +103,21 @@ _mesa_alloc_accum_buffer( GLcontext *ctx ) */ static void rescale_accum( GLcontext *ctx ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4; const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1; - const GLfloat s = ctx->IntegerAccumScaler * (32767.0 / fChanMax); + const GLfloat s = swrast->_IntegerAccumScaler * (32767.0 / fChanMax); GLaccum *accum = ctx->DrawBuffer->Accum; GLuint i; - assert(ctx->IntegerAccumMode); + assert(swrast->_IntegerAccumMode); assert(accum); for (i = 0; i < n; i++) { accum[i] = (GLaccum) (accum[i] * s); } - ctx->IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; } @@ -129,6 +131,7 @@ static void rescale_accum( GLcontext *ctx ) void _mesa_clear_accum_buffer( GLcontext *ctx ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint buffersize; GLfloat acc_scale; @@ -169,12 +172,12 @@ _mesa_clear_accum_buffer( GLcontext *ctx ) b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale); a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale); /* size of region to clear */ - width = 4 * (ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin); - height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; + width = 4 * (ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin); + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; /* ptr to first element to clear */ row = ctx->DrawBuffer->Accum - + 4 * (ctx->DrawBuffer->Ymin * ctx->DrawBuffer->Width - + ctx->DrawBuffer->Xmin); + + 4 * (ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width + + ctx->DrawBuffer->_Xmin); for (j=0;j<height;j++) { for (i=0;i<width;i+=4) { row[i+0] = r; @@ -217,14 +220,14 @@ _mesa_clear_accum_buffer( GLcontext *ctx ) if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 && ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) { #ifdef USE_OPTIMIZED_ACCUM - ctx->IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumMode = GL_TRUE; #else - ctx->IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; #endif - ctx->IntegerAccumScaler = 0.0; /* denotes empty accum buffer */ + swrast->_IntegerAccumScaler = 0.0; /* denotes empty accum buffer */ } else { - ctx->IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; } } } @@ -236,6 +239,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, GLint width, GLint height ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint width4; GLfloat acc_scale; GLchan rgba[MAX_WIDTH][4]; @@ -273,7 +277,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, const GLaccum intVal = (GLaccum) (value * acc_scale); GLuint j; /* Leave optimized accum buffer mode */ - if (ctx->IntegerAccumMode) + if (swrast->_IntegerAccumMode) rescale_accum(ctx); for (j = 0; j < height; j++) { GLaccum * acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos; @@ -290,7 +294,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, if (value != 1.0F) { GLuint j; /* Leave optimized accum buffer mode */ - if (ctx->IntegerAccumMode) + if (swrast->_IntegerAccumMode) rescale_accum(ctx); for (j = 0; j < height; j++) { GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos; @@ -311,19 +315,19 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, ctx->Pixel.DriverReadBuffer ); /* May have to leave optimized accum buffer mode */ - if (ctx->IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0) - ctx->IntegerAccumScaler = value; - if (ctx->IntegerAccumMode && value != ctx->IntegerAccumScaler) + if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0) + swrast->_IntegerAccumScaler = value; + if (swrast->_IntegerAccumMode && value != swrast->_IntegerAccumScaler) rescale_accum(ctx); RENDER_START(ctx); - if (ctx->IntegerAccumMode) { + if (swrast->_IntegerAccumMode) { /* simply add integer color values into accum buffer */ GLuint j; GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; - assert(ctx->IntegerAccumScaler > 0.0); - assert(ctx->IntegerAccumScaler <= 1.0); + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); for (j = 0; j < height; j++) { GLuint i, i4; @@ -371,24 +375,24 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, /* This is a change to go into optimized accum buffer mode */ if (value > 0.0 && value <= 1.0) { #ifdef USE_OPTIMIZED_ACCUM - ctx->IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumMode = GL_TRUE; #else - ctx->IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; #endif - ctx->IntegerAccumScaler = value; + swrast->_IntegerAccumScaler = value; } else { - ctx->IntegerAccumMode = GL_FALSE; - ctx->IntegerAccumScaler = 0.0; + swrast->_IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumScaler = 0.0; } RENDER_START(ctx); - if (ctx->IntegerAccumMode) { + if (swrast->_IntegerAccumMode) { /* just copy values into accum buffer */ GLuint j; GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; - assert(ctx->IntegerAccumScaler > 0.0); - assert(ctx->IntegerAccumScaler <= 1.0); + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); for (j = 0; j < height; j++) { GLuint i, i4; gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); @@ -431,15 +435,15 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, case GL_RETURN: /* May have to leave optimized accum buffer mode */ - if (ctx->IntegerAccumMode && value != 1.0) + if (swrast->_IntegerAccumMode && value != 1.0) rescale_accum(ctx); RENDER_START(ctx); - if (ctx->IntegerAccumMode && ctx->IntegerAccumScaler > 0) { + if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) { /* build lookup table to avoid many floating point multiplies */ static GLchan multTable[32768]; static GLfloat prevMult = 0.0; - const GLfloat mult = ctx->IntegerAccumScaler; + const GLfloat mult = swrast->_IntegerAccumScaler; const GLint max = MIN2((GLint) (256 / mult), 32767); GLuint j; if (mult != prevMult) { @@ -448,8 +452,8 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, prevMult = mult; } - assert(ctx->IntegerAccumScaler > 0.0); - assert(ctx->IntegerAccumScaler <= 1.0); + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); for (j = 0; j < height; j++) { const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4; GLuint i, i4; diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c index 07e8dacd4ab..6440ffb18fa 100644 --- a/src/mesa/swrast/s_alpha.c +++ b/src/mesa/swrast/s_alpha.c @@ -1,4 +1,4 @@ -/* $Id: s_alpha.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */ +/* $Id: s_alpha.c,v 1.2 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -60,9 +60,8 @@ _mesa_alpha_test( const GLcontext *ctx, } return 1; case GL_LEQUAL: - for (i=0;i<n;i++) { + for (i=0;i<n;i++) mask[i] &= (rgba[i][ACOMP] <= ref); - } return 1; case GL_GEQUAL: for (i=0;i<n;i++) { diff --git a/src/mesa/swrast/s_alphabuf.c b/src/mesa/swrast/s_alphabuf.c index ed7b9cbded1..11b782e7879 100644 --- a/src/mesa/swrast/s_alphabuf.c +++ b/src/mesa/swrast/s_alphabuf.c @@ -161,11 +161,11 @@ _mesa_clear_alpha_buffers( GLcontext *ctx ) if (ctx->Scissor.Enabled) { /* clear scissor region */ GLint j; - GLint rowLen = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin + 1; - GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1; + GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin + 1; + GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin + 1; GLchan *aptr = buffer - + ctx->DrawBuffer->Ymin * ctx->DrawBuffer->Width - + ctx->DrawBuffer->Xmin; + + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width + + ctx->DrawBuffer->_Xmin; for (j = 0; j < rows; j++) { #if CHAN_BITS == 8 MEMSET( aptr, aclear, rowLen ); diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index b62198f091e..c0564e0b6a5 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -1,4 +1,4 @@ -/* $Id: s_buffers.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */ +/* $Id: s_buffers.c,v 1.2 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -44,10 +44,10 @@ static void clear_color_buffer_with_masking( GLcontext *ctx ) { - const GLint x = ctx->DrawBuffer->Xmin; - const GLint y = ctx->DrawBuffer->Ymin; - const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; - const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Visual.RGBAflag) { /* RGBA mode */ @@ -94,10 +94,10 @@ clear_color_buffer_with_masking( GLcontext *ctx ) static void clear_color_buffer(GLcontext *ctx) { - const GLint x = ctx->DrawBuffer->Xmin; - const GLint y = ctx->DrawBuffer->Ymin; - const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; - const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Visual.RGBAflag) { /* RGBA mode */ diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index ca6b05c4869..f1dfef3cc4c 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -1,4 +1,4 @@ -/* $Id: s_context.c,v 1.3 2000/11/10 17:45:16 brianp Exp $ */ +/* $Id: s_context.c,v 1.4 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -114,6 +114,44 @@ _swrast_update_rasterflags( GLcontext *ctx ) } +static void +_swrast_update_polygon( GLcontext *ctx ) +{ + GLfloat backface_sign = 1; + + if (ctx->Polygon.CullFlag) { + backface_sign = 1; + switch(ctx->Polygon.CullFaceMode) { + case GL_BACK: + if(ctx->Polygon.FrontFace==GL_CCW) + backface_sign = -1; + break; + case GL_FRONT: + if(ctx->Polygon.FrontFace!=GL_CCW) + backface_sign = -1; + break; + default: + case GL_FRONT_AND_BACK: + backface_sign = 0; + break; + } + } + else { + backface_sign = 0; + } + + SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; +} + + +static void +_swrast_update_hint( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + swrast->_PreferPixelFog = (!swrast->AllowVertexFog || + (ctx->Hint.Fog == GL_NICEST && + swrast->AllowPixelFog)); +} #define _SWRAST_NEW_TRIANGLE (_NEW_RENDERMODE| \ _NEW_POLYGON| \ @@ -282,7 +320,17 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState) { if (swrast->NewState & _SWRAST_NEW_RASTERMASK) - _swrast_update_rasterflags( ctx ); + _swrast_update_rasterflags( ctx ); + + if (swrast->NewState & _NEW_TEXTURE) + swrast->_MultiTextureEnabled = (ctx->Texture._ReallyEnabled & + ~ENABLE_TEX0); + + if (swrast->NewState & _NEW_POLYGON) + _swrast_update_polygon( ctx ); + + if (swrast->NewState & _NEW_HINT) + _swrast_update_hint( ctx ); swrast->NewState = 0; swrast->StateChanges = 0; @@ -332,6 +380,20 @@ _swrast_get_stipple_counter_ref( GLcontext *ctx ) return &SWRAST_CONTEXT(ctx)->StippleCounter; } +void +_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) +{ + SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); + SWRAST_CONTEXT(ctx)->AllowVertexFog = value; +} + +void +_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) +{ + SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); + SWRAST_CONTEXT(ctx)->AllowPixelFog = value; +} + GLboolean _swrast_CreateContext( GLcontext *ctx ) @@ -366,6 +428,14 @@ _swrast_CreateContext( GLcontext *ctx ) swrast->InvalidateState = _swrast_sleep; swrast->BlendFunc = _swrast_validate_blend_func; + swrast->AllowVertexFog = GL_TRUE; + swrast->AllowPixelFog = GL_TRUE; + + /* Optimized Accum buffer */ + swrast->_IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumScaler = 0.0; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) swrast->TextureSample[i] = _swrast_validate_texture_sample; diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 493758ad695..10e162b7056 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -93,16 +93,34 @@ typedef void (*swrast_point_func)( GLcontext *ctx, SWvertex *); typedef struct { - GLuint NewState; - GLuint StateChanges; + /* Configuration mechanisms to make software rasterizer match + * characteristics of the hardware rasterizer (if present): + */ + GLboolean AllowVertexFog; + GLboolean AllowPixelFog; + /* Derived values, invalidated on statechanges, updated from + * _swrast_validate_derived(): + */ GLuint _RasterMask; + GLboolean _MultiTextureEnabled; GLuint _MinMagThresh[MAX_TEXTURE_UNITS]; + GLfloat _backface_sign; + GLboolean _PreferPixelFog; + + /* Accum buffer temporaries. + */ + GLboolean _IntegerAccumMode; /* Storing unscaled integers? */ + GLfloat _IntegerAccumScaler; /* Implicit scale factor */ + + /* Working values: + */ struct pixel_buffer* PB; GLuint StippleCounter; /* Line stipple counter */ - - + GLuint NewState; + GLuint StateChanges; + /* Mechanism to allow driver (like X11) to register further * software rasterization routines. */ diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 3186f8ea27c..1199f67dd88 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1,4 +1,4 @@ -/* $Id: s_depth.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_depth.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -1538,10 +1538,10 @@ _mesa_clear_depth_buffer( GLcontext *ctx ) /* only clear scissor region */ if (ctx->Visual.DepthBits <= 16) { const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax); - const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; + const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->Width; GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin; + + ctx->DrawBuffer->_Ymin * width + ctx->DrawBuffer->_Xmin; GLint i, j; for (i = 0; i < rows; i++) { for (j = 0; j < width; j++) { @@ -1552,10 +1552,10 @@ _mesa_clear_depth_buffer( GLcontext *ctx ) } else { const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax); - const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; + const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->Width; GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin; + + ctx->DrawBuffer->_Ymin * width + ctx->DrawBuffer->_Xmin; GLint i, j; for (i = 0; i < rows; i++) { for (j = 0; j < width; j++) { diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index d646bd4b28e..dc15e598f57 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -1,4 +1,4 @@ -/* $Id: s_drawpix.c,v 1.3 2000/11/10 17:45:16 brianp Exp $ */ +/* $Id: s_drawpix.c,v 1.4 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -61,27 +61,27 @@ _mesa_clip_pixelrect(const GLcontext *ctx, const GLframebuffer *buffer = ctx->DrawBuffer; /* left clipping */ - if (*destX < buffer->Xmin) { - *skipPixels += (buffer->Xmin - *destX); - *width -= (buffer->Xmin - *destX); - *destX = buffer->Xmin; + if (*destX < buffer->_Xmin) { + *skipPixels += (buffer->_Xmin - *destX); + *width -= (buffer->_Xmin - *destX); + *destX = buffer->_Xmin; } /* right clipping */ - if (*destX + *width > buffer->Xmax) - *width -= (*destX + *width - buffer->Xmax); + if (*destX + *width > buffer->_Xmax) + *width -= (*destX + *width - buffer->_Xmax); if (*width <= 0) return GL_FALSE; /* bottom clipping */ - if (*destY < buffer->Ymin) { - *skipRows += (buffer->Ymin - *destY); - *height -= (buffer->Ymin - *destY); - *destY = buffer->Ymin; + if (*destY < buffer->_Ymin) { + *skipRows += (buffer->_Ymin - *destY); + *height -= (buffer->_Ymin - *destY); + *destY = buffer->_Ymin; } /* top clipping */ - if (*destY + *height > buffer->Ymax) - *height -= (*destY + *height - buffer->Ymax); + if (*destY + *height > buffer->_Ymax) + *height -= (*destY + *height - buffer->_Ymax); if (*height <= 0) return GL_TRUE; @@ -139,48 +139,48 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, */ if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { /* horizontal clipping */ - if (destX < ctx->DrawBuffer->Xmin) { - skipPixels += (ctx->DrawBuffer->Xmin - destX); - drawWidth -= (ctx->DrawBuffer->Xmin - destX); - destX = ctx->DrawBuffer->Xmin; + if (destX < ctx->DrawBuffer->_Xmin) { + skipPixels += (ctx->DrawBuffer->_Xmin - destX); + drawWidth -= (ctx->DrawBuffer->_Xmin - destX); + destX = ctx->DrawBuffer->_Xmin; } - if (destX + drawWidth > ctx->DrawBuffer->Xmax) - drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax); + if (destX + drawWidth > ctx->DrawBuffer->_Xmax) + drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax); if (drawWidth <= 0) return GL_TRUE; /* vertical clipping */ - if (destY < ctx->DrawBuffer->Ymin) { - skipRows += (ctx->DrawBuffer->Ymin - destY); - drawHeight -= (ctx->DrawBuffer->Ymin - destY); - destY = ctx->DrawBuffer->Ymin; + if (destY < ctx->DrawBuffer->_Ymin) { + skipRows += (ctx->DrawBuffer->_Ymin - destY); + drawHeight -= (ctx->DrawBuffer->_Ymin - destY); + destY = ctx->DrawBuffer->_Ymin; } - if (destY + drawHeight > ctx->DrawBuffer->Ymax) - drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax); + if (destY + drawHeight > ctx->DrawBuffer->_Ymax) + drawHeight -= (destY + drawHeight - ctx->DrawBuffer->_Ymax); if (drawHeight <= 0) return GL_TRUE; } else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { /* upside-down image */ /* horizontal clipping */ - if (destX < ctx->DrawBuffer->Xmin) { - skipPixels += (ctx->DrawBuffer->Xmin - destX); - drawWidth -= (ctx->DrawBuffer->Xmin - destX); - destX = ctx->DrawBuffer->Xmin; + if (destX < ctx->DrawBuffer->_Xmin) { + skipPixels += (ctx->DrawBuffer->_Xmin - destX); + drawWidth -= (ctx->DrawBuffer->_Xmin - destX); + destX = ctx->DrawBuffer->_Xmin; } - if (destX + drawWidth > ctx->DrawBuffer->Xmax) - drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax); + if (destX + drawWidth > ctx->DrawBuffer->_Xmax) + drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax); if (drawWidth <= 0) return GL_TRUE; /* vertical clipping */ - if (destY > ctx->DrawBuffer->Ymax) { - skipRows += (destY - ctx->DrawBuffer->Ymax); - drawHeight -= (destY - ctx->DrawBuffer->Ymax); - destY = ctx->DrawBuffer->Ymax; + if (destY > ctx->DrawBuffer->_Ymax) { + skipRows += (destY - ctx->DrawBuffer->_Ymax); + drawHeight -= (destY - ctx->DrawBuffer->_Ymax); + destY = ctx->DrawBuffer->_Ymax; } - if (destY - drawHeight < ctx->DrawBuffer->Ymin) - drawHeight -= (ctx->DrawBuffer->Ymin - (destY - drawHeight)); + if (destY - drawHeight < ctx->DrawBuffer->_Ymin) + drawHeight -= (ctx->DrawBuffer->_Ymin - (destY - drawHeight)); if (drawHeight <= 0) return GL_TRUE; } diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 501f3721c60..e14c6a8e217 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -1,4 +1,4 @@ -/* $Id: s_feedback.c,v 1.1 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_feedback.c,v 1.2 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -46,7 +46,7 @@ -static void feedback_vertex( GLcontext *ctx, SWvertex *v ) +static void feedback_vertex( GLcontext *ctx, SWvertex *v, SWvertex *pv ) { GLfloat win[4]; GLfloat color[4]; @@ -59,10 +59,10 @@ static void feedback_vertex( GLcontext *ctx, SWvertex *v ) win[2] = v->win[2] / ctx->Visual.DepthMaxF; win[3] = 1.0 / v->win[3]; - color[0] = CHAN_TO_FLOAT(v->color[0]); - color[1] = CHAN_TO_FLOAT(v->color[1]); - color[2] = CHAN_TO_FLOAT(v->color[2]); - color[3] = CHAN_TO_FLOAT(v->color[3]); + color[0] = CHAN_TO_FLOAT(pv->color[0]); + color[1] = CHAN_TO_FLOAT(pv->color[1]); + color[2] = CHAN_TO_FLOAT(pv->color[2]); + color[3] = CHAN_TO_FLOAT(pv->color[3]); if (v->texcoord[texUnit][3] != 1.0 && v->texcoord[texUnit][3] != 0.0) { @@ -92,9 +92,15 @@ void gl_feedback_triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN ); FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */ - feedback_vertex( ctx, v0 ); - feedback_vertex( ctx, v1 ); - feedback_vertex( ctx, v2 ); + if (ctx->Light.ShadeModel == GL_SMOOTH) { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v1 ); + feedback_vertex( ctx, v2, v2 ); + } else { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v0 ); + feedback_vertex( ctx, v2, v0 ); + } } } @@ -109,8 +115,13 @@ void gl_feedback_line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 ) FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token ); - feedback_vertex( ctx, v0 ); - feedback_vertex( ctx, v1 ); + if (ctx->Light.ShadeModel == GL_SMOOTH) { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v1 ); + } else { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v0 ); + } swrast->StippleCounter++; } @@ -119,7 +130,7 @@ void gl_feedback_line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 ) void gl_feedback_point( GLcontext *ctx, SWvertex *v ) { FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN ); - feedback_vertex( ctx, v ); + feedback_vertex( ctx, v, v ); } @@ -128,6 +139,7 @@ void gl_select_triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, { if (gl_cull_triangle( ctx, v0, v1, v2 )) { const GLfloat zs = 1.0F / ctx->Visual.DepthMaxF; + gl_update_hitflag( ctx, v0->win[2] * zs ); gl_update_hitflag( ctx, v1->win[2] * zs ); gl_update_hitflag( ctx, v2->win[2] * zs ); diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index c25a3851759..e460a77f181 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -1,4 +1,4 @@ -/* $Id: s_lines.c,v 1.4 2000/11/10 17:45:16 brianp Exp $ */ +/* $Id: s_lines.c,v 1.5 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -979,7 +979,7 @@ _swrast_choose_line( GLcontext *ctx ) ASSERT(swrast->Triangle); } else if (ctx->Texture._ReallyEnabled) { - if (ctx->Texture._MultiTextureEnabled + if (swrast->_MultiTextureEnabled || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled) { /* multi-texture and/or separate specular color */ diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 59fadfb8e92..e5360dff7d2 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -1,4 +1,4 @@ -/* $Id: s_points.c,v 1.3 2000/11/10 17:45:16 brianp Exp $ */ +/* $Id: s_points.c,v 1.4 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -362,7 +362,8 @@ multitextured_rgba_point( GLcontext *ctx, SWvertex *vert ) static void antialiased_rgba_point( GLcontext *ctx, SWvertex *vert ) { - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *PB = swrast->PB; const GLfloat radius = ctx->Point.Size * 0.5F; const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ const GLfloat rmax = radius + 0.7071F; @@ -421,7 +422,7 @@ antialiased_rgba_point( GLcontext *ctx, SWvertex *vert ) /* coverage is in [0,256] */ alpha = (alpha * coverage) >> 8; } - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, fog, red, green, blue, alpha, texcoord ); @@ -614,7 +615,8 @@ dist_atten_general_rgba_point( GLcontext *ctx, SWvertex *vert ) static void dist_atten_textured_rgba_point( GLcontext *ctx, SWvertex *vert ) { - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *PB = swrast->PB; const GLfloat psize = ctx->Point.Size; GLfloat dist = attenuation_distance( ctx, vert->eye ); @@ -683,7 +685,7 @@ dist_atten_textured_rgba_point( GLcontext *ctx, SWvertex *vert ) for (iy = y0; iy <= y1; iy++) { for (ix = x0; ix <= x1; ix++) { - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, fog, red, green, blue, alpha, texcoord ); @@ -706,7 +708,8 @@ dist_atten_textured_rgba_point( GLcontext *ctx, SWvertex *vert ) static void dist_atten_antialiased_rgba_point( GLcontext *ctx, SWvertex *vert ) { - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *PB = swrast->PB; const GLfloat psize = ctx->Point.Size; GLfloat dist = attenuation_distance( ctx, vert->eye ); @@ -775,7 +778,7 @@ dist_atten_antialiased_rgba_point( GLcontext *ctx, SWvertex *vert ) alpha = (alpha * coverage) >> 8; } alpha = (GLint) (alpha * alphaf); - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { PB_WRITE_MULTITEX_PIXEL( PB, x, y, z, fog, red, green, blue, alpha, texcoord ); @@ -906,7 +909,7 @@ _swrast_choose_point( GLcontext *ctx ) swrast->Point = antialiased_rgba_point; } else if (ctx->Texture._ReallyEnabled) { - if (ctx->Texture._MultiTextureEnabled || + if (swrast->_MultiTextureEnabled || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled) { swrast->Point = multitextured_rgba_point; diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index ba3aca53927..ac91dadcf3a 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -1,4 +1,4 @@ -/* $Id: s_readpix.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_readpix.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -520,24 +520,24 @@ read_fast_rgba_pixels( GLcontext *ctx, rowLength = width; /* horizontal clipping */ - if (srcX < ctx->ReadBuffer->Xmin) { - skipPixels += (ctx->ReadBuffer->Xmin - srcX); - readWidth -= (ctx->ReadBuffer->Xmin - srcX); - srcX = ctx->ReadBuffer->Xmin; + if (srcX < ctx->ReadBuffer->_Xmin) { + skipPixels += (ctx->ReadBuffer->_Xmin - srcX); + readWidth -= (ctx->ReadBuffer->_Xmin - srcX); + srcX = ctx->ReadBuffer->_Xmin; } - if (srcX + readWidth > ctx->ReadBuffer->Xmax) - readWidth -= (srcX + readWidth - ctx->ReadBuffer->Xmax); + if (srcX + readWidth > ctx->ReadBuffer->_Xmax) + readWidth -= (srcX + readWidth - ctx->ReadBuffer->_Xmax); if (readWidth <= 0) return GL_TRUE; /* vertical clipping */ - if (srcY < ctx->ReadBuffer->Ymin) { - skipRows += (ctx->ReadBuffer->Ymin - srcY); - readHeight -= (ctx->ReadBuffer->Ymin - srcY); - srcY = ctx->ReadBuffer->Ymin; + if (srcY < ctx->ReadBuffer->_Ymin) { + skipRows += (ctx->ReadBuffer->_Ymin - srcY); + readHeight -= (ctx->ReadBuffer->_Ymin - srcY); + srcY = ctx->ReadBuffer->_Ymin; } - if (srcY + readHeight > ctx->ReadBuffer->Ymax) - readHeight -= (srcY + readHeight - ctx->ReadBuffer->Ymax); + if (srcY + readHeight > ctx->ReadBuffer->_Ymax) + readHeight -= (srcY + readHeight - ctx->ReadBuffer->_Ymax); if (readHeight <= 0) return GL_TRUE; diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index a115199ab82..019534710e4 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,4 +1,4 @@ -/* $Id: s_span.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_span.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -206,7 +206,7 @@ void gl_write_index_span( GLcontext *ctx, /* Per-pixel fog */ if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_ci_pixels( ctx, n, fog, index ); else _mesa_depth_fog_ci_pixels( ctx, n, z, index ); @@ -323,7 +323,7 @@ void gl_write_monoindex_span( GLcontext *ctx, } if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_ci_pixels( ctx, n, fog, indexes ); else _mesa_depth_fog_ci_pixels( ctx, n, z, indexes ); @@ -476,7 +476,7 @@ void gl_write_rgba_span( GLcontext *ctx, /* Per-pixel fog */ if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); else _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); @@ -660,7 +660,7 @@ void gl_write_monocolor_span( GLcontext *ctx, /* Per-pixel fog */ if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); else _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); @@ -796,13 +796,14 @@ void gl_write_texture_span( GLcontext *ctx, gl_texture_pixels( ctx, 0, n, s, t, u, lambda, rgba, rgba ); /* Add base and specular colors */ - if (spec && ctx->Light.Enabled - && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + if (spec && + (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) add_colors( n, rgba, spec ); /* rgba = rgba + spec */ /* Per-pixel fog */ if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); else _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); @@ -932,13 +933,15 @@ gl_write_multitexture_span( GLcontext *ctx, gl_texture_pixels( ctx, i, n, s[i], t[i], u[i], lambda[i], rgbaIn, rgba ); /* Add base and specular colors */ - if (spec && ctx->Light.Enabled - && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + if (spec && + (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) add_colors( n, rgba, spec ); /* rgba = rgba + spec */ /* Per-pixel fog */ if (ctx->Fog.Enabled) { - if (fog && ctx->Hint.Fog != GL_NICEST) + if (fog && !swrast->_PreferPixelFog) _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); else _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index 80839451cba..aed107ca003 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -1,4 +1,4 @@ -/* $Id: s_stencil.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_stencil.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -1137,15 +1137,15 @@ clear_software_stencil_buffer( GLcontext *ctx ) if (ctx->Scissor.Enabled) { /* clear scissor region only */ - const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Stencil.WriteMask != STENCIL_MAX) { /* must apply mask to the clear */ GLint y; - for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) { + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { const GLstencil mask = ctx->Stencil.WriteMask; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); - GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->Xmin, y ); + GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); GLint i; for (i = 0; i < width; i++) { stencil[i] = (stencil[i] & invMask) | clearVal; @@ -1155,8 +1155,8 @@ clear_software_stencil_buffer( GLcontext *ctx ) else { /* no masking */ GLint y; - for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) { - GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->Xmin, y ); + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { + GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); #if STENCIL_BITS==8 MEMSET( stencil, ctx->Stencil.Clear, width * sizeof(GLstencil) ); #else @@ -1217,12 +1217,12 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) if (ctx->Scissor.Enabled) { /* clear scissor region only */ - const GLint x = ctx->DrawBuffer->Xmin; - const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Stencil.WriteMask != STENCIL_MAX) { /* must apply mask to the clear */ GLint y; - for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) { + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { const GLstencil mask = ctx->Stencil.WriteMask; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); @@ -1242,7 +1242,7 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) for (i = 0; i < width; i++) { stencil[i] = ctx->Stencil.Clear; } - for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) { + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { (*ctx->Driver.WriteStencilSpan)(ctx, x, y, width, stencil, NULL); } } @@ -1256,7 +1256,7 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) const GLstencil clearVal = (ctx->Stencil.Clear & mask); const GLint width = ctx->DrawBuffer->Width; const GLint height = ctx->DrawBuffer->Height; - const GLint x = ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; GLint y; for (y = 0; y < height; y++) { GLstencil stencil[MAX_WIDTH]; @@ -1272,7 +1272,7 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) /* clear whole buffer without masking */ const GLint width = ctx->DrawBuffer->Width; const GLint height = ctx->DrawBuffer->Width; - const GLint x = ctx->DrawBuffer->Xmin; + const GLint x = ctx->DrawBuffer->_Xmin; GLstencil stencil[MAX_WIDTH]; GLint y, i; for (i = 0; i < width; i++) { diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 267a0f2c8e5..8ca640610ec 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -1,4 +1,4 @@ -/* $Id: s_triangle.c,v 1.2 2000/11/05 18:24:41 keithw Exp $ */ +/* $Id: s_triangle.c,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -58,7 +58,7 @@ GLboolean gl_cull_triangle( GLcontext *ctx, GLfloat fy = v2->win[1] - v0->win[1]; GLfloat c = ex*fy-ey*fx; - if (c * ctx->_backface_sign > 0) + if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0) return 0; return 1; @@ -2378,7 +2378,7 @@ _swrast_choose_triangle( GLcontext *ctx ) needLambda = GL_TRUE; else needLambda = GL_FALSE; - if (ctx->Texture._MultiTextureEnabled) { + if (swrast->_MultiTextureEnabled) { swrast->Triangle = lambda_multitextured_triangle; dputs("lambda_multitextured_triangle"); } diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index a87b24c40c6..8fdbec9d187 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_tritemp.h,v 1.2 2000/11/05 18:24:41 keithw Exp $ */ +/* $Id: s_tritemp.h,v 1.3 2000/11/13 20:02:57 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -96,7 +96,7 @@ EdgeT eMaj, eTop, eBot; GLfloat oneOverArea; SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ - float bf = ctx->_backface_sign; + float bf = SWRAST_CONTEXT(ctx)->_backface_sign; /* find the order of the 3 vertices along the Y axis */ { @@ -713,8 +713,10 @@ dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } - ffog = FloatToFixed(vLower->fog) * 256 + dfogdx * adjx + dfogdy * adjy + FIXED_HALF; - fdfogOuter = SignedFloatToFixed(dfogdy + dxOuter * dfogdx); + { + ffog = FloatToFixed(vLower->fog) * 256 + dfogdx * adjx + dfogdy * adjy + FIXED_HALF; + fdfogOuter = SignedFloatToFixed(dfogdy + dxOuter * dfogdx); + } #endif #ifdef INTERP_RGB fr = (GLfixed)(IntToFixed(vLower->color[0]) @@ -980,7 +982,7 @@ zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter); # endif fz += fdzOuter; - ffog += fdfogOuter; + ffog += fdfogOuter; #endif #ifdef INTERP_RGB fr += fdrOuter; fg += fdgOuter; fb += fdbOuter; diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 88689499fd2..82a0add00ed 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -150,5 +150,12 @@ _swrast_flush( GLcontext *ctx ); extern void _swrast_InvalidateState( GLcontext *ctx, GLuint new_state ); +/* Configure software rasterizer to match hardware rasterizer characteristics: + */ +extern void +_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ); + +extern void +_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ); #endif diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index a10f22cb3f5..10942037a3a 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -1,4 +1,4 @@ -/* $Id: ss_context.c,v 1.2 2000/11/10 17:45:16 brianp Exp $ */ +/* $Id: ss_context.c,v 1.3 2000/11/13 20:02:58 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -107,10 +107,9 @@ static void _swsetup_invalidate_state( GLcontext *ctx, GLuint new_state ) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); - + swsetup->NewState |= new_state; - if (new_state & _SWSETUP_NEW_RENDERINDEX) { swsetup->Triangle = _swsetup_validate_triangle; swsetup->Line = _swsetup_validate_line; diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index 992bc4f396a..ab70f5c97bc 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -36,7 +36,8 @@ #define SS_OFFSET_BIT 0x2 #define SS_TWOSIDE_BIT 0x4 #define SS_UNFILLED_BIT 0x10 -#define SS_MAX_TRIFUNC 0x20 +#define SS_COPY_EXTRAS 0x20 /* optimization */ +#define SS_MAX_TRIFUNC 0x40 static triangle_func tri_tab[SS_MAX_TRIFUNC]; static line_func line_tab[SS_MAX_TRIFUNC]; @@ -112,6 +113,70 @@ static quad_func quad_tab[SS_MAX_TRIFUNC]; #define TAG(x) x##_flat_offset_twoside_unfilled #include "ss_tritmp.h" +#define IND (0|SS_COPY_EXTRAS) +#define TAG(x) x##_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_spec +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_offset_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_offset_spec +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_twoside_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_TWOSIDE_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_twoside_spec +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_offset_twoside_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_offset_twoside_spec +#include "ss_tritmp.h" + +#define IND (SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_offset_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_offset_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_twoside_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_twoside_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_offset_twoside_unfilled_spec +#include "ss_tritmp.h" + +#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_COPY_EXTRAS) +#define TAG(x) x##_flat_offset_twoside_unfilled_spec +#include "ss_tritmp.h" + void _swsetup_trifuncs_init( GLcontext *ctx ) { @@ -133,6 +198,23 @@ void _swsetup_trifuncs_init( GLcontext *ctx ) init_flat_twoside_unfilled(); init_offset_twoside_unfilled(); init_flat_offset_twoside_unfilled(); + + init_spec(); + init_flat_spec(); + init_offset_spec(); + init_flat_offset_spec(); + init_twoside_spec(); + init_flat_twoside_spec(); + init_offset_twoside_spec(); + init_flat_offset_twoside_spec(); + init_unfilled_spec(); + init_flat_unfilled_spec(); + init_offset_unfilled_spec(); + init_flat_offset_unfilled_spec(); + init_twoside_unfilled_spec(); + init_flat_twoside_unfilled_spec(); + init_offset_twoside_unfilled_spec(); + init_flat_offset_twoside_unfilled_spec(); } @@ -153,6 +235,11 @@ void _swsetup_choose_trifuncs( GLcontext *ctx ) if (ctx->Polygon._Unfilled) ind |= SS_UNFILLED_BIT; + if ((ctx->_TriangleCaps & DD_SEPERATE_SPECULAR) || + ctx->RenderMode == GL_SELECT || + !ctx->Visual.RGBAflag) + ind |= SS_COPY_EXTRAS; + swsetup->Triangle = tri_tab[ind]; swsetup->Line = line_tab[ind]; swsetup->Points = points_tab[ind]; diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 570827a1b56..37b56642252 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -45,16 +45,24 @@ static void TAG(triangle)(GLcontext *ctx, if (IND & (SS_TWOSIDE_BIT | SS_FLAT_BIT)) { SS_COLOR(c[0], v[0]->color); - SS_COLOR(c[1], v[1]->color); - SS_COLOR(c[2], v[2]->color); - SS_SPEC(s[0], v[0]->specular); - SS_SPEC(s[1], v[1]->specular); - SS_SPEC(s[2], v[2]->specular); + if (IND & SS_TWOSIDE_BIT) { + SS_COLOR(c[1], v[1]->color); + SS_COLOR(c[2], v[2]->color); + } + + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(s[0], v[0]->specular); + SS_IND(i[0], v[0]->index); + + if (IND & SS_TWOSIDE_BIT) { + SS_SPEC(s[1], v[1]->specular); + SS_IND(i[1], v[1]->index); - SS_IND(i[0], v[0]->index); - SS_IND(i[1], v[1]->index); - SS_IND(i[2], v[2]->index); + SS_SPEC(s[2], v[2]->specular); + SS_IND(i[2], v[2]->index); + } + } } if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) @@ -82,25 +90,29 @@ static void TAG(triangle)(GLcontext *ctx, SS_COLOR(v[1]->color, vbcolor[pv]); SS_COLOR(v[2]->color, vbcolor[pv]); - SS_SPEC(v[0]->specular, vbspec[pv]); - SS_SPEC(v[1]->specular, vbspec[pv]); - SS_SPEC(v[2]->specular, vbspec[pv]); - - SS_IND(v[0]->index, vbindex[pv]); - SS_IND(v[1]->index, vbindex[pv]); - SS_IND(v[2]->index, vbindex[pv]); + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(v[0]->specular, vbspec[pv]); + SS_SPEC(v[1]->specular, vbspec[pv]); + SS_SPEC(v[2]->specular, vbspec[pv]); + + SS_IND(v[0]->index, vbindex[pv]); + SS_IND(v[1]->index, vbindex[pv]); + SS_IND(v[2]->index, vbindex[pv]); + } } else { SS_COLOR(v[0]->color, vbcolor[e0]); SS_COLOR(v[1]->color, vbcolor[e1]); SS_COLOR(v[2]->color, vbcolor[e2]); - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); - SS_IND(v[0]->index, vbindex[e0]); - SS_IND(v[1]->index, vbindex[e1]); - SS_IND(v[2]->index, vbindex[e2]); + SS_IND(v[0]->index, vbindex[e0]); + SS_IND(v[1]->index, vbindex[e1]); + SS_IND(v[2]->index, vbindex[e2]); + } } } } @@ -125,23 +137,18 @@ static void TAG(triangle)(GLcontext *ctx, } } } - else if(IND & SS_FLAT_BIT) + else if (IND & SS_FLAT_BIT) { GLubyte *color = VB->Color[0]->data[pv]; GLubyte *spec = VB->SecondaryColor[0]->data[pv]; GLuint index = VB->Index[0]->data[pv]; SS_COLOR(v[0]->color, color); - SS_COLOR(v[1]->color, color); - SS_COLOR(v[2]->color, color); - SS_SPEC(v[0]->specular, spec); - SS_SPEC(v[1]->specular, spec); - SS_SPEC(v[2]->specular, spec); - - SS_IND(v[0]->index, index); - SS_IND(v[1]->index, index); - SS_IND(v[2]->index, index); + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(v[0]->specular, spec); + SS_IND(v[0]->index, index); + } } if (mode == GL_POINT) { @@ -181,16 +188,24 @@ static void TAG(triangle)(GLcontext *ctx, if (IND & (SS_FLAT_BIT | SS_TWOSIDE_BIT)) { SS_COLOR(v[0]->color, c[0]); - SS_COLOR(v[1]->color, c[1]); - SS_COLOR(v[2]->color, c[2]); - - SS_SPEC(v[0]->specular, s[0]); - SS_SPEC(v[1]->specular, s[1]); - SS_SPEC(v[2]->specular, s[2]); - SS_IND(v[0]->index, i[0]); - SS_IND(v[1]->index, i[1]); - SS_IND(v[2]->index, i[2]); + if (IND & SS_TWOSIDE_BIT) { + SS_COLOR(v[1]->color, c[1]); + SS_COLOR(v[2]->color, c[2]); + } + + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(v[0]->specular, s[0]); + SS_IND(v[0]->index, i[0]); + + if (IND & SS_TWOSIDE_BIT) { + SS_SPEC(v[1]->specular, s[1]); + SS_IND(v[1]->index, i[1]); + + SS_SPEC(v[2]->specular, s[2]); + SS_IND(v[2]->index, i[2]); + } + } } } @@ -223,35 +238,26 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) GLuint index = VB->Index[0]->data[pv]; SS_COLOR(c[0], vert0->color); - SS_COLOR(c[1], vert1->color); - - SS_SPEC(s[0], vert0->specular); - SS_SPEC(s[1], vert1->specular); - - SS_IND(i[0], vert0->index); - SS_IND(i[1], vert1->index); - SS_COLOR(vert0->color, color); - SS_COLOR(vert1->color, color); - - SS_SPEC(vert0->specular, spec); - SS_SPEC(vert1->specular, spec); - SS_IND(vert0->index, index); - SS_IND(vert1->index, index); + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(s[0], vert0->specular); + SS_SPEC(vert0->specular, spec); + + SS_IND(i[0], vert0->index); + SS_IND(vert0->index, index); + } } _swrast_Line( ctx, vert0, vert1 ); if (IND & SS_FLAT_BIT) { SS_COLOR(vert0->color, c[0]); - SS_COLOR(vert1->color, c[1]); - SS_SPEC(vert0->specular, s[0]); - SS_SPEC(vert1->specular, s[1]); - - SS_IND(vert0->index, i[0]); - SS_IND(vert1->index, i[1]); + if (IND & SS_COPY_EXTRAS) { + SS_SPEC(vert0->specular, s[0]); + SS_IND(vert0->index, i[0]); + } } } diff --git a/src/mesa/swrast_setup/ss_vb.c b/src/mesa/swrast_setup/ss_vb.c index 5e0f4dc84b3..15e6049cb51 100644 --- a/src/mesa/swrast_setup/ss_vb.c +++ b/src/mesa/swrast_setup/ss_vb.c @@ -165,16 +165,16 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx) if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled) funcindex |= SPEC; - - if (ctx->Point._Attenuated) - funcindex |= EYE; - - if (ctx->Fog.Enabled) - funcindex |= FOG; } else { funcindex = INDEX; } + + if (ctx->Point._Attenuated) + funcindex |= EYE; + + if (ctx->Fog.Enabled) + funcindex |= FOG; } else { /* feedback or section */ |