Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 pj 1
/* $Id: t_eval_api.c,v 1.1 2003-02-28 11:48:06 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 - original code
28
 *    Brian Paul - vertex program updates
29
 */
30
 
31
 
32
#include "glheader.h"
33
#include "colormac.h"
34
#include "context.h"
35
#include "macros.h"
36
#include "imports.h"
37
#include "mmath.h"
38
#include "mtypes.h"
39
#include "math/m_eval.h"
40
 
41
#include "t_eval_api.h"
42
#include "t_imm_api.h"
43
#include "t_imm_alloc.h"
44
#include "t_imm_exec.h"
45
 
46
 
47
/* KW: If are compiling, we don't know whether eval will produce a
48
 *     vertex when it is run in the future.  If this is pure immediate
49
 *     mode, eval is a noop if neither vertex map is enabled.
50
 *
51
 *     Thus we need to have a check in the display list code or
52
 *     elsewhere for eval(1,2) vertices in the case where
53
 *     map(1,2)_vertex is disabled, and to purge those vertices from
54
 *     the vb.
55
 */
56
void
57
_tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
58
{
59
   GET_CURRENT_CONTEXT(ctx);
60
   GLint i;
61
   GLfloat u, du;
62
   GLenum prim;
63
   ASSERT_OUTSIDE_BEGIN_END(ctx);
64
 
65
   if (MESA_VERBOSE & VERBOSE_API)
66
      _mesa_debug(ctx, "glEvalMesh1()");
67
 
68
   switch (mode) {
69
      case GL_POINT:
70
         prim = GL_POINTS;
71
         break;
72
      case GL_LINE:
73
         prim = GL_LINE_STRIP;
74
         break;
75
      default:
76
         _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
77
         return;
78
   }
79
 
80
   /* No effect if vertex maps disabled.
81
    */
82
   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 &&
83
       (!ctx->VertexProgram.Enabled || !ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]))
84
      return;
85
 
86
   du = ctx->Eval.MapGrid1du;
87
   u = ctx->Eval.MapGrid1u1 + i1 * du;
88
 
89
   /* Need to turn off compilation -- this is already saved, and the
90
    * coordinates generated and the test above depend on state that
91
    * may change before the list is executed.
92
    *
93
    * TODO: Anaylse display lists to determine if this state is
94
    * constant.
95
    *
96
    * State to watch:
97
    *       - enabled maps
98
    *       - map state for each enabled map, including control points
99
    *       - grid state
100
    *
101
    * Could alternatively cache individual maps in arrays, rather than
102
    * building immediates.  
103
    */
104
   {
105
      GLboolean compiling = ctx->CompileFlag;
106
      TNLcontext *tnl = TNL_CONTEXT(ctx);
107
      struct immediate *im = TNL_CURRENT_IM(ctx);
108
      GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
109
 
110
      NotifyBegin = tnl->Driver.NotifyBegin;
111
      tnl->Driver.NotifyBegin = 0;
112
 
113
      if (compiling) {
114
         struct immediate *tmp = _tnl_alloc_immediate( ctx );
115
         FLUSH_VERTICES( ctx, 0 );
116
         SET_IMMEDIATE( ctx, tmp );
117
         TNL_CURRENT_IM(ctx)->ref_count++;       
118
         ctx->CompileFlag = GL_FALSE;
119
      }
120
 
121
      _tnl_Begin( prim );
122
      for (i=i1;i<=i2;i++,u+=du) {
123
         _tnl_eval_coord1f( ctx, u );
124
      }
125
      _tnl_end(ctx);
126
 
127
      /* Need this for replay *and* compile:
128
       */
129
      FLUSH_VERTICES( ctx, 0 );
130
      tnl->Driver.NotifyBegin = NotifyBegin;
131
 
132
      if (compiling) {
133
         TNL_CURRENT_IM(ctx)->ref_count--;
134
         ASSERT( TNL_CURRENT_IM(ctx)->ref_count == 0 );
135
         _tnl_free_immediate( ctx, TNL_CURRENT_IM(ctx) );
136
         SET_IMMEDIATE( ctx, im );
137
         ctx->CompileFlag = GL_TRUE;
138
      }
139
   }
