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