3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell - original code
27 * Brian Paul - vertex program updates
37 #include "math/m_eval.h"
39 #include "t_eval_api.h"
40 #include "t_imm_api.h"
41 #include "t_imm_alloc.h"
42 #include "t_imm_exec.h"
45 /* KW: If are compiling, we don't know whether eval will produce a
46 * vertex when it is run in the future. If this is pure immediate
47 * mode, eval is a noop if neither vertex map is enabled.
49 * Thus we need to have a check in the display list code or
50 * elsewhere for eval(1,2) vertices in the case where
51 * map(1,2)_vertex is disabled, and to purge those vertices from
55 _tnl_exec_EvalMesh1( GLenum mode
, GLint i1
, GLint i2
)
57 GET_CURRENT_CONTEXT(ctx
);
61 ASSERT_OUTSIDE_BEGIN_END(ctx
);
63 if (MESA_VERBOSE
& VERBOSE_API
)
64 _mesa_debug(ctx
, "glEvalMesh1()");
74 _mesa_error( ctx
, GL_INVALID_ENUM
, "glEvalMesh1(mode)" );
78 /* No effect if vertex maps disabled.
80 if (!ctx
->Eval
.Map1Vertex4
&& !ctx
->Eval
.Map1Vertex3
&&
81 (!ctx
->VertexProgram
.Enabled
|| !ctx
->Eval
.Map1Attrib
[VERT_ATTRIB_POS
]))
84 du
= ctx
->Eval
.MapGrid1du
;
85 u
= ctx
->Eval
.MapGrid1u1
+ i1
* du
;
87 /* Need to turn off compilation -- this is already saved, and the
88 * coordinates generated and the test above depend on state that
89 * may change before the list is executed.
91 * TODO: Anaylse display lists to determine if this state is
96 * - map state for each enabled map, including control points
99 * Could alternatively cache individual maps in arrays, rather than
100 * building immediates.
103 GLboolean compiling
= ctx
->CompileFlag
;
104 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
105 struct immediate
*im
= TNL_CURRENT_IM(ctx
);
106 GLboolean (*NotifyBegin
)(GLcontext
*ctx
, GLenum p
);
108 NotifyBegin
= tnl
->Driver
.NotifyBegin
;
109 tnl
->Driver
.NotifyBegin
= 0;
112 struct immediate
*tmp
= _tnl_alloc_immediate( ctx
);
113 FLUSH_VERTICES( ctx
, 0 );
114 SET_IMMEDIATE( ctx
, tmp
);
115 TNL_CURRENT_IM(ctx
)->ref_count
++;
116 ctx
->CompileFlag
= GL_FALSE
;
120 for (i
=i1
;i
<=i2
;i
++,u
+=du
) {
121 _tnl_eval_coord1f( ctx
, u
);
125 /* Need this for replay *and* compile:
127 FLUSH_VERTICES( ctx
, 0 );
128 tnl
->Driver
.NotifyBegin
= NotifyBegin
;
131 TNL_CURRENT_IM(ctx
)->ref_count
--;
132 ASSERT( TNL_CURRENT_IM(ctx
)->ref_count
== 0 );
133 _tnl_free_immediate( ctx
, TNL_CURRENT_IM(ctx
) );
134 SET_IMMEDIATE( ctx
, im
);
135 ctx
->CompileFlag
= GL_TRUE
;
143 _tnl_exec_EvalMesh2( GLenum mode
, GLint i1
, GLint i2
, GLint j1
, GLint j2
)
145 GET_CURRENT_CONTEXT(ctx
);
147 GLfloat u
, du
, v
, dv
, v1
, u1
;
148 ASSERT_OUTSIDE_BEGIN_END(ctx
);
150 if (MESA_VERBOSE
& VERBOSE_API
)
151 _mesa_debug(ctx
, "glEvalMesh2()");
153 /* No effect if vertex maps disabled.
155 if (!ctx
->Eval
.Map2Vertex4
&& !ctx
->Eval
.Map2Vertex3
&&
156 (!ctx
->VertexProgram
.Enabled
|| !ctx
->Eval
.Map2Attrib
[VERT_ATTRIB_POS
]))
159 du
= ctx
->Eval
.MapGrid2du
;
160 dv
= ctx
->Eval
.MapGrid2dv
;
161 v1
= ctx
->Eval
.MapGrid2v1
+ j1
* dv
;
162 u1
= ctx
->Eval
.MapGrid2u1
+ i1
* du
;
164 /* Need to turn off compilation -- this is already saved, and the
165 * coordinates generated and the test above depend on state that
166 * may change before the list is executed.
169 GLboolean compiling
= ctx
->CompileFlag
;
170 struct immediate
*im
= TNL_CURRENT_IM(ctx
);
171 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
172 GLboolean (*NotifyBegin
)(GLcontext
*ctx
, GLenum p
);
174 NotifyBegin
= tnl
->Driver
.NotifyBegin
;
175 tnl
->Driver
.NotifyBegin
= 0;
178 struct immediate
*tmp
= _tnl_alloc_immediate( ctx
);
179 FLUSH_VERTICES( ctx
, 0 );
180 SET_IMMEDIATE( ctx
, tmp
);
181 TNL_CURRENT_IM(ctx
)->ref_count
++;
182 ctx
->CompileFlag
= GL_FALSE
;
187 _tnl_Begin( GL_POINTS
);
188 for (v
=v1
,j
=j1
;j
<=j2
;j
++,v
+=dv
) {
189 for (u
=u1
,i
=i1
;i
<=i2
;i
++,u
+=du
) {
190 _tnl_eval_coord2f( ctx
, u
, v
);
196 for (v
=v1
,j
=j1
;j
<=j2
;j
++,v
+=dv
) {
197 _tnl_Begin( GL_LINE_STRIP
);
198 for (u
=u1
,i
=i1
;i
<=i2
;i
++,u
+=du
) {
199 _tnl_eval_coord2f( ctx
, u
, v
);
203 for (u
=u1
,i
=i1
;i
<=i2
;i
++,u
+=du
) {
204 _tnl_Begin( GL_LINE_STRIP
);
205 for (v
=v1
,j
=j1
;j
<=j2
;j
++,v
+=dv
) {
206 _tnl_eval_coord2f( ctx
, u
, v
);
212 for (v
=v1
,j
=j1
;j
<j2
;j
++,v
+=dv
) {
213 _tnl_Begin( GL_TRIANGLE_STRIP
);
214 for (u
=u1
,i
=i1
;i
<=i2
;i
++,u
+=du
) {
215 _tnl_eval_coord2f( ctx
, u
, v
);
216 _tnl_eval_coord2f( ctx
, u
, v
+dv
);
222 _mesa_error( ctx
, GL_INVALID_ENUM
, "glEvalMesh2(mode)" );
226 /* Need this for replay *and* compile:
228 FLUSH_VERTICES( ctx
, 0 );
229 tnl
->Driver
.NotifyBegin
= NotifyBegin
;
232 TNL_CURRENT_IM(ctx
)->ref_count
--;
233 _tnl_free_immediate( ctx
, TNL_CURRENT_IM( ctx
) );
234 SET_IMMEDIATE( ctx
, im
);
235 ctx
->CompileFlag
= GL_TRUE
;
241 void _tnl_eval_init( GLcontext
*ctx
)
243 GLvertexformat
*vfmt
= &(TNL_CONTEXT(ctx
)->vtxfmt
);
244 vfmt
->EvalMesh1
= _tnl_exec_EvalMesh1
;
245 vfmt
->EvalMesh2
= _tnl_exec_EvalMesh2
;