home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_vb_normals.cpp < prev    next >
C/C++ Source or Header  |  2002-10-29  |  6KB  |  200 lines

  1. /* $Id: t_vb_normals.c,v 1.17 2002/10/29 20:29:04 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  * Authors:
  27.  *    Keith Whitwell <keith@tungstengraphics.com>
  28.  */
  29.  
  30.  
  31. #include "glheader.h"
  32. #include "colormac.h"
  33. #include "context.h"
  34. #include "macros.h"
  35. #include "imports.h"
  36. #include "mmath.h"
  37. #include "mtypes.h"
  38.  
  39. #include "math/m_xform.h"
  40.  
  41. #include "t_context.h"
  42. #include "t_pipeline.h"
  43.  
  44.  
  45.  
  46. struct normal_stage_data {
  47.    normal_func NormalTransform;
  48.    GLvector4f normal;
  49. };
  50.  
  51. #define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr)
  52.  
  53.  
  54.  
  55.  
  56. static GLboolean run_normal_stage( GLcontext *ctx,
  57.                    struct gl_pipeline_stage *stage )
  58. {
  59.    struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
  60.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  61.  
  62.    ASSERT(store->NormalTransform);
  63.  
  64.    if (stage->changed_inputs) {
  65.       /* We can only use the display list's saved normal lengths if we've
  66.        * got a transformation matrix with uniform scaling.
  67.        */
  68.       const GLfloat *lengths;
  69.       if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
  70.          lengths = NULL;
  71.       else
  72.          lengths = VB->NormalLengthPtr;
  73.  
  74.       store->NormalTransform( ctx->ModelviewMatrixStack.Top,
  75.                   ctx->_ModelViewInvScale,
  76.                   VB->NormalPtr,  /* input normals */
  77.                   lengths,
  78.                   &store->normal ); /* resulting normals */
  79.    }
  80.  
  81.    VB->NormalPtr = &store->normal;
  82.    VB->NormalLengthPtr = 0;    /* no longer valid */
  83.    return GL_TRUE;
  84. }
  85.  
  86.  
  87. static GLboolean run_validate_normal_stage( GLcontext *ctx,
  88.                         struct gl_pipeline_stage *stage )
  89. {
  90.    struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
  91.  
  92.    ASSERT(ctx->_NeedNormals);
  93.  
  94.    if (ctx->_NeedEyeCoords) {
  95.       GLuint transform = NORM_TRANSFORM_NO_ROT;
  96.  
  97.       if (ctx->ModelviewMatrixStack.Top->flags & (MAT_FLAG_GENERAL |
  98.                   MAT_FLAG_ROTATION |
  99.                   MAT_FLAG_GENERAL_3D |
  100.                   MAT_FLAG_PERSPECTIVE))
  101.      transform = NORM_TRANSFORM;
  102.  
  103.  
  104.       if (ctx->Transform.Normalize) {
  105.      store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE];
  106.       }
  107.       else if (ctx->Transform.RescaleNormals &&
  108.            ctx->_ModelViewInvScale != 1.0) {
  109.      store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE];
  110.       }
  111.       else {
  112.      store->NormalTransform = _mesa_normal_tab[transform];
  113.       }
  114.    }
  115.    else {
  116.       if (ctx->Transform.Normalize) {
  117.      store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE];
  118.       }
  119.       else if (!ctx->Transform.RescaleNormals &&
  120.            ctx->_ModelViewInvScale != 1.0) {
  121.      store->NormalTransform = _mesa_normal_tab[NORM_RESCALE];
  122.       }
  123.       else {
  124.      store->NormalTransform = 0;
  125.       }
  126.    }
  127.  
  128.    if (store->NormalTransform) {
  129.       stage->run = run_normal_stage;
  130.       return stage->run( ctx, stage );
  131.    } else {
  132.       stage->active = GL_FALSE;    /* !!! */
  133.       return GL_TRUE;
  134.    }
  135. }
  136.  
  137.  
  138. static void check_normal_transform( GLcontext *ctx,
  139.                     struct gl_pipeline_stage *stage )
  140. {
  141.    stage->active = ctx->_NeedNormals && !ctx->VertexProgram.Enabled;
  142.    /* Don't clobber the initialize function:
  143.     */
  144.    if (stage->privatePtr)
  145.       stage->run = run_validate_normal_stage;
  146. }
  147.  
  148.  
  149. static GLboolean alloc_normal_data( GLcontext *ctx,
  150.                  struct gl_pipeline_stage *stage )
  151. {
  152.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  153.    struct normal_stage_data *store;
  154.    stage->privatePtr = MALLOC(sizeof(*store));
  155.    store = NORMAL_STAGE_DATA(stage);
  156.    if (!store)
  157.       return GL_FALSE;
  158.  
  159.    _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 );
  160.  
  161.    /* Now run the stage.
  162.     */
  163.    stage->run = run_validate_normal_stage;
  164.    return stage->run( ctx, stage );
  165. }
  166.  
  167.  
  168.  
  169. static void free_normal_data( struct gl_pipeline_stage *stage )
  170. {
  171.    struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
  172.    if (store) {
  173.       _mesa_vector4f_free( &store->normal );
  174.       FREE( store );
  175.       stage->privatePtr = NULL;
  176.    }
  177. }
  178.  
  179. #define _TNL_NEW_NORMAL_TRANSFORM        (_NEW_MODELVIEW| \
  180.                       _NEW_TRANSFORM| \
  181.                                           _MESA_NEW_NEED_NORMALS| \
  182.                                           _MESA_NEW_NEED_EYE_COORDS)
  183.  
  184.  
  185.  
  186. const struct gl_pipeline_stage _tnl_normal_transform_stage =
  187. {
  188.    "normal transform",        /* name */
  189.    _TNL_NEW_NORMAL_TRANSFORM,    /* re-check */
  190.    _TNL_NEW_NORMAL_TRANSFORM,    /* re-run */
  191.    GL_FALSE,            /* active? */
  192.    VERT_BIT_NORMAL,        /* inputs */
  193.    VERT_BIT_NORMAL,        /* outputs */
  194.    0,                /* changed_inputs */
  195.    NULL,            /* private data */
  196.    free_normal_data,        /* destructor */
  197.    check_normal_transform,    /* check */
  198.    alloc_normal_data        /* run -- initially set to alloc */
  199. };
  200.