1 /* $Id: api_eval.c,v 1.2 2001/12/14 02:50:01 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
27 * Keith Whitwell <keithw@valinux.com>
35 #include "math/m_eval.h"
37 static void do_EvalCoord1f(GLcontext
* ctx
, GLfloat u
)
41 if (ctx
->Eval
.Map1Index
)
44 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Index
;
45 GLfloat uu
= (u
- map
->u1
) * map
->du
;
46 _math_horner_bezier_curve(map
->Points
, &findex
, uu
, 1, map
->Order
);
47 glIndexi( (GLint
) findex
);
51 if (ctx
->Eval
.Map1Color4
) {
53 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Color4
;
54 GLfloat uu
= (u
- map
->u1
) * map
->du
;
55 _math_horner_bezier_curve(map
->Points
, fcolor
, uu
, 4, map
->Order
);
60 if (ctx
->Eval
.Map1Normal
) {
62 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Normal
;
63 GLfloat uu
= (u
- map
->u1
) * map
->du
;
64 _math_horner_bezier_curve(map
->Points
, normal
, uu
, 3, map
->Order
);
65 glNormal3fv( normal
);
68 /** Texture Coordinates **/
69 if (ctx
->Eval
.Map1TextureCoord4
) {
71 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture4
;
72 GLfloat uu
= (u
- map
->u1
) * map
->du
;
73 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 4, map
->Order
);
74 glTexCoord4fv( texcoord
);
76 else if (ctx
->Eval
.Map1TextureCoord3
) {
78 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture3
;
79 GLfloat uu
= (u
- map
->u1
) * map
->du
;
80 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 3, map
->Order
);
81 glTexCoord3fv( texcoord
);
83 else if (ctx
->Eval
.Map1TextureCoord2
) {
85 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture2
;
86 GLfloat uu
= (u
- map
->u1
) * map
->du
;
87 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 2, map
->Order
);
88 glTexCoord2fv( texcoord
);
90 else if (ctx
->Eval
.Map1TextureCoord1
) {
92 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Texture1
;
93 GLfloat uu
= (u
- map
->u1
) * map
->du
;
94 _math_horner_bezier_curve(map
->Points
, texcoord
, uu
, 1, map
->Order
);
95 glTexCoord1fv( texcoord
);
99 if (ctx
->Eval
.Map1Vertex4
)
102 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex4
;
103 GLfloat uu
= (u
- map
->u1
) * map
->du
;
104 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 4, map
->Order
);
105 glVertex4fv( vertex
);
107 else if (ctx
->Eval
.Map1Vertex3
)
110 struct gl_1d_map
*map
= &ctx
->EvalMap
.Map1Vertex3
;
111 GLfloat uu
= (u
- map
->u1
) * map
->du
;
112 _math_horner_bezier_curve(map
->Points
, vertex
, uu
, 3, map
->Order
);
113 glVertex3fv( vertex
);
117 #define CROSS_PROD(n, u, v) \
118 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
119 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
120 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
123 static void do_EvalCoord2f( GLcontext
* ctx
, GLfloat u
, GLfloat v
)
126 if (ctx
->Eval
.Map2Index
) {
128 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Index
;
129 GLfloat uu
= (u
- map
->u1
) * map
->du
;
130 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
131 _math_horner_bezier_surf(map
->Points
, &findex
, uu
, vv
, 1,
132 map
->Uorder
, map
->Vorder
);
133 glIndexi( (GLuint
) (GLint
) findex
);
137 if (ctx
->Eval
.Map2Color4
) {
139 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Color4
;
140 GLfloat uu
= (u
- map
->u1
) * map
->du
;
141 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
142 _math_horner_bezier_surf(map
->Points
, fcolor
, uu
, vv
, 4,
143 map
->Uorder
, map
->Vorder
);
144 glColor4fv( fcolor
);
148 if (ctx
->Eval
.Map2Normal
&&
149 (!ctx
->Eval
.AutoNormal
|| (!ctx
->Eval
.Map2Vertex3
&&
150 !ctx
->Eval
.Map2Vertex4
))) {
152 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Normal
;
153 GLfloat uu
= (u
- map
->u1
) * map
->du
;
154 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
155 _math_horner_bezier_surf(map
->Points
, normal
, uu
, vv
, 3,
156 map
->Uorder
, map
->Vorder
);
157 glNormal3fv( normal
);
160 /** Texture Coordinates **/
161 if (ctx
->Eval
.Map2TextureCoord4
) {
163 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture4
;
164 GLfloat uu
= (u
- map
->u1
) * map
->du
;
165 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
166 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 4,
167 map
->Uorder
, map
->Vorder
);
168 glTexCoord4fv( texcoord
);
170 else if (ctx
->Eval
.Map2TextureCoord3
) {
172 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture3
;
173 GLfloat uu
= (u
- map
->u1
) * map
->du
;
174 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
175 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 3,
176 map
->Uorder
, map
->Vorder
);
177 glTexCoord3fv( texcoord
);
179 else if (ctx
->Eval
.Map2TextureCoord2
) {
181 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture2
;
182 GLfloat uu
= (u
- map
->u1
) * map
->du
;
183 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
184 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 2,
185 map
->Uorder
, map
->Vorder
);
186 glTexCoord2fv( texcoord
);
188 else if (ctx
->Eval
.Map2TextureCoord1
) {
190 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Texture1
;
191 GLfloat uu
= (u
- map
->u1
) * map
->du
;
192 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
193 _math_horner_bezier_surf(map
->Points
, texcoord
, uu
, vv
, 1,
194 map
->Uorder
, map
->Vorder
);
195 glTexCoord1fv( texcoord
);
199 if(ctx
->Eval
.Map2Vertex4
) {
202 struct gl_2d_map
*map
= &ctx
->EvalMap
.Map2Vertex4
;
203 GLfloat uu
= (u
- map
->u1
) * map
->du
;
204 GLfloat vv
= (v
- map
->v1
) * map
->dv
;
206 if (ctx
->Eval
.AutoNormal
) {
207 GLfloat du
[4], dv
[4];
209 _math_de_casteljau_surf(map
->Points
, vertex
, du
, dv
, uu
, vv
, 4,
210 map
->Uorder
, map
->Vorder
);
212 CROSS_PROD(normal
, du
, dv
);
213 NORMALIZE_3FV(normal
);
216 _math_horner_bezier_surf(map
->Points
, vertex
, uu
, vv
, 4,
217 map
->Uorder
, map
->Vorder
);
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] );