X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_vb_normals.c;h=6fc89c23b3331362d63e28d9da0ea8cf3011fdd8;hb=55f335bd303da8fff90ccc8d7e43aac70d4b80b5;hp=31f309a7bc591253fda5f4ccf7df536c1fdad08a;hpb=3c63452e64df7e10aa073c6c3b9492b1d7dabbb8;p=mesa.git diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c index 31f309a7bc5..6fc89c23b33 100644 --- a/src/mesa/tnl/t_vb_normals.c +++ b/src/mesa/tnl/t_vb_normals.c @@ -1,10 +1,7 @@ -/* $Id: t_vb_normals.c,v 1.16 2002/10/24 23:57:25 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 4.1 * - * Copyright (C) 1999-2002 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"), @@ -19,22 +16,20 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * 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. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN 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. * * Authors: - * Keith Whitwell + * Keith Whitwell */ -#include "glheader.h" -#include "colormac.h" -#include "context.h" -#include "macros.h" -#include "imports.h" -#include "mmath.h" -#include "mtypes.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/imports.h" +#include "main/mtypes.h" #include "math/m_xform.h" @@ -42,7 +37,6 @@ #include "t_pipeline.h" - struct normal_stage_data { normal_func NormalTransform; GLvector4f normal; @@ -51,61 +45,76 @@ struct normal_stage_data { #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(struct gl_context *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) { - /* We can only use the display list's saved normal lengths if we've - * got a transformation matrix with uniform scaling. - */ - const GLfloat *lengths; - if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE) - lengths = NULL; - else - lengths = VB->NormalLengthPtr; - - store->NormalTransform( ctx->ModelviewMatrixStack.Top, - ctx->_ModelViewInvScale, - VB->NormalPtr, /* input normals */ - lengths, - &store->normal ); /* resulting normals */ + /* 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->NormalPtr = &store->normal; - VB->NormalLengthPtr = 0; /* no longer valid */ + VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &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(struct gl_context *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->ModelviewMatrixStack.Top->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.0F) { store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE]; } else { @@ -113,87 +122,65 @@ 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]; } else if (!ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0) { + ctx->_ModelViewInvScale != 1.0F) { 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 && !ctx->VertexProgram.Enabled; - /* 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(struct gl_context *ctx, struct tnl_pipeline_stage *stage) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct normal_stage_data *store; - stage->privatePtr = MALLOC(sizeof(*store)); + + stage->privatePtr = malloc(sizeof(*store)); store = NORMAL_STAGE_DATA(stage); if (!store) return GL_FALSE; _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); - - /* Now run the stage. - */ - stage->run = run_validate_normal_stage; - return stage->run( ctx, stage ); + 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_vector4f_free( &store->normal ); - FREE( store ); + 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 = +const struct tnl_pipeline_stage _tnl_normal_transform_stage = { "normal transform", /* name */ - _TNL_NEW_NORMAL_TRANSFORM, /* re-check */ - _TNL_NEW_NORMAL_TRANSFORM, /* re-run */ - GL_FALSE, /* active? */ - VERT_BIT_NORMAL, /* inputs */ - VERT_BIT_NORMAL, /* outputs */ - 0, /* changed_inputs */ - NULL, /* private data */ - free_normal_data, /* destructor */ - check_normal_transform, /* check */ - alloc_normal_data /* run -- initially set to alloc */ + NULL, /* privatePtr */ + alloc_normal_data, /* create */ + free_normal_data, /* destroy */ + validate_normal_stage, /* validate */ + run_normal_stage /* run */ };