140
}
141
 
142
 
143
 
144
void
145
_tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
146
{
147
   GET_CURRENT_CONTEXT(ctx);
148
   GLint i, j;
149
   GLfloat u, du, v, dv, v1, u1;
150
   ASSERT_OUTSIDE_BEGIN_END(ctx);
151
 
152
   if (MESA_VERBOSE & VERBOSE_API)
153
      _mesa_debug(ctx, "glEvalMesh2()");
154
 
155
   /* No effect if vertex maps disabled.
156
    */
157
   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 &&
158
       (!ctx->VertexProgram.Enabled || !ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]))
159
      return;
160
 
161
   du = ctx->Eval.MapGrid2du;
162
   dv = ctx->Eval.MapGrid2dv;
163
   v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
164
   u1 = ctx->Eval.MapGrid2u1 + i1 * du;
165
 
166
   /* Need to turn off compilation -- this is already saved, and the
167
    * coordinates generated and the test above depend on state that
168
    * may change before the list is executed.
169
    */
170
   {
171
      GLboolean compiling = ctx->CompileFlag;
172
      struct immediate *im = TNL_CURRENT_IM(ctx);
173
      TNLcontext *tnl = TNL_CONTEXT(ctx);
174
      GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
175
 
176
      NotifyBegin = tnl->Driver.NotifyBegin;
177
      tnl->Driver.NotifyBegin = 0;
178
 
179
      if (compiling) {
180
         struct immediate *tmp = _tnl_alloc_immediate( ctx );
181
         FLUSH_VERTICES( ctx, 0 );
182
         SET_IMMEDIATE( ctx, tmp );
183
         TNL_CURRENT_IM(ctx)->ref_count++;       
184
         ctx->CompileFlag = GL_FALSE;
185
      }
186
 
187
      switch (mode) {
188
      case GL_POINT:
189
         _tnl_Begin( GL_POINTS );
190
         for (v=v1,j=j1;j<=j2;j++,v+=dv) {
191
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
192
               _tnl_eval_coord2f( ctx, u, v );
193
            }
194
         }
195
         _tnl_end(ctx);
196
         break;
197
      case GL_LINE:
198
         for (v=v1,j=j1;j<=j2;j++,v+=dv) {
199
            _tnl_Begin( GL_LINE_STRIP );
200
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
201
               _tnl_eval_coord2f( ctx, u, v );
202
            }
203
            _tnl_end(ctx);
204
         }
205
         for (u=u1,i=i1;i<=i2;i++,u+=du) {
206
            _tnl_Begin( GL_LINE_STRIP );
207
            for (v=v1,j=j1;j<=j2;j++,v+=dv) {
208
               _tnl_eval_coord2f( ctx, u, v );
209
            }
210
            _tnl_end(ctx);
211
         }
212
         break;
213
      case GL_FILL:
214
         for (v=v1,j=j1;j<j2;j++,v+=dv) {
215
            _tnl_Begin( GL_TRIANGLE_STRIP );
216
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
217
               _tnl_eval_coord2f( ctx, u, v );
218
               _tnl_eval_coord2f( ctx, u, v+dv );
219
            }
220
            _tnl_end(ctx);
221
         }
222
         break;
223
      default:
224
         _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
225
         return;
226
      }
227
 
228
      /* Need this for replay *and* compile:
229
       */
230
      FLUSH_VERTICES( ctx, 0 );
231
      tnl->Driver.NotifyBegin = NotifyBegin;
232
 
233
      if (compiling) {
234
         TNL_CURRENT_IM(ctx)->ref_count--;
235
         _tnl_free_immediate( ctx, TNL_CURRENT_IM( ctx ) );
236
         SET_IMMEDIATE( ctx, im );
237
         ctx->CompileFlag = GL_TRUE;
238
      }
239
   }
240
}
241
 
242
 
243
void _tnl_eval_init( GLcontext *ctx )
244
{
245
   GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
246
   vfmt->EvalMesh1 = _tnl_exec_EvalMesh1;
247
   vfmt->EvalMesh2 = _tnl_exec_EvalMesh2;
248
}