fixed bad clear value
[mesa.git] / src / mesa / tnl / t_eval_api.c
1 /* $Id: t_eval_api.c,v 1.12 2002/10/24 23:57:25 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 - 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 }