Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 pj 1
/* $Id: t_vb_normals.c,v 1.1 2003-02-28 11:48:07 pj 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
};