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 <keith@tungstengraphics.com>
33 #include "math/m_eval.h"
35 static void do_EvalCoord1f(GLcontext
* ctx
, GLfloat u
)
39 if (ctx
->Eval
.Map1Index
)
42 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Index
;
43 GLfloat uu
= (u
- map
->u1
) * map
->du
;
44 _math_horner_bezier_curve(map
->Points
, &findex
, uu
, 1, map
->Order
);
45 glIndexi( (GLint
) findex
);
49 if (ctx
->Eval
.Map1Color4
) {
51 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Color4
;
52 GLfloat uu
= (u
- map
->u1
) * map
->du
;
53 _math_horner_bezier_curve(map
->Points
, fcolor
, uu
, 4, map
->Order
);
58 if (ctx
->Eval
.Map1Normal
) {
60 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Normal
;
61 GLfloat uu
= (u
- map
->u1
) * map
->du
;
62 _math_horner_bezier_curve(map
->Points
, normal
, uu
, 3, map
->Order
);
63 glNormal3fv( normal
);
66 /** Texture Coordinates **/
67 if (ctx
->Eval
.Map1TextureCoord4
) {
69 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture4
;
70 GLfloat uu
= (u
- map
->u1
) * map
->du
;
71 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 4, map
->Order
);
72 glTexCoord4fv( texcoord
);
74 else if (ctx
->Eval
.Map1TextureCoord3
) {
76 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture3
;
77 GLfloat uu
= (u
- map
->u1
) * map
->du
;
78 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 3, map
->Order
);
79 glTexCoord3fv( texcoord
);
81 else if (ctx
->Eval
.Map1TextureCoord2
) {
83 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture2
;
84 GLfloat uu
= (u
- map
->u1
) * map
->du
;
85 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 2, map
->Order
);
86 glTexCoord2fv( texcoord
);
88 else if (ctx
->Eval
.Map1TextureCoord1
) {
90 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture1
;
91 GLfloat uu
= (u
- map
->u1
) * map
->du
;
92 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 1, map
->Order
);
93 glTexCoord1fv( texcoord
);
97 if (ctx
->Eval
.Map1Vertex4
)
100 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex4
;
101 GLfloat uu
= (u
- map
->u1
) * map
->du
;
102 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 4, map
->Order
);
103 glVertex4fv( vertex
);
105 else if (ctx
->Eval
.Map1Vertex3
)
108 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex3
;
109 GLfloat uu
= (u
- map
->u1
) * map
->du
;
110 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 3, map
->Order
);
111 glVertex3fv( vertex
);
115 #define CROSS_PROD(n, u, v) \
116 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
117 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
118 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
121 static void do_EvalCoord2f( GLcontext
* ctx
, GLfloat u
, GLfloat v
)
124 if (ctx
->Eval
.Map2Index
) {
126 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Index
;
127 GLfloat uu
= (u
- map
->u1
) * map
->du
;
128 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
129 _math_horner_bezier_surf(map
->Points
, &findex
, uu
, vv
, 1,
130 map
->Uorder
, map
->Vorder
);
131 glIndexi( (GLuint
) (GLint
) findex
);
135 if (ctx
->Eval
.Map2Color4
) {
137 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Color4
;
138 GLfloat uu
= (u
- map
->u1
) * map
->du
;
139 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
140 _math_horner_bezier_surf(map
->Points
, fcolor
, uu
, vv
, 4,
141 map
->Uorder
, map
->Vorder
);
142 glColor4fv( fcolor
);
146 if (ctx
->Eval
.Map2Normal
&&
147 (!ctx
->Eval
.AutoNormal
|| (!ctx
->Eval
.Map2Vertex3
&&
148 !ctx
->Eval
.Map2Vertex4
))) {
150 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Normal
;
151 GLfloat uu
= (u
- map
->u1
) * map
->du
;
152 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
153 _math_horner_bezier_surf(map
->Points
, normal
, uu
, vv
, 3,
154 map
->Uorder
, map
->Vorder
);
155 glNormal3fv( normal
);
158 /** Texture Coordinates **/
159 if (ctx
->Eval
.Map2TextureCoord4
) {
161 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture4
;
162 GLfloat uu
= (u
- map
->u1
) * map
->du
;
163 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
164 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 4,
165 map
->Uorder
, map
->Vorder
);
166 glTexCoord4fv( texcoord
);
168 else if (ctx
->Eval
.Map2TextureCoord3
) {
170 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture3
;
171 GLfloat uu
= (u
- map
->u1
) * map
->du
;
172 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
173 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 3,
174 map
->Uorder
, map
->Vorder
);
175 glTexCoord3fv( texcoord
);
177 else if (ctx
->Eval
.Map2TextureCoord2
) {
179 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture2
;
180 GLfloat uu
= (u
- map
->u1
) * map
->du
;
181 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
182 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 2,
183 map
->Uorder
, map
->Vorder
);
184 glTexCoord2fv( texcoord
);
186 else if (ctx
->Eval
.Map2TextureCoord1
) {
188 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture1
;
189 GLfloat uu
= (u
- map
->u1
) * map
->du
;
190 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
191 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 1,
192 map
->Uorder
, map
->Vorder
);
193 glTexCoord1fv( texcoord
);
197 if(ctx
->Eval
.Map2Vertex4
) {
200 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Vertex4
;
201 GLfloat uu
= (u
- map
->u1
) * map
->du
;
202 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
204 if (ctx
->Eval
.AutoNormal
) {
205 GLfloat du
[4], dv
[4];
207 _math_de_casteljau_surf(map
->Points
, vertex
, du
, dv
, uu
, vv
, 4,
208 map
->Uorder
, map
->Vorder
);
210 CROSS_PROD(normal
, du
, dv
);
211 NORMALIZE_3FV(normal
);
214 _math_horner_bezier_surf(map
->Points
, vertex
, uu
, vv
, 4,
215 map
->Uorder
, map
->Vorder
);
218 else if (ctx
->Eval
.Map2Vertex3
) {
220 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Vertex3
;
221 GLfloat uu
= (u
- map
->u1
) * map
->du
;
222 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
223 if (ctx
->Eval
.AutoNormal
) {
224 GLfloat du
[3], dv
[3];
226 _math_de_casteljau_surf(map
->Points
, vertex
, du
, dv
, uu
, vv
, 3,
227 map
->Uorder
, map
->Vorder
);
228 CROSS_PROD(normal
, du
, dv
);
229 NORMALIZE_3FV(normal
);
230 glNormal3fv( normal
);
231 glVertex3fv( vertex
);
234 _math_horner_bezier_surf(map
->Points
, vertex
, uu
, vv
, 3,
235 map
->Uorder
, map
->Vorder
);
236 glVertex3fv( vertex
);
242 void _mesa_EvalPoint1( GLint i
)
244 GET_CURRENT_CONTEXT( ctx
);
245 GLfloat du
= ((ctx
->Eval
.MapGrid1u2
- ctx
->Eval
.MapGrid1u1
) /
246 (GLfloat
) ctx
->Eval
.MapGrid1un
);
247 GLfloat u
= i
* du
+ ctx
->Eval
.MapGrid1u1
;
253 void _mesa_EvalPoint2( GLint i
, GLint j
)
255 GET_CURRENT_CONTEXT( ctx
);
256 GLfloat du
= ((ctx
->Eval
.MapGrid2u2
- ctx
->Eval
.MapGrid2u1
) /
257 (GLfloat
) ctx
->Eval
.MapGrid2un
);
258 GLfloat dv
= ((ctx
->Eval
.MapGrid2v2
- ctx
->Eval
.MapGrid2v1
) /
259 (GLfloat
) ctx
->Eval
.MapGrid2vn
);
260 GLfloat u
= i
* du
+ ctx
->Eval
.MapGrid2u1
;
261 GLfloat v
= j
* dv
+ ctx
->Eval
.MapGrid2v1
;
263 glEvalCoord2f( u
, v
);
266 /* Wierd thing about eval is that it doesn't affect 'current' values.
267 * This technique of saving and resetting current values requires
270 * 1) Current values are updated immediately in the glColor,
273 * 2) Hardware color values are stored seperately from ctx->Current,
274 * for example in dma buffers, or direct emit to registers.
276 void _mesa_EvalCoord1f( GLfloat u
)
278 GET_CURRENT_CONTEXT( ctx
);
279 GLfloat normal
[3], texcoord
[4], color
[4];
282 COPY_3FV( normal
, ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
] );
283 COPY_4FV( texcoord
, ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
] );
284 COPY_4FV( color
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
] );
285 index
= ctx
->Current
.Index
;
287 do_EvalCoord1f( ctx
, u
);
289 COPY_3FV( ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
], normal
);
290 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
], texcoord
);
291 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
], color
);
292 ctx
->Current
.Index
= index
;
295 void _mesa_EvalCoord2f( GLfloat u
, GLfloat v
)
297 GET_CURRENT_CONTEXT( ctx
);
298 GLfloat normal
[3], texcoord
[4], color
[4];
301 COPY_3FV( normal
, ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
] );
302 COPY_4FV( texcoord
, ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
] );
303 COPY_4FV( color
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
] );
304 index
= ctx
->Current
.Index
;
306 do_EvalCoord2f( ctx
, u
, v
);
308 COPY_3FV( ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
], normal
);
309 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
], texcoord
);
310 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
], color
);
311 ctx
->Current
.Index
= index
;
314 void _mesa_EvalCoord1fv( const GLfloat
*u
)
316 glEvalCoord1f( u
[0] );
319 void _mesa_EvalCoord2fv( const GLfloat
*u
)
321 glEvalCoord2f( u
[0], u
[1] );