2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
32 #include "math/m_eval.h"
34 static void do_EvalCoord1f(GLcontext
* ctx
, GLfloat u
)
38 if (ctx
->Eval
.Map1Index
)
41 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Index
;
42 GLfloat uu
= (u
- map
->u1
) * map
->du
;
43 _math_horner_bezier_curve(map
->Points
, &findex
, uu
, 1, map
->Order
);
44 glIndexi( (GLint
) findex
);
48 if (ctx
->Eval
.Map1Color4
) {
50 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Color4
;
51 GLfloat uu
= (u
- map
->u1
) * map
->du
;
52 _math_horner_bezier_curve(map
->Points
, fcolor
, uu
, 4, map
->Order
);
57 if (ctx
->Eval
.Map1Normal
) {
59 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Normal
;
60 GLfloat uu
= (u
- map
->u1
) * map
->du
;
61 _math_horner_bezier_curve(map
->Points
, normal
, uu
, 3, map
->Order
);
62 glNormal3fv( normal
);
65 /** Texture Coordinates **/
66 if (ctx
->Eval
.Map1TextureCoord4
) {
68 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture4
;
69 GLfloat uu
= (u
- map
->u1
) * map
->du
;
70 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 4, map
->Order
);
71 glTexCoord4fv( texcoord
);
73 else if (ctx
->Eval
.Map1TextureCoord3
) {
75 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture3
;
76 GLfloat uu
= (u
- map
->u1
) * map
->du
;
77 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 3, map
->Order
);
78 glTexCoord3fv( texcoord
);
80 else if (ctx
->Eval
.Map1TextureCoord2
) {
82 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture2
;
83 GLfloat uu
= (u
- map
->u1
) * map
->du
;
84 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 2, map
->Order
);
85 glTexCoord2fv( texcoord
);
87 else if (ctx
->Eval
.Map1TextureCoord1
) {
89 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture1
;
90 GLfloat uu
= (u
- map
->u1
) * map
->du
;
91 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 1, map
->Order
);
92 glTexCoord1fv( texcoord
);
96 if (ctx
->Eval
.Map1Vertex4
)
99 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex4
;
100 GLfloat uu
= (u
- map
->u1
) * map
->du
;
101 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 4, map
->Order
);
102 glVertex4fv( vertex
);
104 else if (ctx
->Eval
.Map1Vertex3
)
107 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex3
;
108 GLfloat uu
= (u
- map
->u1
) * map
->du
;
109 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 3, map
->Order
);
110 glVertex3fv( vertex
);
114 #define CROSS_PROD(n, u, v) \
115 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
116 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
117 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
120 static void do_EvalCoord2f( GLcontext
* ctx
, GLfloat u
, GLfloat v
)
123 if (ctx
->Eval
.Map2Index
) {
125 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Index
;
126 GLfloat uu
= (u
- map
->u1
) * map
->du
;
127 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
128 _math_horner_bezier_surf(map
->Points
, &findex
, uu
, vv
, 1,
129 map
->Uorder
, map
->Vorder
);
130 glIndexi( (GLuint
) (GLint
) findex
);
134 if (ctx
->Eval
.Map2Color4
) {
136 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Color4
;
137 GLfloat uu
= (u
- map
->u1
) * map
->du
;
138 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
139 _math_horner_bezier_surf(map
->Points
, fcolor
, uu
, vv
, 4,
140 map
->Uorder
, map
->Vorder
);
141 glColor4fv( fcolor
);
145 if (ctx
->Eval
.Map2Normal
&&
146 (!ctx
->Eval
.AutoNormal
|| (!ctx
->Eval
.Map2Vertex3
&&
147 !ctx
->Eval
.Map2Vertex4
))) {
149 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Normal
;
150 GLfloat uu
= (u
- map
->u1
) * map
->du
;
151 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
152 _math_horner_bezier_surf(map
->Points
, normal
, uu
, vv
, 3,
153 map
->Uorder
, map
->Vorder
);
154 glNormal3fv( normal
);
157 /** Texture Coordinates **/
158 if (ctx
->Eval
.Map2TextureCoord4
) {
160 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture4
;
161 GLfloat uu
= (u
- map
->u1
) * map
->du
;
162 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
163 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 4,
164 map
->Uorder
, map
->Vorder
);
165 glTexCoord4fv( texcoord
);
167 else if (ctx
->Eval
.Map2TextureCoord3
) {
169 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture3
;
170 GLfloat uu
= (u
- map
->u1
) * map
->du
;
171 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
172 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 3,
173 map
->Uorder
, map
->Vorder
);
174 glTexCoord3fv( texcoord
);
176 else if (ctx
->Eval
.Map2TextureCoord2
) {
178 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture2
;
179 GLfloat uu
= (u
- map
->u1
) * map
->du
;
180 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
181 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 2,
182 map
->Uorder
, map
->Vorder
);
183 glTexCoord2fv( texcoord
);
185 else if (ctx
->Eval
.Map2TextureCoord1
) {
187 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture1
;
188 GLfloat uu
= (u
- map
->u1
) * map
->du
;
189 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
190 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 1,
191 map
->Uorder
, map
->Vorder
);
192 glTexCoord1fv( texcoord
);
196 if(ctx
->Eval
.Map2Vertex4
) {
199 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Vertex4
;
200 GLfloat uu
= (u
- map
->u1
) * map
->du
;
201 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
203 if (ctx
->Eval
.AutoNormal
) {
204 GLfloat du
[4], dv
[4];
206 _math_de_casteljau_surf(map
->Points
, vertex
, du
, dv
, uu
, vv
, 4,
207 map
->Uorder
, map
->Vorder
);
209 CROSS_PROD(normal
, du
, dv
);
210 NORMALIZE_3FV(normal
);
211 glNormal3fv( normal
);
212 glVertex4fv( vertex
);
215 _math_horner_bezier_surf(map
->Points
, vertex
, uu
, vv
, 4,
216 map
->Uorder
, map
->Vorder
);
217 glVertex4fv( vertex
);
220 else if (ctx
->Eval
.Map2Vertex3
) {
222 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Vertex3
;
223 GLfloat uu
= (u
- map
->u1
) * map
->du
;
224 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
225 if (ctx
->Eval
.AutoNormal
) {
226 GLfloat du
[3], dv
[3];
228 _math_de_casteljau_surf(map
->Points
, vertex
, du
, dv
, uu
, vv
, 3,
229 map
->Uorder
, map
->Vorder
);
230 CROSS_PROD(normal
, du
, dv
);
231 NORMALIZE_3FV(normal
);
232 glNormal3fv( normal
);
233 glVertex3fv( vertex
);
236 _math_horner_bezier_surf(map
->Points
, vertex
, uu
, vv
, 3,
237 map
->Uorder
, map
->Vorder
);
238 glVertex3fv( vertex
);
244 void _mesa_EvalPoint1( GLint i
)
246 GET_CURRENT_CONTEXT( ctx
);
247 GLfloat du
= ((ctx
->Eval
.MapGrid1u2
- ctx
->Eval
.MapGrid1u1
) /
248 (GLfloat
) ctx
->Eval
.MapGrid1un
);
249 GLfloat u
= i
* du
+ ctx
->Eval
.MapGrid1u1
;
255 void _mesa_EvalPoint2( GLint i
, GLint j
)
257 GET_CURRENT_CONTEXT( ctx
);
258 GLfloat du
= ((ctx
->Eval
.MapGrid2u2
- ctx
->Eval
.MapGrid2u1
) /
259 (GLfloat
) ctx
->Eval
.MapGrid2un
);
260 GLfloat dv
= ((ctx
->Eval
.MapGrid2v2
- ctx
->Eval
.MapGrid2v1
) /
261 (GLfloat
) ctx
->Eval
.MapGrid2vn
);
262 GLfloat u
= i
* du
+ ctx
->Eval
.MapGrid2u1
;
263 GLfloat v
= j
* dv
+ ctx
->Eval
.MapGrid2v1
;
265 glEvalCoord2f( u
, v
);
268 /* Wierd thing about eval is that it doesn't affect 'current' values.
269 * This technique of saving and resetting current values requires
272 * 1) Current values are updated immediately in the glColor,
275 * 2) Hardware color values are stored seperately from ctx->Current,
276 * for example in dma buffers, or direct emit to registers.
278 void _mesa_EvalCoord1f( GLfloat u
)
280 GET_CURRENT_CONTEXT( ctx
);
281 GLfloat normal
[3], texcoord
[4], color
[4];
284 COPY_3FV( normal
, ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
] );
285 COPY_4FV( texcoord
, ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
] );
286 COPY_4FV( color
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
] );
287 index
= ctx
->Current
.Index
;
289 do_EvalCoord1f( ctx
, u
);
291 COPY_3FV( ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
], normal
);
292 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
], texcoord
);
293 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
], color
);
294 ctx
->Current
.Index
= index
;
297 void _mesa_EvalCoord2f( GLfloat u
, GLfloat v
)
299 GET_CURRENT_CONTEXT( ctx
);
300 GLfloat normal
[3], texcoord
[4], color
[4];
303 COPY_3FV( normal
, ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
] );
304 COPY_4FV( texcoord
, ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
] );
305 COPY_4FV( color
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
] );
306 index
= ctx
->Current
.Index
;
308 do_EvalCoord2f( ctx
, u
, v
);
310 COPY_3FV( ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
], normal
);
311 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
], texcoord
);
312 COPY_4FV( ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
], color
);
313 ctx
->Current
.Index
= index
;
316 void _mesa_EvalCoord1fv( const GLfloat
*u
)
318 glEvalCoord1f( u
[0] );
321 void _mesa_EvalCoord2fv( const GLfloat
*u
)
323 glEvalCoord2f( u
[0], u
[1] );