X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Ftnl%2Ft_vb_normals.c;h=a4821cc1cccf7230a53752d6012b7c591ad84032;hb=2f6675b8160c5fa2e6e9b5642c133fd2843a7508;hp=4f9503bed3d40213ddd1881251221b5d4ccb7d04;hpb=b51b0a847d7e7daaea69f77ab569086ef81c24a2;p=mesa.git diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c index 4f9503bed3d..a4821cc1ccc 100644 --- a/src/mesa/tnl/t_vb_normals.c +++ b/src/mesa/tnl/t_vb_normals.c @@ -1,10 +1,8 @@ -/* $Id: t_vb_normals.c,v 1.6 2001/03/07 05:06:13 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 6.5 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,18 +21,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * Author: - * Keith Whitwell + * Authors: + * Keith Whitwell */ -#include "glheader.h" -#include "colormac.h" -#include "context.h" -#include "macros.h" -#include "mem.h" -#include "mmath.h" -#include "mtypes.h" +#include "main/glheader.h" +#include "main/colormac.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/imports.h" +#include "main/mtypes.h" #include "math/m_xform.h" @@ -42,60 +39,85 @@ #include "t_pipeline.h" - struct normal_stage_data { - normal_func *NormalTransform; - GLvector3f normal; + normal_func NormalTransform; + GLvector4f normal; }; #define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr) - - -static GLboolean run_normal_stage( GLcontext *ctx, - struct gl_pipeline_stage *stage ) +static GLboolean +run_normal_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + const GLfloat *lengths; - ASSERT(store->NormalTransform); + if (!store->NormalTransform) + return GL_TRUE; - if (stage->changed_inputs) - (store->NormalTransform[0])(&ctx->ModelView, - ctx->_ModelViewInvScale, - VB->NormalPtr, - 0, - 0, - &store->normal); + /* We can only use the display list's saved normal lengths if we've + * got a transformation matrix with uniform scaling. + */ + if (_math_matrix_is_general_scale(ctx->ModelviewMatrixStack.Top)) + lengths = NULL; + else + lengths = VB->NormalLengthPtr; + + store->NormalTransform( ctx->ModelviewMatrixStack.Top, + ctx->_ModelViewInvScale, + VB->AttribPtr[_TNL_ATTRIB_NORMAL], /* input normals */ + lengths, + &store->normal ); /* resulting normals */ + + if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count > 1) { + store->normal.stride = 4 * sizeof(GLfloat); + } + else { + store->normal.stride = 0; + } + VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &store->normal; VB->NormalPtr = &store->normal; + + VB->NormalLengthPtr = NULL; /* no longer valid */ return GL_TRUE; } -static GLboolean run_validate_normal_stage( GLcontext *ctx, - struct gl_pipeline_stage *stage) +/** + * Examine current GL state and set the store->NormalTransform pointer + * to point to the appropriate normal transformation routine. + */ +static void +validate_normal_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); - ASSERT(ctx->_NeedNormals); + if (ctx->VertexProgram._Current || + (!ctx->Light.Enabled && + !(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) { + store->NormalTransform = NULL; + return; + } if (ctx->_NeedEyeCoords) { + /* Eye coordinates are needed, for whatever reasons. + * Do lighting in eye coordinates, as the GL spec says. + */ GLuint transform = NORM_TRANSFORM_NO_ROT; - if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) + if (_math_matrix_has_rotation(ctx->ModelviewMatrixStack.Top)) { + /* need to do full (3x3) matrix transform */ transform = NORM_TRANSFORM; - - + } + if (ctx->Transform.Normalize) { store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE]; } else if (ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0) { + ctx->_ModelViewInvScale != 1.0) { store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE]; } else { @@ -103,6 +125,11 @@ static GLboolean run_validate_normal_stage( GLcontext *ctx, } } else { + /* We don't need eye coordinates. + * Do lighting in object coordinates. Thus, we don't need to fully + * transform normal vectors (just leave them in object coordinates) + * but we still need to do normalization/rescaling if enabled. + */ if (ctx->Transform.Normalize) { store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE]; } @@ -111,77 +138,52 @@ static GLboolean run_validate_normal_stage( GLcontext *ctx, store->NormalTransform = _mesa_normal_tab[NORM_RESCALE]; } else { - store->NormalTransform = 0; + store->NormalTransform = NULL; } } - - if (store->NormalTransform) { - stage->run = run_normal_stage; - return stage->run( ctx, stage ); - } else { - stage->active = GL_FALSE; /* !!! */ - return GL_TRUE; - } } -static void check_normal_transform( GLcontext *ctx, - struct gl_pipeline_stage *stage ) -{ - stage->active = ctx->_NeedNormals; - /* Don't clobber the initialize function: - */ - if (stage->privatePtr) - stage->run = run_validate_normal_stage; -} - - -static GLboolean alloc_normal_data( GLcontext *ctx, - struct gl_pipeline_stage *stage ) +/** + * Allocate stage's private data (storage for transformed normals). + */ +static GLboolean +alloc_normal_data(GLcontext *ctx, struct tnl_pipeline_stage *stage) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct normal_stage_data *store; - stage->privatePtr = MALLOC(sizeof(*store)); + + stage->privatePtr = _mesa_malloc(sizeof(*store)); store = NORMAL_STAGE_DATA(stage); if (!store) return GL_FALSE; - _mesa_vector3f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); - - /* Now run the stage. - */ - stage->run = run_validate_normal_stage; - return stage->run( ctx, stage ); + _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); + return GL_TRUE; } - -static void free_normal_data( struct gl_pipeline_stage *stage ) +/** + * Free stage's private data. + */ +static void +free_normal_data(struct tnl_pipeline_stage *stage) { struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); if (store) { - _mesa_vector3f_free( &store->normal ); - FREE( store ); + _mesa_vector4f_free( &store->normal ); + _mesa_free( store ); stage->privatePtr = NULL; } } -#define _TNL_NEW_NORMAL_TRANSFORM (_NEW_MODELVIEW| \ - _NEW_TRANSFORM| \ - _MESA_NEW_NEED_NORMALS| \ - _MESA_NEW_NEED_EYE_COORDS) - - -const struct gl_pipeline_stage _tnl_normal_transform_stage = -{ - "normal transform", - _TNL_NEW_NORMAL_TRANSFORM, /* re-check */ - _TNL_NEW_NORMAL_TRANSFORM, /* re-run */ - 0,VERT_NORM,VERT_NORM, /* active, inputs, outputs */ - 0, 0, /* changed_inputs, private */ - free_normal_data, /* destructor */ - check_normal_transform, /* check */ - alloc_normal_data /* run -- initially set to alloc */ +const struct tnl_pipeline_stage _tnl_normal_transform_stage = +{ + "normal transform", /* name */ + NULL, /* privatePtr */ + alloc_normal_data, /* create */ + free_normal_data, /* destroy */ + validate_normal_stage, /* validate */ + run_normal_stage /* run */ }; -