xref: /reactos/dll/opengl/mesa/eval.c (revision 5f2bebf7)
1 /* $Id: eval.c,v 1.9 1998/02/03 00:53:51 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version:  2.6
6  * Copyright (C) 1995-1997  Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: eval.c,v $
26  * Revision 1.9  1998/02/03 00:53:51  brianp
27  * fixed bug in gl_copy_map_points*() functions (Sam Jordan)
28  *
29  * Revision 1.8  1997/07/24 01:25:01  brianp
30  * changed precompiled header symbol from PCH to PC_HEADER
31  *
32  * Revision 1.7  1997/06/20 01:58:47  brianp
33  * changed color components from GLfixed to GLubyte
34  *
35  * Revision 1.6  1997/05/28 03:24:22  brianp
36  * added precompiled header (PCH) support
37  *
38  * Revision 1.5  1997/05/14 03:27:04  brianp
39  * removed context argument from gl_init_eval()
40  *
41  * Revision 1.4  1997/05/01 01:38:38  brianp
42  * use NORMALIZE_3FV() from mmath.h instead of private NORMALIZE() macro
43  *
44  * Revision 1.3  1997/04/02 03:10:58  brianp
45  * changed some #include's
46  *
47  * Revision 1.2  1996/09/15 14:17:30  brianp
48  * now use GLframebuffer and GLvisual
49  *
50  * Revision 1.1  1996/09/13 01:38:16  brianp
51  * Initial revision
52  *
53  */
54 
55 
56 /*
57  * eval.c was written by
58  * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
59  * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
60  *
61  * My original implementation of evaluators was simplistic and didn't
62  * compute surface normal vectors properly.  Bernd and Volker applied
63  * used more sophisticated methods to get better results.
64  *
65  * Thanks guys!
66  */
67 
68 
69 #ifdef PC_HEADER
70 #include "all.h"
71 #else
72 #include <math.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include "context.h"
76 #include "eval.h"
77 #include "dlist.h"
78 #include "macros.h"
79 #include "mmath.h"
80 #include "types.h"
81 #include "vbfill.h"
82 #endif
83 
84 
85 
86 /*
87  * Do one-time initialization for evaluators.
88  */
gl_init_eval(void)89 void gl_init_eval( void )
90 {
91   static int init_flag = 0;
92 
93   /* Compute a table of nCr (combination) values used by the
94    * Bernstein polynomial generator.
95    */
96 
97   if (init_flag==0)
98   { /* no initialization needed */
99   }
100 
101   init_flag = 1;
102 }
103 
104 
105 
106 /*
107  * Horner scheme for Bezier curves
108  *
109  * Bezier curves can be computed via a Horner scheme.
110  * Horner is numerically less stable than the de Casteljau
111  * algorithm, but it is faster. For curves of degree n
112  * the complexity of Horner is O(n) and de Casteljau is O(n^2).
113  * Since stability is not important for displaying curve
114  * points I decided to use the Horner scheme.
115  *
116  * A cubic Bezier curve with control points b0, b1, b2, b3 can be
117  * written as
118  *
119  *        (([3]        [3]     )     [3]       )     [3]
120  * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3
121  *
122  *                                           [n]
123  * where s=1-t and the binomial coefficients [i]. These can
124  * be computed iteratively using the identity:
125  *
126  * [n]               [n  ]             [n]
127  * [i] = (n-i+1)/i * [i-1]     and     [0] = 1
128  */
129 
130 static void
horner_bezier_curve(GLfloat * cp,GLfloat * out,GLfloat t,GLuint dim,GLuint order)131 horner_bezier_curve(GLfloat *cp, GLfloat *out, GLfloat t,
132                     GLuint dim, GLuint order)
133 {
134   GLfloat s, powert;
135   GLuint i, k, bincoeff;
136 
137   if(order >= 2)
138   {
139     bincoeff = order-1;
140     s = 1.0-t;
141 
142     for(k=0; k<dim; k++)
143       out[k] = s*cp[k] + bincoeff*t*cp[dim+k];
144 
145     for(i=2, cp+=2*dim, powert=t*t; i<order; i++, powert*=t, cp +=dim)
146     {
147       bincoeff *= order-i;
148       bincoeff /= i;
149 
150       for(k=0; k<dim; k++)
151         out[k] = s*out[k] + bincoeff*powert*cp[k];
152     }
153   }
154   else /* order=1 -> constant curve */
155   {
156     for(k=0; k<dim; k++)
157       out[k] = cp[k];
158   }
159 }
160 
161 /*
162  * Tensor product Bezier surfaces
163  *
164  * Again the Horner scheme is used to compute a point on a
165  * TP Bezier surface. First a control polygon for a curve
166  * on the surface in one parameter direction is computed,
167  * then the point on the curve for the other parameter
168  * direction is evaluated.
169  *
170  * To store the curve control polygon additional storage
171  * for max(uorder,vorder) points is needed in the
172  * control net cn.
173  */
174 
175 static void
horner_bezier_surf(GLfloat * cn,GLfloat * out,GLfloat u,GLfloat v,GLuint dim,GLuint uorder,GLuint vorder)176 horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v,
177                    GLuint dim, GLuint uorder, GLuint vorder)
178 {
179   GLfloat *cp = cn + uorder*vorder*dim;
180   GLuint i, uinc = vorder*dim;
181 
182   if(vorder > uorder)
183   {
184     if(uorder >= 2)
185     {
186       GLfloat s, poweru;
187       GLuint j, k, bincoeff;
188 
189       /* Compute the control polygon for the surface-curve in u-direction */
190       for(j=0; j<vorder; j++)
191       {
192         GLfloat *ucp = &cn[j*dim];
193 
194         /* Each control point is the point for parameter u on a */
195         /* curve defined by the control polygons in u-direction */
196 	bincoeff = uorder-1;
197 	s = 1.0-u;
198 
199 	for(k=0; k<dim; k++)
200 	  cp[j*dim+k] = s*ucp[k] + bincoeff*u*ucp[uinc+k];
201 
202 	for(i=2, ucp+=2*uinc, poweru=u*u; i<uorder;
203             i++, poweru*=u, ucp +=uinc)
204 	{
205 	  bincoeff *= uorder-i;
206           bincoeff /= i;
207 
208 	  for(k=0; k<dim; k++)
209 	    cp[j*dim+k] = s*cp[j*dim+k] + bincoeff*poweru*ucp[k];
210 	}
211       }
212 
213       /* Evaluate curve point in v */
214       horner_bezier_curve(cp, out, v, dim, vorder);
215     }
216     else /* uorder=1 -> cn defines a curve in v */
217       horner_bezier_curve(cn, out, v, dim, vorder);
218   }
219   else /* vorder <= uorder */
220   {
221     if(vorder > 1)
222     {
223       GLuint i;
224 
225       /* Compute the control polygon for the surface-curve in u-direction */
226       for(i=0; i<uorder; i++, cn += uinc)
227       {
228 	/* For constant i all cn[i][j] (j=0..vorder) are located */
229 	/* on consecutive memory locations, so we can use        */
230 	/* horner_bezier_curve to compute the control points     */
231 
232 	horner_bezier_curve(cn, &cp[i*dim], v, dim, vorder);
233       }
234 
235       /* Evaluate curve point in u */
236       horner_bezier_curve(cp, out, u, dim, uorder);
237     }
238     else  /* vorder=1 -> cn defines a curve in u */
239       horner_bezier_curve(cn, out, u, dim, uorder);
240   }
241 }
242 
243 /*
244  * The direct de Casteljau algorithm is used when a point on the
245  * surface and the tangent directions spanning the tangent plane
246  * should be computed (this is needed to compute normals to the
247  * surface). In this case the de Casteljau algorithm approach is
248  * nicer because a point and the partial derivatives can be computed
249  * at the same time. To get the correct tangent length du and dv
250  * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1.
251  * Since only the directions are needed, this scaling step is omitted.
252  *
253  * De Casteljau needs additional storage for uorder*vorder
254  * values in the control net cn.
255  */
256 
257 static void
de_casteljau_surf(GLfloat * cn,GLfloat * out,GLfloat * du,GLfloat * dv,GLfloat u,GLfloat v,GLuint dim,GLuint uorder,GLuint vorder)258 de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv,
259                   GLfloat u, GLfloat v, GLuint dim,
260                   GLuint uorder, GLuint vorder)
261 {
262   GLfloat *dcn = cn + uorder*vorder*dim;
263   GLfloat us = 1.0-u, vs = 1.0-v;
264   GLuint h, i, j, k;
265   GLuint minorder = uorder < vorder ? uorder : vorder;
266   GLuint uinc = vorder*dim;
267   GLuint dcuinc = vorder;
268 
269   /* Each component is evaluated separately to save buffer space  */
270   /* This does not drasticaly decrease the performance of the     */
271   /* algorithm. If additional storage for (uorder-1)*(vorder-1)   */
272   /* points would be available, the components could be accessed  */
273   /* in the innermost loop which could lead to less cache misses. */
274 
275 #define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)]
276 #define DCN(I, J) dcn[(I)*dcuinc+(J)]
277   if(minorder < 3)
278   {
279     if(uorder==vorder)
280     {
281       for(k=0; k<dim; k++)
282       {
283 	/* Derivative direction in u */
284 	du[k] = vs*(CN(1,0,k) - CN(0,0,k)) +
285 	         v*(CN(1,1,k) - CN(0,1,k));
286 
287 	/* Derivative direction in v */
288 	dv[k] = us*(CN(0,1,k) - CN(0,0,k)) +
289 	         u*(CN(1,1,k) - CN(1,0,k));
290 
291 	/* bilinear de Casteljau step */
292         out[k] =  us*(vs*CN(0,0,k) + v*CN(0,1,k)) +
293 	           u*(vs*CN(1,0,k) + v*CN(1,1,k));
294       }
295     }
296     else if(minorder == uorder)
297     {
298       for(k=0; k<dim; k++)
299       {
300 	/* bilinear de Casteljau step */
301 	DCN(1,0) =    CN(1,0,k) -   CN(0,0,k);
302 	DCN(0,0) = us*CN(0,0,k) + u*CN(1,0,k);
303 
304 	for(j=0; j<vorder-1; j++)
305 	{
306 	  /* for the derivative in u */
307 	  DCN(1,j+1) =    CN(1,j+1,k) -   CN(0,j+1,k);
308 	  DCN(1,j)   = vs*DCN(1,j)    + v*DCN(1,j+1);
309 
310 	  /* for the `point' */
311 	  DCN(0,j+1) = us*CN(0,j+1,k) + u*CN(1,j+1,k);
312 	  DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
313 	}
314 
315 	/* remaining linear de Casteljau steps until the second last step */
316 	for(h=minorder; h<vorder-1; h++)
317 	  for(j=0; j<vorder-h; j++)
318 	  {
319 	    /* for the derivative in u */
320 	    DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1);
321 
322 	    /* for the `point' */
323 	    DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
324 	  }
325 
326 	/* derivative direction in v */
327 	dv[k] = DCN(0,1) - DCN(0,0);
328 
329 	/* derivative direction in u */
330 	du[k] =   vs*DCN(1,0) + v*DCN(1,1);
331 
332 	/* last linear de Casteljau step */
333 	out[k] =  vs*DCN(0,0) + v*DCN(0,1);
334       }
335     }
336     else /* minorder == vorder */
337     {
338       for(k=0; k<dim; k++)
339       {
340 	/* bilinear de Casteljau step */
341 	DCN(0,1) =    CN(0,1,k) -   CN(0,0,k);
342 	DCN(0,0) = vs*CN(0,0,k) + v*CN(0,1,k);
343 	for(i=0; i<uorder-1; i++)
344 	{
345 	  /* for the derivative in v */
346 	  DCN(i+1,1) =    CN(i+1,1,k) -   CN(i+1,0,k);
347 	  DCN(i,1)   = us*DCN(i,1)    + u*DCN(i+1,1);
348 
349 	  /* for the `point' */
350 	  DCN(i+1,0) = vs*CN(i+1,0,k) + v*CN(i+1,1,k);
351 	  DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
352 	}
353 
354 	/* remaining linear de Casteljau steps until the second last step */
355 	for(h=minorder; h<uorder-1; h++)
356 	  for(i=0; i<uorder-h; i++)
357 	  {
358 	    /* for the derivative in v */
359 	    DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1);
360 
361 	    /* for the `point' */
362 	    DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
363 	  }
364 
365 	/* derivative direction in u */
366 	du[k] = DCN(1,0) - DCN(0,0);
367 
368 	/* derivative direction in v */
369 	dv[k] =   us*DCN(0,1) + u*DCN(1,1);
370 
371 	/* last linear de Casteljau step */
372 	out[k] =  us*DCN(0,0) + u*DCN(1,0);
373       }
374     }
375   }
376   else if(uorder == vorder)
377   {
378     for(k=0; k<dim; k++)
379     {
380       /* first bilinear de Casteljau step */
381       for(i=0; i<uorder-1; i++)
382       {
383 	DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
384 	for(j=0; j<vorder-1; j++)
385 	{
386 	  DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
387 	  DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
388 	}
389       }
390 
391       /* remaining bilinear de Casteljau steps until the second last step */
392       for(h=2; h<minorder-1; h++)
393 	for(i=0; i<uorder-h; i++)
394 	{
395 	  DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
396 	  for(j=0; j<vorder-h; j++)
397 	  {
398 	    DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
399 	    DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
400 	  }
401 	}
402 
403       /* derivative direction in u */
404       du[k] = vs*(DCN(1,0) - DCN(0,0)) +
405 	       v*(DCN(1,1) - DCN(0,1));
406 
407       /* derivative direction in v */
408       dv[k] = us*(DCN(0,1) - DCN(0,0)) +
409 	       u*(DCN(1,1) - DCN(1,0));
410 
411       /* last bilinear de Casteljau step */
412       out[k] =  us*(vs*DCN(0,0) + v*DCN(0,1)) +
413 	         u*(vs*DCN(1,0) + v*DCN(1,1));
414     }
415   }
416   else if(minorder == uorder)
417   {
418     for(k=0; k<dim; k++)
419     {
420       /* first bilinear de Casteljau step */
421       for(i=0; i<uorder-1; i++)
422       {
423 	DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
424 	for(j=0; j<vorder-1; j++)
425 	{
426 	  DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
427 	  DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
428 	}
429       }
430 
431       /* remaining bilinear de Casteljau steps until the second last step */
432       for(h=2; h<minorder-1; h++)
433 	for(i=0; i<uorder-h; i++)
434 	{
435 	  DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
436 	  for(j=0; j<vorder-h; j++)
437 	  {
438 	    DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
439 	    DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
440 	  }
441 	}
442 
443       /* last bilinear de Casteljau step */
444       DCN(2,0) =    DCN(1,0) -   DCN(0,0);
445       DCN(0,0) = us*DCN(0,0) + u*DCN(1,0);
446       for(j=0; j<vorder-1; j++)
447       {
448 	/* for the derivative in u */
449 	DCN(2,j+1) =    DCN(1,j+1) -    DCN(0,j+1);
450 	DCN(2,j)   = vs*DCN(2,j)    + v*DCN(2,j+1);
451 
452 	/* for the `point' */
453 	DCN(0,j+1) = us*DCN(0,j+1 ) + u*DCN(1,j+1);
454 	DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
455       }
456 
457       /* remaining linear de Casteljau steps until the second last step */
458       for(h=minorder; h<vorder-1; h++)
459 	for(j=0; j<vorder-h; j++)
460 	{
461 	  /* for the derivative in u */
462 	  DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1);
463 
464 	  /* for the `point' */
465 	  DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
466 	}
467 
468       /* derivative direction in v */
469       dv[k] = DCN(0,1) - DCN(0,0);
470 
471       /* derivative direction in u */
472       du[k] =   vs*DCN(2,0) + v*DCN(2,1);
473 
474       /* last linear de Casteljau step */
475       out[k] =  vs*DCN(0,0) + v*DCN(0,1);
476     }
477   }
478   else /* minorder == vorder */
479   {
480     for(k=0; k<dim; k++)
481     {
482       /* first bilinear de Casteljau step */
483       for(i=0; i<uorder-1; i++)
484       {
485 	DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
486 	for(j=0; j<vorder-1; j++)
487 	{
488 	  DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
489 	  DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
490 	}
491       }
492 
493       /* remaining bilinear de Casteljau steps until the second last step */
494       for(h=2; h<minorder-1; h++)
495 	for(i=0; i<uorder-h; i++)
496 	{
497 	  DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
498 	  for(j=0; j<vorder-h; j++)
499 	  {
500 	    DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
501 	    DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
502 	  }
503 	}
504 
505       /* last bilinear de Casteljau step */
506       DCN(0,2) =    DCN(0,1) -   DCN(0,0);
507       DCN(0,0) = vs*DCN(0,0) + v*DCN(0,1);
508       for(i=0; i<uorder-1; i++)
509       {
510 	/* for the derivative in v */
511 	DCN(i+1,2) =    DCN(i+1,1)  -   DCN(i+1,0);
512 	DCN(i,2)   = us*DCN(i,2)    + u*DCN(i+1,2);
513 
514 	/* for the `point' */
515 	DCN(i+1,0) = vs*DCN(i+1,0)  + v*DCN(i+1,1);
516 	DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
517       }
518 
519       /* remaining linear de Casteljau steps until the second last step */
520       for(h=minorder; h<uorder-1; h++)
521 	for(i=0; i<uorder-h; i++)
522 	{
523 	  /* for the derivative in v */
524 	  DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2);
525 
526 	  /* for the `point' */
527 	  DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
528 	}
529 
530       /* derivative direction in u */
531       du[k] = DCN(1,0) - DCN(0,0);
532 
533       /* derivative direction in v */
534       dv[k] =   us*DCN(0,2) + u*DCN(1,2);
535 
536       /* last linear de Casteljau step */
537       out[k] =  us*DCN(0,0) + u*DCN(1,0);
538     }
539   }
540 #undef DCN
541 #undef CN
542 }
543 
544 /*
545  * Return the number of components per control point for any type of
546  * evaluator.  Return 0 if bad target.
547  */
548 
components(GLenum target)549 static GLint components( GLenum target )
550 {
551    switch (target) {
552       case GL_MAP1_VERTEX_3:		return 3;
553       case GL_MAP1_VERTEX_4:		return 4;
554       case GL_MAP1_INDEX:		return 1;
555       case GL_MAP1_COLOR_4:		return 4;
556       case GL_MAP1_NORMAL:		return 3;
557       case GL_MAP1_TEXTURE_COORD_1:	return 1;
558       case GL_MAP1_TEXTURE_COORD_2:	return 2;
559       case GL_MAP1_TEXTURE_COORD_3:	return 3;
560       case GL_MAP1_TEXTURE_COORD_4:	return 4;
561       case GL_MAP2_VERTEX_3:		return 3;
562       case GL_MAP2_VERTEX_4:		return 4;
563       case GL_MAP2_INDEX:		return 1;
564       case GL_MAP2_COLOR_4:		return 4;
565       case GL_MAP2_NORMAL:		return 3;
566       case GL_MAP2_TEXTURE_COORD_1:	return 1;
567       case GL_MAP2_TEXTURE_COORD_2:	return 2;
568       case GL_MAP2_TEXTURE_COORD_3:	return 3;
569       case GL_MAP2_TEXTURE_COORD_4:	return 4;
570       default:				return 0;
571    }
572 }
573 
574 
575 /**********************************************************************/
576 /***            Copy and deallocate control points                  ***/
577 /**********************************************************************/
578 
579 
580 /*
581  * Copy 1-parametric evaluator control points from user-specified
582  * memory space to a buffer of contiguous control points.
583  * Input:  see glMap1f for details
584  * Return:  pointer to buffer of contiguous control points or NULL if out
585  *          of memory.
586  */
gl_copy_map_points1f(GLenum target,GLint ustride,GLint uorder,const GLfloat * points)587 GLfloat *gl_copy_map_points1f( GLenum target,
588                                GLint ustride, GLint uorder,
589                                const GLfloat *points )
590 {
591    GLfloat *buffer, *p;
592    GLuint i, k, size = components(target);
593 
594    if (!points || size==0) {
595       return NULL;
596    }
597 
598    buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
599 
600    if(buffer)
601       for(i=0, p=buffer; i<uorder; i++, points+=ustride)
602 	for(k=0; k<size; k++)
603 	  *p++ = points[k];
604 
605    return buffer;
606 }
607 
608 
609 
610 /*
611  * Same as above but convert doubles to floats.
612  */
gl_copy_map_points1d(GLenum target,GLint ustride,GLint uorder,const GLdouble * points)613 GLfloat *gl_copy_map_points1d( GLenum target,
614 			        GLint ustride, GLint uorder,
615 			        const GLdouble *points )
616 {
617    GLfloat *buffer, *p;
618    GLuint i, k, size = components(target);
619 
620    if (!points || size==0) {
621       return NULL;
622    }
623 
624    buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
625 
626    if(buffer)
627       for(i=0, p=buffer; i<uorder; i++, points+=ustride)
628 	for(k=0; k<size; k++)
629 	  *p++ = (GLfloat) points[k];
630 
631    return buffer;
632 }
633 
634 
635 
636 /*
637  * Copy 2-parametric evaluator control points from user-specified
638  * memory space to a buffer of contiguous control points.
639  * Additional memory is allocated to be used by the horner and
640  * de Casteljau evaluation schemes.
641  *
642  * Input:  see glMap2f for details
643  * Return:  pointer to buffer of contiguous control points or NULL if out
644  *          of memory.
645  */
gl_copy_map_points2f(GLenum target,GLint ustride,GLint uorder,GLint vstride,GLint vorder,const GLfloat * points)646 GLfloat *gl_copy_map_points2f( GLenum target,
647 			        GLint ustride, GLint uorder,
648 			        GLint vstride, GLint vorder,
649 			        const GLfloat *points )
650 {
651    GLfloat *buffer, *p;
652    GLuint i, j, k, size, dsize, hsize;
653    GLint uinc;
654 
655    size = components(target);
656 
657    if (!points || size==0) {
658       return NULL;
659    }
660 
661    /* max(uorder, vorder) additional points are used in      */
662    /* horner evaluation and uorder*vorder additional */
663    /* values are needed for de Casteljau                     */
664    dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
665    hsize = (uorder > vorder ? uorder : vorder)*size;
666 
667    if(hsize>dsize)
668      buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
669    else
670      buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
671 
672    /* compute the increment value for the u-loop */
673    uinc = ustride - vorder*vstride;
674 
675    if (buffer)
676       for (i=0, p=buffer; i<uorder; i++, points += uinc)
677 	 for (j=0; j<vorder; j++, points += vstride)
678 	    for (k=0; k<size; k++)
679 	       *p++ = points[k];
680 
681    return buffer;
682 }
683 
684 
685 
686 /*
687  * Same as above but convert doubles to floats.
688  */
gl_copy_map_points2d(GLenum target,GLint ustride,GLint uorder,GLint vstride,GLint vorder,const GLdouble * points)689 GLfloat *gl_copy_map_points2d(GLenum target,
690                               GLint ustride, GLint uorder,
691                               GLint vstride, GLint vorder,
692                               const GLdouble *points )
693 {
694    GLfloat *buffer, *p;
695    GLuint i, j, k, size, hsize, dsize;
696    GLint uinc;
697 
698    size = components(target);
699 
700    if (!points || size==0) {
701       return NULL;
702    }
703 
704    /* max(uorder, vorder) additional points are used in      */
705    /* horner evaluation and uorder*vorder additional */
706    /* values are needed for de Casteljau                     */
707    dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
708    hsize = (uorder > vorder ? uorder : vorder)*size;
709 
710    if(hsize>dsize)
711      buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
712    else
713      buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
714 
715    /* compute the increment value for the u-loop */
716    uinc = ustride - vorder*vstride;
717 
718    if (buffer)
719       for (i=0, p=buffer; i<uorder; i++, points += uinc)
720 	 for (j=0; j<vorder; j++, points += vstride)
721 	    for (k=0; k<size; k++)
722 	       *p++ = (GLfloat) points[k];
723 
724    return buffer;
725 }
726 
727 
728 /*
729  * This function is called by the display list deallocator function to
730  * specify that a given set of control points are no longer needed.
731  */
gl_free_control_points(GLcontext * ctx,GLenum target,GLfloat * data)732 void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
733 {
734    struct gl_1d_map *map1 = NULL;
735    struct gl_2d_map *map2 = NULL;
736 
737    switch (target) {
738       case GL_MAP1_VERTEX_3:
739          map1 = &ctx->EvalMap.Map1Vertex3;
740          break;
741       case GL_MAP1_VERTEX_4:
742          map1 = &ctx->EvalMap.Map1Vertex4;
743 	 break;
744       case GL_MAP1_INDEX:
745          map1 = &ctx->EvalMap.Map1Index;
746          break;
747       case GL_MAP1_COLOR_4:
748          map1 = &ctx->EvalMap.Map1Color4;
749          break;
750       case GL_MAP1_NORMAL:
751          map1 = &ctx->EvalMap.Map1Normal;
752 	 break;
753       case GL_MAP1_TEXTURE_COORD_1:
754          map1 = &ctx->EvalMap.Map1Texture1;
755 	 break;
756       case GL_MAP1_TEXTURE_COORD_2:
757          map1 = &ctx->EvalMap.Map1Texture2;
758 	 break;
759       case GL_MAP1_TEXTURE_COORD_3:
760          map1 = &ctx->EvalMap.Map1Texture3;
761 	 break;
762       case GL_MAP1_TEXTURE_COORD_4:
763          map1 = &ctx->EvalMap.Map1Texture4;
764 	 break;
765       case GL_MAP2_VERTEX_3:
766          map2 = &ctx->EvalMap.Map2Vertex3;
767 	 break;
768       case GL_MAP2_VERTEX_4:
769          map2 = &ctx->EvalMap.Map2Vertex4;
770 	 break;
771       case GL_MAP2_INDEX:
772          map2 = &ctx->EvalMap.Map2Index;
773 	 break;
774       case GL_MAP2_COLOR_4:
775          map2 = &ctx->EvalMap.Map2Color4;
776          break;
777       case GL_MAP2_NORMAL:
778          map2 = &ctx->EvalMap.Map2Normal;
779 	 break;
780       case GL_MAP2_TEXTURE_COORD_1:
781          map2 = &ctx->EvalMap.Map2Texture1;
782 	 break;
783       case GL_MAP2_TEXTURE_COORD_2:
784          map2 = &ctx->EvalMap.Map2Texture2;
785 	 break;
786       case GL_MAP2_TEXTURE_COORD_3:
787          map2 = &ctx->EvalMap.Map2Texture3;
788 	 break;
789       case GL_MAP2_TEXTURE_COORD_4:
790          map2 = &ctx->EvalMap.Map2Texture4;
791 	 break;
792       default:
793 	 gl_error( ctx, GL_INVALID_ENUM, "gl_free_control_points" );
794          return;
795    }
796 
797    if (map1) {
798       if (data==map1->Points) {
799          /* The control points in the display list are currently */
800          /* being used so we can mark them as discard-able. */
801          map1->Retain = GL_FALSE;
802       }
803       else {
804          /* The control points in the display list are not currently */
805          /* being used. */
806          free( data );
807       }
808    }
809    if (map2) {
810       if (data==map2->Points) {
811          /* The control points in the display list are currently */
812          /* being used so we can mark them as discard-able. */
813          map2->Retain = GL_FALSE;
814       }
815       else {
816          /* The control points in the display list are not currently */
817          /* being used. */
818          free( data );
819       }
820    }
821 
822 }
823 
824 
825 
826 /**********************************************************************/
827 /***                      API entry points                          ***/
828 /**********************************************************************/
829 
830 
831 /*
832  * Note that the array of control points must be 'unpacked' at this time.
833  * Input:  retain - if TRUE, this control point data is also in a display
834  *                  list and can't be freed until the list is freed.
835  */
gl_Map1f(GLcontext * ctx,GLenum target,GLfloat u1,GLfloat u2,GLint stride,GLint order,const GLfloat * points,GLboolean retain)836 void gl_Map1f( GLcontext* ctx, GLenum target,
837                GLfloat u1, GLfloat u2, GLint stride,
838                GLint order, const GLfloat *points, GLboolean retain )
839 {
840    GLuint k;
841 
842    if (!points) {
843       gl_error( ctx, GL_OUT_OF_MEMORY, "glMap1f" );
844       return;
845    }
846 
847    /* may be a new stride after copying control points */
848    stride = components( target );
849 
850    if (INSIDE_BEGIN_END(ctx)) {
851       gl_error( ctx, GL_INVALID_OPERATION, "glMap1" );
852       return;
853    }
854 
855    if (u1==u2) {
856       gl_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
857       return;
858    }
859 
860    if (order<1 || order>MAX_EVAL_ORDER) {
861       gl_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
862       return;
863    }
864 
865    k = components( target );
866    if (k==0) {
867       gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
868    }
869 
870    if (stride < k) {
871       gl_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
872       return;
873    }
874 
875    switch (target) {
876       case GL_MAP1_VERTEX_3:
877          ctx->EvalMap.Map1Vertex3.Order = order;
878 	 ctx->EvalMap.Map1Vertex3.u1 = u1;
879 	 ctx->EvalMap.Map1Vertex3.u2 = u2;
880 	 if (ctx->EvalMap.Map1Vertex3.Points
881              && !ctx->EvalMap.Map1Vertex3.Retain) {
882 	    free( ctx->EvalMap.Map1Vertex3.Points );
883 	 }
884 	 ctx->EvalMap.Map1Vertex3.Points = (GLfloat *) points;
885          ctx->EvalMap.Map1Vertex3.Retain = retain;
886 	 break;
887       case GL_MAP1_VERTEX_4:
888          ctx->EvalMap.Map1Vertex4.Order = order;
889 	 ctx->EvalMap.Map1Vertex4.u1 = u1;
890 	 ctx->EvalMap.Map1Vertex4.u2 = u2;
891 	 if (ctx->EvalMap.Map1Vertex4.Points
892              && !ctx->EvalMap.Map1Vertex4.Retain) {
893 	    free( ctx->EvalMap.Map1Vertex4.Points );
894 	 }
895 	 ctx->EvalMap.Map1Vertex4.Points = (GLfloat *) points;
896 	 ctx->EvalMap.Map1Vertex4.Retain = retain;
897 	 break;
898       case GL_MAP1_INDEX:
899          ctx->EvalMap.Map1Index.Order = order;
900 	 ctx->EvalMap.Map1Index.u1 = u1;
901 	 ctx->EvalMap.Map1Index.u2 = u2;
902 	 if (ctx->EvalMap.Map1Index.Points
903              && !ctx->EvalMap.Map1Index.Retain) {
904 	    free( ctx->EvalMap.Map1Index.Points );
905 	 }
906 	 ctx->EvalMap.Map1Index.Points = (GLfloat *) points;
907 	 ctx->EvalMap.Map1Index.Retain = retain;
908 	 break;
909       case GL_MAP1_COLOR_4:
910          ctx->EvalMap.Map1Color4.Order = order;
911 	 ctx->EvalMap.Map1Color4.u1 = u1;
912 	 ctx->EvalMap.Map1Color4.u2 = u2;
913 	 if (ctx->EvalMap.Map1Color4.Points
914              && !ctx->EvalMap.Map1Color4.Retain) {
915 	    free( ctx->EvalMap.Map1Color4.Points );
916 	 }
917 	 ctx->EvalMap.Map1Color4.Points = (GLfloat *) points;
918 	 ctx->EvalMap.Map1Color4.Retain = retain;
919 	 break;
920       case GL_MAP1_NORMAL:
921          ctx->EvalMap.Map1Normal.Order = order;
922 	 ctx->EvalMap.Map1Normal.u1 = u1;
923 	 ctx->EvalMap.Map1Normal.u2 = u2;
924 	 if (ctx->EvalMap.Map1Normal.Points
925              && !ctx->EvalMap.Map1Normal.Retain) {
926 	    free( ctx->EvalMap.Map1Normal.Points );
927 	 }
928 	 ctx->EvalMap.Map1Normal.Points = (GLfloat *) points;
929 	 ctx->EvalMap.Map1Normal.Retain = retain;
930 	 break;
931       case GL_MAP1_TEXTURE_COORD_1:
932          ctx->EvalMap.Map1Texture1.Order = order;
933 	 ctx->EvalMap.Map1Texture1.u1 = u1;
934 	 ctx->EvalMap.Map1Texture1.u2 = u2;
935 	 if (ctx->EvalMap.Map1Texture1.Points
936              && !ctx->EvalMap.Map1Texture1.Retain) {
937 	    free( ctx->EvalMap.Map1Texture1.Points );
938 	 }
939 	 ctx->EvalMap.Map1Texture1.Points = (GLfloat *) points;
940 	 ctx->EvalMap.Map1Texture1.Retain = retain;
941 	 break;
942       case GL_MAP1_TEXTURE_COORD_2:
943          ctx->EvalMap.Map1Texture2.Order = order;
944 	 ctx->EvalMap.Map1Texture2.u1 = u1;
945 	 ctx->EvalMap.Map1Texture2.u2 = u2;
946 	 if (ctx->EvalMap.Map1Texture2.Points
947              && !ctx->EvalMap.Map1Texture2.Retain) {
948 	    free( ctx->EvalMap.Map1Texture2.Points );
949 	 }
950 	 ctx->EvalMap.Map1Texture2.Points = (GLfloat *) points;
951 	 ctx->EvalMap.Map1Texture2.Retain = retain;
952 	 break;
953       case GL_MAP1_TEXTURE_COORD_3:
954          ctx->EvalMap.Map1Texture3.Order = order;
955 	 ctx->EvalMap.Map1Texture3.u1 = u1;
956 	 ctx->EvalMap.Map1Texture3.u2 = u2;
957 	 if (ctx->EvalMap.Map1Texture3.Points
958              && !ctx->EvalMap.Map1Texture3.Retain) {
959 	    free( ctx->EvalMap.Map1Texture3.Points );
960 	 }
961 	 ctx->EvalMap.Map1Texture3.Points = (GLfloat *) points;
962 	 ctx->EvalMap.Map1Texture3.Retain = retain;
963 	 break;
964       case GL_MAP1_TEXTURE_COORD_4:
965          ctx->EvalMap.Map1Texture4.Order = order;
966 	 ctx->EvalMap.Map1Texture4.u1 = u1;
967 	 ctx->EvalMap.Map1Texture4.u2 = u2;
968 	 if (ctx->EvalMap.Map1Texture4.Points
969              && !ctx->EvalMap.Map1Texture4.Retain) {
970 	    free( ctx->EvalMap.Map1Texture4.Points );
971 	 }
972 	 ctx->EvalMap.Map1Texture4.Points = (GLfloat *) points;
973 	 ctx->EvalMap.Map1Texture4.Retain = retain;
974 	 break;
975       default:
976          gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
977    }
978 }
979 
980 
981 
982 
983 /*
984  * Note that the array of control points must be 'unpacked' at this time.
985  * Input:  retain - if TRUE, this control point data is also in a display
986  *                  list and can't be freed until the list is freed.
987  */
gl_Map2f(GLcontext * ctx,GLenum target,GLfloat u1,GLfloat u2,GLint ustride,GLint uorder,GLfloat v1,GLfloat v2,GLint vstride,GLint vorder,const GLfloat * points,GLboolean retain)988 void gl_Map2f( GLcontext* ctx, GLenum target,
989 	      GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
990 	      GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
991 	      const GLfloat *points, GLboolean retain )
992 {
993    GLuint k;
994 
995    if (INSIDE_BEGIN_END(ctx)) {
996       gl_error( ctx, GL_INVALID_OPERATION, "glMap2" );
997       return;
998    }
999 
1000    if (u1==u2) {
1001       gl_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
1002       return;
1003    }
1004 
1005    if (v1==v2) {
1006       gl_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
1007       return;
1008    }
1009 
1010    if (uorder<1 || uorder>MAX_EVAL_ORDER) {
1011       gl_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
1012       return;
1013    }
1014 
1015    if (vorder<1 || vorder>MAX_EVAL_ORDER) {
1016       gl_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
1017       return;
1018    }
1019 
1020    k = components( target );
1021    if (k==0) {
1022       gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
1023    }
1024 
1025    if (ustride < k) {
1026       gl_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
1027       return;
1028    }
1029    if (vstride < k) {
1030       gl_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
1031       return;
1032    }
1033 
1034    switch (target) {
1035       case GL_MAP2_VERTEX_3:
1036          ctx->EvalMap.Map2Vertex3.Uorder = uorder;
1037 	 ctx->EvalMap.Map2Vertex3.u1 = u1;
1038 	 ctx->EvalMap.Map2Vertex3.u2 = u2;
1039          ctx->EvalMap.Map2Vertex3.Vorder = vorder;
1040 	 ctx->EvalMap.Map2Vertex3.v1 = v1;
1041 	 ctx->EvalMap.Map2Vertex3.v2 = v2;
1042 	 if (ctx->EvalMap.Map2Vertex3.Points
1043              && !ctx->EvalMap.Map2Vertex3.Retain) {
1044 	    free( ctx->EvalMap.Map2Vertex3.Points );
1045 	 }
1046 	 ctx->EvalMap.Map2Vertex3.Retain = retain;
1047 	 ctx->EvalMap.Map2Vertex3.Points = (GLfloat *) points;
1048 	 break;
1049       case GL_MAP2_VERTEX_4:
1050          ctx->EvalMap.Map2Vertex4.Uorder = uorder;
1051 	 ctx->EvalMap.Map2Vertex4.u1 = u1;
1052 	 ctx->EvalMap.Map2Vertex4.u2 = u2;
1053          ctx->EvalMap.Map2Vertex4.Vorder = vorder;
1054 	 ctx->EvalMap.Map2Vertex4.v1 = v1;
1055 	 ctx->EvalMap.Map2Vertex4.v2 = v2;
1056 	 if (ctx->EvalMap.Map2Vertex4.Points
1057              && !ctx->EvalMap.Map2Vertex4.Retain) {
1058 	    free( ctx->EvalMap.Map2Vertex4.Points );
1059 	 }
1060 	 ctx->EvalMap.Map2Vertex4.Points = (GLfloat *) points;
1061 	 ctx->EvalMap.Map2Vertex4.Retain = retain;
1062 	 break;
1063       case GL_MAP2_INDEX:
1064          ctx->EvalMap.Map2Index.Uorder = uorder;
1065 	 ctx->EvalMap.Map2Index.u1 = u1;
1066 	 ctx->EvalMap.Map2Index.u2 = u2;
1067          ctx->EvalMap.Map2Index.Vorder = vorder;
1068 	 ctx->EvalMap.Map2Index.v1 = v1;
1069 	 ctx->EvalMap.Map2Index.v2 = v2;
1070 	 if (ctx->EvalMap.Map2Index.Points
1071              && !ctx->EvalMap.Map2Index.Retain) {
1072 	    free( ctx->EvalMap.Map2Index.Points );
1073 	 }
1074 	 ctx->EvalMap.Map2Index.Retain = retain;
1075 	 ctx->EvalMap.Map2Index.Points = (GLfloat *) points;
1076 	 break;
1077       case GL_MAP2_COLOR_4:
1078          ctx->EvalMap.Map2Color4.Uorder = uorder;
1079 	 ctx->EvalMap.Map2Color4.u1 = u1;
1080 	 ctx->EvalMap.Map2Color4.u2 = u2;
1081          ctx->EvalMap.Map2Color4.Vorder = vorder;
1082 	 ctx->EvalMap.Map2Color4.v1 = v1;
1083 	 ctx->EvalMap.Map2Color4.v2 = v2;
1084 	 if (ctx->EvalMap.Map2Color4.Points
1085              && !ctx->EvalMap.Map2Color4.Retain) {
1086 	    free( ctx->EvalMap.Map2Color4.Points );
1087 	 }
1088 	 ctx->EvalMap.Map2Color4.Retain = retain;
1089 	 ctx->EvalMap.Map2Color4.Points = (GLfloat *) points;
1090 	 break;
1091       case GL_MAP2_NORMAL:
1092          ctx->EvalMap.Map2Normal.Uorder = uorder;
1093 	 ctx->EvalMap.Map2Normal.u1 = u1;
1094 	 ctx->EvalMap.Map2Normal.u2 = u2;
1095          ctx->EvalMap.Map2Normal.Vorder = vorder;
1096 	 ctx->EvalMap.Map2Normal.v1 = v1;
1097 	 ctx->EvalMap.Map2Normal.v2 = v2;
1098 	 if (ctx->EvalMap.Map2Normal.Points
1099              && !ctx->EvalMap.Map2Normal.Retain) {
1100 	    free( ctx->EvalMap.Map2Normal.Points );
1101 	 }
1102 	 ctx->EvalMap.Map2Normal.Retain = retain;
1103 	 ctx->EvalMap.Map2Normal.Points = (GLfloat *) points;
1104 	 break;
1105       case GL_MAP2_TEXTURE_COORD_1:
1106          ctx->EvalMap.Map2Texture1.Uorder = uorder;
1107 	 ctx->EvalMap.Map2Texture1.u1 = u1;
1108 	 ctx->EvalMap.Map2Texture1.u2 = u2;
1109          ctx->EvalMap.Map2Texture1.Vorder = vorder;
1110 	 ctx->EvalMap.Map2Texture1.v1 = v1;
1111 	 ctx->EvalMap.Map2Texture1.v2 = v2;
1112 	 if (ctx->EvalMap.Map2Texture1.Points
1113              && !ctx->EvalMap.Map2Texture1.Retain) {
1114 	    free( ctx->EvalMap.Map2Texture1.Points );
1115 	 }
1116 	 ctx->EvalMap.Map2Texture1.Retain = retain;
1117 	 ctx->EvalMap.Map2Texture1.Points = (GLfloat *) points;
1118 	 break;
1119       case GL_MAP2_TEXTURE_COORD_2:
1120          ctx->EvalMap.Map2Texture2.Uorder = uorder;
1121 	 ctx->EvalMap.Map2Texture2.u1 = u1;
1122 	 ctx->EvalMap.Map2Texture2.u2 = u2;
1123          ctx->EvalMap.Map2Texture2.Vorder = vorder;
1124 	 ctx->EvalMap.Map2Texture2.v1 = v1;
1125 	 ctx->EvalMap.Map2Texture2.v2 = v2;
1126 	 if (ctx->EvalMap.Map2Texture2.Points
1127              && !ctx->EvalMap.Map2Texture2.Retain) {
1128 	    free( ctx->EvalMap.Map2Texture2.Points );
1129 	 }
1130 	 ctx->EvalMap.Map2Texture2.Retain = retain;
1131 	 ctx->EvalMap.Map2Texture2.Points = (GLfloat *) points;
1132 	 break;
1133       case GL_MAP2_TEXTURE_COORD_3:
1134          ctx->EvalMap.Map2Texture3.Uorder = uorder;
1135 	 ctx->EvalMap.Map2Texture3.u1 = u1;
1136 	 ctx->EvalMap.Map2Texture3.u2 = u2;
1137          ctx->EvalMap.Map2Texture3.Vorder = vorder;
1138 	 ctx->EvalMap.Map2Texture3.v1 = v1;
1139 	 ctx->EvalMap.Map2Texture3.v2 = v2;
1140 	 if (ctx->EvalMap.Map2Texture3.Points
1141              && !ctx->EvalMap.Map2Texture3.Retain) {
1142 	    free( ctx->EvalMap.Map2Texture3.Points );
1143 	 }
1144 	 ctx->EvalMap.Map2Texture3.Retain = retain;
1145 	 ctx->EvalMap.Map2Texture3.Points = (GLfloat *) points;
1146 	 break;
1147       case GL_MAP2_TEXTURE_COORD_4:
1148          ctx->EvalMap.Map2Texture4.Uorder = uorder;
1149 	 ctx->EvalMap.Map2Texture4.u1 = u1;
1150 	 ctx->EvalMap.Map2Texture4.u2 = u2;
1151          ctx->EvalMap.Map2Texture4.Vorder = vorder;
1152 	 ctx->EvalMap.Map2Texture4.v1 = v1;
1153 	 ctx->EvalMap.Map2Texture4.v2 = v2;
1154 	 if (ctx->EvalMap.Map2Texture4.Points
1155              && !ctx->EvalMap.Map2Texture4.Retain) {
1156 	    free( ctx->EvalMap.Map2Texture4.Points );
1157 	 }
1158 	 ctx->EvalMap.Map2Texture4.Retain = retain;
1159 	 ctx->EvalMap.Map2Texture4.Points = (GLfloat *) points;
1160 	 break;
1161       default:
1162          gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
1163    }
1164 }
1165 
1166 
1167 
1168 
1169 
gl_GetMapdv(GLcontext * ctx,GLenum target,GLenum query,GLdouble * v)1170 void gl_GetMapdv( GLcontext* ctx, GLenum target, GLenum query, GLdouble *v )
1171 {
1172    GLuint i, n;
1173    GLfloat *data;
1174 
1175    switch (query) {
1176       case GL_COEFF:
1177 	 switch (target) {
1178 	    case GL_MAP1_COLOR_4:
1179 	       data = ctx->EvalMap.Map1Color4.Points;
1180 	       n = ctx->EvalMap.Map1Color4.Order * 4;
1181 	       break;
1182 	    case GL_MAP1_INDEX:
1183 	       data = ctx->EvalMap.Map1Index.Points;
1184 	       n = ctx->EvalMap.Map1Index.Order;
1185 	       break;
1186 	    case GL_MAP1_NORMAL:
1187 	       data = ctx->EvalMap.Map1Normal.Points;
1188 	       n = ctx->EvalMap.Map1Normal.Order * 3;
1189 	       break;
1190 	    case GL_MAP1_TEXTURE_COORD_1:
1191 	       data = ctx->EvalMap.Map1Texture1.Points;
1192 	       n = ctx->EvalMap.Map1Texture1.Order * 1;
1193 	       break;
1194 	    case GL_MAP1_TEXTURE_COORD_2:
1195 	       data = ctx->EvalMap.Map1Texture2.Points;
1196 	       n = ctx->EvalMap.Map1Texture2.Order * 2;
1197 	       break;
1198 	    case GL_MAP1_TEXTURE_COORD_3:
1199 	       data = ctx->EvalMap.Map1Texture3.Points;
1200 	       n = ctx->EvalMap.Map1Texture3.Order * 3;
1201 	       break;
1202 	    case GL_MAP1_TEXTURE_COORD_4:
1203 	       data = ctx->EvalMap.Map1Texture4.Points;
1204 	       n = ctx->EvalMap.Map1Texture4.Order * 4;
1205 	       break;
1206 	    case GL_MAP1_VERTEX_3:
1207 	       data = ctx->EvalMap.Map1Vertex3.Points;
1208 	       n = ctx->EvalMap.Map1Vertex3.Order * 3;
1209 	       break;
1210 	    case GL_MAP1_VERTEX_4:
1211 	       data = ctx->EvalMap.Map1Vertex4.Points;
1212 	       n = ctx->EvalMap.Map1Vertex4.Order * 4;
1213 	       break;
1214 	    case GL_MAP2_COLOR_4:
1215 	       data = ctx->EvalMap.Map2Color4.Points;
1216 	       n = ctx->EvalMap.Map2Color4.Uorder
1217                  * ctx->EvalMap.Map2Color4.Vorder * 4;
1218 	       break;
1219 	    case GL_MAP2_INDEX:
1220 	       data = ctx->EvalMap.Map2Index.Points;
1221 	       n = ctx->EvalMap.Map2Index.Uorder
1222                  * ctx->EvalMap.Map2Index.Vorder;
1223 	       break;
1224 	    case GL_MAP2_NORMAL:
1225 	       data = ctx->EvalMap.Map2Normal.Points;
1226 	       n = ctx->EvalMap.Map2Normal.Uorder
1227                  * ctx->EvalMap.Map2Normal.Vorder * 3;
1228 	       break;
1229 	    case GL_MAP2_TEXTURE_COORD_1:
1230 	       data = ctx->EvalMap.Map2Texture1.Points;
1231 	       n = ctx->EvalMap.Map2Texture1.Uorder
1232                  * ctx->EvalMap.Map2Texture1.Vorder * 1;
1233 	       break;
1234 	    case GL_MAP2_TEXTURE_COORD_2:
1235 	       data = ctx->EvalMap.Map2Texture2.Points;
1236 	       n = ctx->EvalMap.Map2Texture2.Uorder
1237                  * ctx->EvalMap.Map2Texture2.Vorder * 2;
1238 	       break;
1239 	    case GL_MAP2_TEXTURE_COORD_3:
1240 	       data = ctx->EvalMap.Map2Texture3.Points;
1241 	       n = ctx->EvalMap.Map2Texture3.Uorder
1242                  * ctx->EvalMap.Map2Texture3.Vorder * 3;
1243 	       break;
1244 	    case GL_MAP2_TEXTURE_COORD_4:
1245 	       data = ctx->EvalMap.Map2Texture4.Points;
1246 	       n = ctx->EvalMap.Map2Texture4.Uorder
1247                  * ctx->EvalMap.Map2Texture4.Vorder * 4;
1248 	       break;
1249 	    case GL_MAP2_VERTEX_3:
1250 	       data = ctx->EvalMap.Map2Vertex3.Points;
1251 	       n = ctx->EvalMap.Map2Vertex3.Uorder
1252                  * ctx->EvalMap.Map2Vertex3.Vorder * 3;
1253 	       break;
1254 	    case GL_MAP2_VERTEX_4:
1255 	       data = ctx->EvalMap.Map2Vertex4.Points;
1256 	       n = ctx->EvalMap.Map2Vertex4.Uorder
1257                  * ctx->EvalMap.Map2Vertex4.Vorder * 4;
1258 	       break;
1259 	    default:
1260 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
1261 	 }
1262 	 if (data) {
1263 	    for (i=0;i<n;i++) {
1264 	       v[i] = data[i];
1265 	    }
1266 	 }
1267          break;
1268       case GL_ORDER:
1269 	 switch (target) {
1270 	    case GL_MAP1_COLOR_4:
1271 	       *v = ctx->EvalMap.Map1Color4.Order;
1272 	       break;
1273 	    case GL_MAP1_INDEX:
1274 	       *v = ctx->EvalMap.Map1Index.Order;
1275 	       break;
1276 	    case GL_MAP1_NORMAL:
1277 	       *v = ctx->EvalMap.Map1Normal.Order;
1278 	       break;
1279 	    case GL_MAP1_TEXTURE_COORD_1:
1280 	       *v = ctx->EvalMap.Map1Texture1.Order;
1281 	       break;
1282 	    case GL_MAP1_TEXTURE_COORD_2:
1283 	       *v = ctx->EvalMap.Map1Texture2.Order;
1284 	       break;
1285 	    case GL_MAP1_TEXTURE_COORD_3:
1286 	       *v = ctx->EvalMap.Map1Texture3.Order;
1287 	       break;
1288 	    case GL_MAP1_TEXTURE_COORD_4:
1289 	       *v = ctx->EvalMap.Map1Texture4.Order;
1290 	       break;
1291 	    case GL_MAP1_VERTEX_3:
1292 	       *v = ctx->EvalMap.Map1Vertex3.Order;
1293 	       break;
1294 	    case GL_MAP1_VERTEX_4:
1295 	       *v = ctx->EvalMap.Map1Vertex4.Order;
1296 	       break;
1297 	    case GL_MAP2_COLOR_4:
1298 	       v[0] = ctx->EvalMap.Map2Color4.Uorder;
1299 	       v[1] = ctx->EvalMap.Map2Color4.Vorder;
1300 	       break;
1301 	    case GL_MAP2_INDEX:
1302 	       v[0] = ctx->EvalMap.Map2Index.Uorder;
1303 	       v[1] = ctx->EvalMap.Map2Index.Vorder;
1304 	       break;
1305 	    case GL_MAP2_NORMAL:
1306 	       v[0] = ctx->EvalMap.Map2Normal.Uorder;
1307 	       v[1] = ctx->EvalMap.Map2Normal.Vorder;
1308 	       break;
1309 	    case GL_MAP2_TEXTURE_COORD_1:
1310 	       v[0] = ctx->EvalMap.Map2Texture1.Uorder;
1311 	       v[1] = ctx->EvalMap.Map2Texture1.Vorder;
1312 	       break;
1313 	    case GL_MAP2_TEXTURE_COORD_2:
1314 	       v[0] = ctx->EvalMap.Map2Texture2.Uorder;
1315 	       v[1] = ctx->EvalMap.Map2Texture2.Vorder;
1316 	       break;
1317 	    case GL_MAP2_TEXTURE_COORD_3:
1318 	       v[0] = ctx->EvalMap.Map2Texture3.Uorder;
1319 	       v[1] = ctx->EvalMap.Map2Texture3.Vorder;
1320 	       break;
1321 	    case GL_MAP2_TEXTURE_COORD_4:
1322 	       v[0] = ctx->EvalMap.Map2Texture4.Uorder;
1323 	       v[1] = ctx->EvalMap.Map2Texture4.Vorder;
1324 	       break;
1325 	    case GL_MAP2_VERTEX_3:
1326 	       v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
1327 	       v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
1328 	       break;
1329 	    case GL_MAP2_VERTEX_4:
1330 	       v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
1331 	       v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
1332 	       break;
1333 	    default:
1334 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
1335 	 }
1336          break;
1337       case GL_DOMAIN:
1338 	 switch (target) {
1339 	    case GL_MAP1_COLOR_4:
1340 	       v[0] = ctx->EvalMap.Map1Color4.u1;
1341 	       v[1] = ctx->EvalMap.Map1Color4.u2;
1342 	       break;
1343 	    case GL_MAP1_INDEX:
1344 	       v[0] = ctx->EvalMap.Map1Index.u1;
1345 	       v[1] = ctx->EvalMap.Map1Index.u2;
1346 	       break;
1347 	    case GL_MAP1_NORMAL:
1348 	       v[0] = ctx->EvalMap.Map1Normal.u1;
1349 	       v[1] = ctx->EvalMap.Map1Normal.u2;
1350 	       break;
1351 	    case GL_MAP1_TEXTURE_COORD_1:
1352 	       v[0] = ctx->EvalMap.Map1Texture1.u1;
1353 	       v[1] = ctx->EvalMap.Map1Texture1.u2;
1354 	       break;
1355 	    case GL_MAP1_TEXTURE_COORD_2:
1356 	       v[0] = ctx->EvalMap.Map1Texture2.u1;
1357 	       v[1] = ctx->EvalMap.Map1Texture2.u2;
1358 	       break;
1359 	    case GL_MAP1_TEXTURE_COORD_3:
1360 	       v[0] = ctx->EvalMap.Map1Texture3.u1;
1361 	       v[1] = ctx->EvalMap.Map1Texture3.u2;
1362 	       break;
1363 	    case GL_MAP1_TEXTURE_COORD_4:
1364 	       v[0] = ctx->EvalMap.Map1Texture4.u1;
1365 	       v[1] = ctx->EvalMap.Map1Texture4.u2;
1366 	       break;
1367 	    case GL_MAP1_VERTEX_3:
1368 	       v[0] = ctx->EvalMap.Map1Vertex3.u1;
1369 	       v[1] = ctx->EvalMap.Map1Vertex3.u2;
1370 	       break;
1371 	    case GL_MAP1_VERTEX_4:
1372 	       v[0] = ctx->EvalMap.Map1Vertex4.u1;
1373 	       v[1] = ctx->EvalMap.Map1Vertex4.u2;
1374 	       break;
1375 	    case GL_MAP2_COLOR_4:
1376 	       v[0] = ctx->EvalMap.Map2Color4.u1;
1377 	       v[1] = ctx->EvalMap.Map2Color4.u2;
1378 	       v[2] = ctx->EvalMap.Map2Color4.v1;
1379 	       v[3] = ctx->EvalMap.Map2Color4.v2;
1380 	       break;
1381 	    case GL_MAP2_INDEX:
1382 	       v[0] = ctx->EvalMap.Map2Index.u1;
1383 	       v[1] = ctx->EvalMap.Map2Index.u2;
1384 	       v[2] = ctx->EvalMap.Map2Index.v1;
1385 	       v[3] = ctx->EvalMap.Map2Index.v2;
1386 	       break;
1387 	    case GL_MAP2_NORMAL:
1388 	       v[0] = ctx->EvalMap.Map2Normal.u1;
1389 	       v[1] = ctx->EvalMap.Map2Normal.u2;
1390 	       v[2] = ctx->EvalMap.Map2Normal.v1;
1391 	       v[3] = ctx->EvalMap.Map2Normal.v2;
1392 	       break;
1393 	    case GL_MAP2_TEXTURE_COORD_1:
1394 	       v[0] = ctx->EvalMap.Map2Texture1.u1;
1395 	       v[1] = ctx->EvalMap.Map2Texture1.u2;
1396 	       v[2] = ctx->EvalMap.Map2Texture1.v1;
1397 	       v[3] = ctx->EvalMap.Map2Texture1.v2;
1398 	       break;
1399 	    case GL_MAP2_TEXTURE_COORD_2:
1400 	       v[0] = ctx->EvalMap.Map2Texture2.u1;
1401 	       v[1] = ctx->EvalMap.Map2Texture2.u2;
1402 	       v[2] = ctx->EvalMap.Map2Texture2.v1;
1403 	       v[3] = ctx->EvalMap.Map2Texture2.v2;
1404 	       break;
1405 	    case GL_MAP2_TEXTURE_COORD_3:
1406 	       v[0] = ctx->EvalMap.Map2Texture3.u1;
1407 	       v[1] = ctx->EvalMap.Map2Texture3.u2;
1408 	       v[2] = ctx->EvalMap.Map2Texture3.v1;
1409 	       v[3] = ctx->EvalMap.Map2Texture3.v2;
1410 	       break;
1411 	    case GL_MAP2_TEXTURE_COORD_4:
1412 	       v[0] = ctx->EvalMap.Map2Texture4.u1;
1413 	       v[1] = ctx->EvalMap.Map2Texture4.u2;
1414 	       v[2] = ctx->EvalMap.Map2Texture4.v1;
1415 	       v[3] = ctx->EvalMap.Map2Texture4.v2;
1416 	       break;
1417 	    case GL_MAP2_VERTEX_3:
1418 	       v[0] = ctx->EvalMap.Map2Vertex3.u1;
1419 	       v[1] = ctx->EvalMap.Map2Vertex3.u2;
1420 	       v[2] = ctx->EvalMap.Map2Vertex3.v1;
1421 	       v[3] = ctx->EvalMap.Map2Vertex3.v2;
1422 	       break;
1423 	    case GL_MAP2_VERTEX_4:
1424 	       v[0] = ctx->EvalMap.Map2Vertex4.u1;
1425 	       v[1] = ctx->EvalMap.Map2Vertex4.u2;
1426 	       v[2] = ctx->EvalMap.Map2Vertex4.v1;
1427 	       v[3] = ctx->EvalMap.Map2Vertex4.v2;
1428 	       break;
1429 	    default:
1430 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
1431 	 }
1432          break;
1433       default:
1434          gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
1435    }
1436 }
1437 
1438 
gl_GetMapfv(GLcontext * ctx,GLenum target,GLenum query,GLfloat * v)1439 void gl_GetMapfv( GLcontext* ctx, GLenum target, GLenum query, GLfloat *v )
1440 {
1441    GLuint i, n;
1442    GLfloat *data;
1443 
1444    switch (query) {
1445       case GL_COEFF:
1446 	 switch (target) {
1447 	    case GL_MAP1_COLOR_4:
1448 	       data = ctx->EvalMap.Map1Color4.Points;
1449 	       n = ctx->EvalMap.Map1Color4.Order * 4;
1450 	       break;
1451 	    case GL_MAP1_INDEX:
1452 	       data = ctx->EvalMap.Map1Index.Points;
1453 	       n = ctx->EvalMap.Map1Index.Order;
1454 	       break;
1455 	    case GL_MAP1_NORMAL:
1456 	       data = ctx->EvalMap.Map1Normal.Points;
1457 	       n = ctx->EvalMap.Map1Normal.Order * 3;
1458 	       break;
1459 	    case GL_MAP1_TEXTURE_COORD_1:
1460 	       data = ctx->EvalMap.Map1Texture1.Points;
1461 	       n = ctx->EvalMap.Map1Texture1.Order * 1;
1462 	       break;
1463 	    case GL_MAP1_TEXTURE_COORD_2:
1464 	       data = ctx->EvalMap.Map1Texture2.Points;
1465 	       n = ctx->EvalMap.Map1Texture2.Order * 2;
1466 	       break;
1467 	    case GL_MAP1_TEXTURE_COORD_3:
1468 	       data = ctx->EvalMap.Map1Texture3.Points;
1469 	       n = ctx->EvalMap.Map1Texture3.Order * 3;
1470 	       break;
1471 	    case GL_MAP1_TEXTURE_COORD_4:
1472 	       data = ctx->EvalMap.Map1Texture4.Points;
1473 	       n = ctx->EvalMap.Map1Texture4.Order * 4;
1474 	       break;
1475 	    case GL_MAP1_VERTEX_3:
1476 	       data = ctx->EvalMap.Map1Vertex3.Points;
1477 	       n = ctx->EvalMap.Map1Vertex3.Order * 3;
1478 	       break;
1479 	    case GL_MAP1_VERTEX_4:
1480 	       data = ctx->EvalMap.Map1Vertex4.Points;
1481 	       n = ctx->EvalMap.Map1Vertex4.Order * 4;
1482 	       break;
1483 	    case GL_MAP2_COLOR_4:
1484 	       data = ctx->EvalMap.Map2Color4.Points;
1485 	       n = ctx->EvalMap.Map2Color4.Uorder
1486                  * ctx->EvalMap.Map2Color4.Vorder * 4;
1487 	       break;
1488 	    case GL_MAP2_INDEX:
1489 	       data = ctx->EvalMap.Map2Index.Points;
1490 	       n = ctx->EvalMap.Map2Index.Uorder
1491                  * ctx->EvalMap.Map2Index.Vorder;
1492 	       break;
1493 	    case GL_MAP2_NORMAL:
1494 	       data = ctx->EvalMap.Map2Normal.Points;
1495 	       n = ctx->EvalMap.Map2Normal.Uorder
1496                  * ctx->EvalMap.Map2Normal.Vorder * 3;
1497 	       break;
1498 	    case GL_MAP2_TEXTURE_COORD_1:
1499 	       data = ctx->EvalMap.Map2Texture1.Points;
1500 	       n = ctx->EvalMap.Map2Texture1.Uorder
1501                  * ctx->EvalMap.Map2Texture1.Vorder * 1;
1502 	       break;
1503 	    case GL_MAP2_TEXTURE_COORD_2:
1504 	       data = ctx->EvalMap.Map2Texture2.Points;
1505 	       n = ctx->EvalMap.Map2Texture2.Uorder
1506                  * ctx->EvalMap.Map2Texture2.Vorder * 2;
1507 	       break;
1508 	    case GL_MAP2_TEXTURE_COORD_3:
1509 	       data = ctx->EvalMap.Map2Texture3.Points;
1510 	       n = ctx->EvalMap.Map2Texture3.Uorder
1511                  * ctx->EvalMap.Map2Texture3.Vorder * 3;
1512 	       break;
1513 	    case GL_MAP2_TEXTURE_COORD_4:
1514 	       data = ctx->EvalMap.Map2Texture4.Points;
1515 	       n = ctx->EvalMap.Map2Texture4.Uorder
1516                  * ctx->EvalMap.Map2Texture4.Vorder * 4;
1517 	       break;
1518 	    case GL_MAP2_VERTEX_3:
1519 	       data = ctx->EvalMap.Map2Vertex3.Points;
1520 	       n = ctx->EvalMap.Map2Vertex3.Uorder
1521                  * ctx->EvalMap.Map2Vertex3.Vorder * 3;
1522 	       break;
1523 	    case GL_MAP2_VERTEX_4:
1524 	       data = ctx->EvalMap.Map2Vertex4.Points;
1525 	       n = ctx->EvalMap.Map2Vertex4.Uorder
1526                  * ctx->EvalMap.Map2Vertex4.Vorder * 4;
1527 	       break;
1528 	    default:
1529 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1530 	 }
1531 	 if (data) {
1532 	    for (i=0;i<n;i++) {
1533 	       v[i] = data[i];
1534 	    }
1535 	 }
1536          break;
1537       case GL_ORDER:
1538 	 switch (target) {
1539 	    case GL_MAP1_COLOR_4:
1540 	       *v = ctx->EvalMap.Map1Color4.Order;
1541 	       break;
1542 	    case GL_MAP1_INDEX:
1543 	       *v = ctx->EvalMap.Map1Index.Order;
1544 	       break;
1545 	    case GL_MAP1_NORMAL:
1546 	       *v = ctx->EvalMap.Map1Normal.Order;
1547 	       break;
1548 	    case GL_MAP1_TEXTURE_COORD_1:
1549 	       *v = ctx->EvalMap.Map1Texture1.Order;
1550 	       break;
1551 	    case GL_MAP1_TEXTURE_COORD_2:
1552 	       *v = ctx->EvalMap.Map1Texture2.Order;
1553 	       break;
1554 	    case GL_MAP1_TEXTURE_COORD_3:
1555 	       *v = ctx->EvalMap.Map1Texture3.Order;
1556 	       break;
1557 	    case GL_MAP1_TEXTURE_COORD_4:
1558 	       *v = ctx->EvalMap.Map1Texture4.Order;
1559 	       break;
1560 	    case GL_MAP1_VERTEX_3:
1561 	       *v = ctx->EvalMap.Map1Vertex3.Order;
1562 	       break;
1563 	    case GL_MAP1_VERTEX_4:
1564 	       *v = ctx->EvalMap.Map1Vertex4.Order;
1565 	       break;
1566 	    case GL_MAP2_COLOR_4:
1567 	       v[0] = ctx->EvalMap.Map2Color4.Uorder;
1568 	       v[1] = ctx->EvalMap.Map2Color4.Vorder;
1569 	       break;
1570 	    case GL_MAP2_INDEX:
1571 	       v[0] = ctx->EvalMap.Map2Index.Uorder;
1572 	       v[1] = ctx->EvalMap.Map2Index.Vorder;
1573 	       break;
1574 	    case GL_MAP2_NORMAL:
1575 	       v[0] = ctx->EvalMap.Map2Normal.Uorder;
1576 	       v[1] = ctx->EvalMap.Map2Normal.Vorder;
1577 	       break;
1578 	    case GL_MAP2_TEXTURE_COORD_1:
1579 	       v[0] = ctx->EvalMap.Map2Texture1.Uorder;
1580 	       v[1] = ctx->EvalMap.Map2Texture1.Vorder;
1581 	       break;
1582 	    case GL_MAP2_TEXTURE_COORD_2:
1583 	       v[0] = ctx->EvalMap.Map2Texture2.Uorder;
1584 	       v[1] = ctx->EvalMap.Map2Texture2.Vorder;
1585 	       break;
1586 	    case GL_MAP2_TEXTURE_COORD_3:
1587 	       v[0] = ctx->EvalMap.Map2Texture3.Uorder;
1588 	       v[1] = ctx->EvalMap.Map2Texture3.Vorder;
1589 	       break;
1590 	    case GL_MAP2_TEXTURE_COORD_4:
1591 	       v[0] = ctx->EvalMap.Map2Texture4.Uorder;
1592 	       v[1] = ctx->EvalMap.Map2Texture4.Vorder;
1593 	       break;
1594 	    case GL_MAP2_VERTEX_3:
1595 	       v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
1596 	       v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
1597 	       break;
1598 	    case GL_MAP2_VERTEX_4:
1599 	       v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
1600 	       v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
1601 	       break;
1602 	    default:
1603 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1604 	 }
1605          break;
1606       case GL_DOMAIN:
1607 	 switch (target) {
1608 	    case GL_MAP1_COLOR_4:
1609 	       v[0] = ctx->EvalMap.Map1Color4.u1;
1610 	       v[1] = ctx->EvalMap.Map1Color4.u2;
1611 	       break;
1612 	    case GL_MAP1_INDEX:
1613 	       v[0] = ctx->EvalMap.Map1Index.u1;
1614 	       v[1] = ctx->EvalMap.Map1Index.u2;
1615 	       break;
1616 	    case GL_MAP1_NORMAL:
1617 	       v[0] = ctx->EvalMap.Map1Normal.u1;
1618 	       v[1] = ctx->EvalMap.Map1Normal.u2;
1619 	       break;
1620 	    case GL_MAP1_TEXTURE_COORD_1:
1621 	       v[0] = ctx->EvalMap.Map1Texture1.u1;
1622 	       v[1] = ctx->EvalMap.Map1Texture1.u2;
1623 	       break;
1624 	    case GL_MAP1_TEXTURE_COORD_2:
1625 	       v[0] = ctx->EvalMap.Map1Texture2.u1;
1626 	       v[1] = ctx->EvalMap.Map1Texture2.u2;
1627 	       break;
1628 	    case GL_MAP1_TEXTURE_COORD_3:
1629 	       v[0] = ctx->EvalMap.Map1Texture3.u1;
1630 	       v[1] = ctx->EvalMap.Map1Texture3.u2;
1631 	       break;
1632 	    case GL_MAP1_TEXTURE_COORD_4:
1633 	       v[0] = ctx->EvalMap.Map1Texture4.u1;
1634 	       v[1] = ctx->EvalMap.Map1Texture4.u2;
1635 	       break;
1636 	    case GL_MAP1_VERTEX_3:
1637 	       v[0] = ctx->EvalMap.Map1Vertex3.u1;
1638 	       v[1] = ctx->EvalMap.Map1Vertex3.u2;
1639 	       break;
1640 	    case GL_MAP1_VERTEX_4:
1641 	       v[0] = ctx->EvalMap.Map1Vertex4.u1;
1642 	       v[1] = ctx->EvalMap.Map1Vertex4.u2;
1643 	       break;
1644 	    case GL_MAP2_COLOR_4:
1645 	       v[0] = ctx->EvalMap.Map2Color4.u1;
1646 	       v[1] = ctx->EvalMap.Map2Color4.u2;
1647 	       v[2] = ctx->EvalMap.Map2Color4.v1;
1648 	       v[3] = ctx->EvalMap.Map2Color4.v2;
1649 	       break;
1650 	    case GL_MAP2_INDEX:
1651 	       v[0] = ctx->EvalMap.Map2Index.u1;
1652 	       v[1] = ctx->EvalMap.Map2Index.u2;
1653 	       v[2] = ctx->EvalMap.Map2Index.v1;
1654 	       v[3] = ctx->EvalMap.Map2Index.v2;
1655 	       break;
1656 	    case GL_MAP2_NORMAL:
1657 	       v[0] = ctx->EvalMap.Map2Normal.u1;
1658 	       v[1] = ctx->EvalMap.Map2Normal.u2;
1659 	       v[2] = ctx->EvalMap.Map2Normal.v1;
1660 	       v[3] = ctx->EvalMap.Map2Normal.v2;
1661 	       break;
1662 	    case GL_MAP2_TEXTURE_COORD_1:
1663 	       v[0] = ctx->EvalMap.Map2Texture1.u1;
1664 	       v[1] = ctx->EvalMap.Map2Texture1.u2;
1665 	       v[2] = ctx->EvalMap.Map2Texture1.v1;
1666 	       v[3] = ctx->EvalMap.Map2Texture1.v2;
1667 	       break;
1668 	    case GL_MAP2_TEXTURE_COORD_2:
1669 	       v[0] = ctx->EvalMap.Map2Texture2.u1;
1670 	       v[1] = ctx->EvalMap.Map2Texture2.u2;
1671 	       v[2] = ctx->EvalMap.Map2Texture2.v1;
1672 	       v[3] = ctx->EvalMap.Map2Texture2.v2;
1673 	       break;
1674 	    case GL_MAP2_TEXTURE_COORD_3:
1675 	       v[0] = ctx->EvalMap.Map2Texture3.u1;
1676 	       v[1] = ctx->EvalMap.Map2Texture3.u2;
1677 	       v[2] = ctx->EvalMap.Map2Texture3.v1;
1678 	       v[3] = ctx->EvalMap.Map2Texture3.v2;
1679 	       break;
1680 	    case GL_MAP2_TEXTURE_COORD_4:
1681 	       v[0] = ctx->EvalMap.Map2Texture4.u1;
1682 	       v[1] = ctx->EvalMap.Map2Texture4.u2;
1683 	       v[2] = ctx->EvalMap.Map2Texture4.v1;
1684 	       v[3] = ctx->EvalMap.Map2Texture4.v2;
1685 	       break;
1686 	    case GL_MAP2_VERTEX_3:
1687 	       v[0] = ctx->EvalMap.Map2Vertex3.u1;
1688 	       v[1] = ctx->EvalMap.Map2Vertex3.u2;
1689 	       v[2] = ctx->EvalMap.Map2Vertex3.v1;
1690 	       v[3] = ctx->EvalMap.Map2Vertex3.v2;
1691 	       break;
1692 	    case GL_MAP2_VERTEX_4:
1693 	       v[0] = ctx->EvalMap.Map2Vertex4.u1;
1694 	       v[1] = ctx->EvalMap.Map2Vertex4.u2;
1695 	       v[2] = ctx->EvalMap.Map2Vertex4.v1;
1696 	       v[3] = ctx->EvalMap.Map2Vertex4.v2;
1697 	       break;
1698 	    default:
1699 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1700 	 }
1701          break;
1702       default:
1703          gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
1704    }
1705 }
1706 
1707 
gl_GetMapiv(GLcontext * ctx,GLenum target,GLenum query,GLint * v)1708 void gl_GetMapiv( GLcontext* ctx, GLenum target, GLenum query, GLint *v )
1709 {
1710    GLuint i, n;
1711    GLfloat *data;
1712 
1713    switch (query) {
1714       case GL_COEFF:
1715 	 switch (target) {
1716 	    case GL_MAP1_COLOR_4:
1717 	       data = ctx->EvalMap.Map1Color4.Points;
1718 	       n = ctx->EvalMap.Map1Color4.Order * 4;
1719 	       break;
1720 	    case GL_MAP1_INDEX:
1721 	       data = ctx->EvalMap.Map1Index.Points;
1722 	       n = ctx->EvalMap.Map1Index.Order;
1723 	       break;
1724 	    case GL_MAP1_NORMAL:
1725 	       data = ctx->EvalMap.Map1Normal.Points;
1726 	       n = ctx->EvalMap.Map1Normal.Order * 3;
1727 	       break;
1728 	    case GL_MAP1_TEXTURE_COORD_1:
1729 	       data = ctx->EvalMap.Map1Texture1.Points;
1730 	       n = ctx->EvalMap.Map1Texture1.Order * 1;
1731 	       break;
1732 	    case GL_MAP1_TEXTURE_COORD_2:
1733 	       data = ctx->EvalMap.Map1Texture2.Points;
1734 	       n = ctx->EvalMap.Map1Texture2.Order * 2;
1735 	       break;
1736 	    case GL_MAP1_TEXTURE_COORD_3:
1737 	       data = ctx->EvalMap.Map1Texture3.Points;
1738 	       n = ctx->EvalMap.Map1Texture3.Order * 3;
1739 	       break;
1740 	    case GL_MAP1_TEXTURE_COORD_4:
1741 	       data = ctx->EvalMap.Map1Texture4.Points;
1742 	       n = ctx->EvalMap.Map1Texture4.Order * 4;
1743 	       break;
1744 	    case GL_MAP1_VERTEX_3:
1745 	       data = ctx->EvalMap.Map1Vertex3.Points;
1746 	       n = ctx->EvalMap.Map1Vertex3.Order * 3;
1747 	       break;
1748 	    case GL_MAP1_VERTEX_4:
1749 	       data = ctx->EvalMap.Map1Vertex4.Points;
1750 	       n = ctx->EvalMap.Map1Vertex4.Order * 4;
1751 	       break;
1752 	    case GL_MAP2_COLOR_4:
1753 	       data = ctx->EvalMap.Map2Color4.Points;
1754 	       n = ctx->EvalMap.Map2Color4.Uorder
1755                  * ctx->EvalMap.Map2Color4.Vorder * 4;
1756 	       break;
1757 	    case GL_MAP2_INDEX:
1758 	       data = ctx->EvalMap.Map2Index.Points;
1759 	       n = ctx->EvalMap.Map2Index.Uorder
1760                  * ctx->EvalMap.Map2Index.Vorder;
1761 	       break;
1762 	    case GL_MAP2_NORMAL:
1763 	       data = ctx->EvalMap.Map2Normal.Points;
1764 	       n = ctx->EvalMap.Map2Normal.Uorder
1765                  * ctx->EvalMap.Map2Normal.Vorder * 3;
1766 	       break;
1767 	    case GL_MAP2_TEXTURE_COORD_1:
1768 	       data = ctx->EvalMap.Map2Texture1.Points;
1769 	       n = ctx->EvalMap.Map2Texture1.Uorder
1770                  * ctx->EvalMap.Map2Texture1.Vorder * 1;
1771 	       break;
1772 	    case GL_MAP2_TEXTURE_COORD_2:
1773 	       data = ctx->EvalMap.Map2Texture2.Points;
1774 	       n = ctx->EvalMap.Map2Texture2.Uorder
1775                  * ctx->EvalMap.Map2Texture2.Vorder * 2;
1776 	       break;
1777 	    case GL_MAP2_TEXTURE_COORD_3:
1778 	       data = ctx->EvalMap.Map2Texture3.Points;
1779 	       n = ctx->EvalMap.Map2Texture3.Uorder
1780                  * ctx->EvalMap.Map2Texture3.Vorder * 3;
1781 	       break;
1782 	    case GL_MAP2_TEXTURE_COORD_4:
1783 	       data = ctx->EvalMap.Map2Texture4.Points;
1784 	       n = ctx->EvalMap.Map2Texture4.Uorder
1785                  * ctx->EvalMap.Map2Texture4.Vorder * 4;
1786 	       break;
1787 	    case GL_MAP2_VERTEX_3:
1788 	       data = ctx->EvalMap.Map2Vertex3.Points;
1789 	       n = ctx->EvalMap.Map2Vertex3.Uorder
1790                  * ctx->EvalMap.Map2Vertex3.Vorder * 3;
1791 	       break;
1792 	    case GL_MAP2_VERTEX_4:
1793 	       data = ctx->EvalMap.Map2Vertex4.Points;
1794 	       n = ctx->EvalMap.Map2Vertex4.Uorder
1795                  * ctx->EvalMap.Map2Vertex4.Vorder * 4;
1796 	       break;
1797 	    default:
1798 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1799 	 }
1800 	 if (data) {
1801 	    for (i=0;i<n;i++) {
1802 	       v[i] = ROUNDF(data[i]);
1803 	    }
1804 	 }
1805          break;
1806       case GL_ORDER:
1807 	 switch (target) {
1808 	    case GL_MAP1_COLOR_4:
1809 	       *v = ctx->EvalMap.Map1Color4.Order;
1810 	       break;
1811 	    case GL_MAP1_INDEX:
1812 	       *v = ctx->EvalMap.Map1Index.Order;
1813 	       break;
1814 	    case GL_MAP1_NORMAL:
1815 	       *v = ctx->EvalMap.Map1Normal.Order;
1816 	       break;
1817 	    case GL_MAP1_TEXTURE_COORD_1:
1818 	       *v = ctx->EvalMap.Map1Texture1.Order;
1819 	       break;
1820 	    case GL_MAP1_TEXTURE_COORD_2:
1821 	       *v = ctx->EvalMap.Map1Texture2.Order;
1822 	       break;
1823 	    case GL_MAP1_TEXTURE_COORD_3:
1824 	       *v = ctx->EvalMap.Map1Texture3.Order;
1825 	       break;
1826 	    case GL_MAP1_TEXTURE_COORD_4:
1827 	       *v = ctx->EvalMap.Map1Texture4.Order;
1828 	       break;
1829 	    case GL_MAP1_VERTEX_3:
1830 	       *v = ctx->EvalMap.Map1Vertex3.Order;
1831 	       break;
1832 	    case GL_MAP1_VERTEX_4:
1833 	       *v = ctx->EvalMap.Map1Vertex4.Order;
1834 	       break;
1835 	    case GL_MAP2_COLOR_4:
1836 	       v[0] = ctx->EvalMap.Map2Color4.Uorder;
1837 	       v[1] = ctx->EvalMap.Map2Color4.Vorder;
1838 	       break;
1839 	    case GL_MAP2_INDEX:
1840 	       v[0] = ctx->EvalMap.Map2Index.Uorder;
1841 	       v[1] = ctx->EvalMap.Map2Index.Vorder;
1842 	       break;
1843 	    case GL_MAP2_NORMAL:
1844 	       v[0] = ctx->EvalMap.Map2Normal.Uorder;
1845 	       v[1] = ctx->EvalMap.Map2Normal.Vorder;
1846 	       break;
1847 	    case GL_MAP2_TEXTURE_COORD_1:
1848 	       v[0] = ctx->EvalMap.Map2Texture1.Uorder;
1849 	       v[1] = ctx->EvalMap.Map2Texture1.Vorder;
1850 	       break;
1851 	    case GL_MAP2_TEXTURE_COORD_2:
1852 	       v[0] = ctx->EvalMap.Map2Texture2.Uorder;
1853 	       v[1] = ctx->EvalMap.Map2Texture2.Vorder;
1854 	       break;
1855 	    case GL_MAP2_TEXTURE_COORD_3:
1856 	       v[0] = ctx->EvalMap.Map2Texture3.Uorder;
1857 	       v[1] = ctx->EvalMap.Map2Texture3.Vorder;
1858 	       break;
1859 	    case GL_MAP2_TEXTURE_COORD_4:
1860 	       v[0] = ctx->EvalMap.Map2Texture4.Uorder;
1861 	       v[1] = ctx->EvalMap.Map2Texture4.Vorder;
1862 	       break;
1863 	    case GL_MAP2_VERTEX_3:
1864 	       v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
1865 	       v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
1866 	       break;
1867 	    case GL_MAP2_VERTEX_4:
1868 	       v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
1869 	       v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
1870 	       break;
1871 	    default:
1872 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1873 	 }
1874          break;
1875       case GL_DOMAIN:
1876 	 switch (target) {
1877 	    case GL_MAP1_COLOR_4:
1878 	       v[0] = ROUNDF(ctx->EvalMap.Map1Color4.u1);
1879 	       v[1] = ROUNDF(ctx->EvalMap.Map1Color4.u2);
1880 	       break;
1881 	    case GL_MAP1_INDEX:
1882 	       v[0] = ROUNDF(ctx->EvalMap.Map1Index.u1);
1883 	       v[1] = ROUNDF(ctx->EvalMap.Map1Index.u2);
1884 	       break;
1885 	    case GL_MAP1_NORMAL:
1886 	       v[0] = ROUNDF(ctx->EvalMap.Map1Normal.u1);
1887 	       v[1] = ROUNDF(ctx->EvalMap.Map1Normal.u2);
1888 	       break;
1889 	    case GL_MAP1_TEXTURE_COORD_1:
1890 	       v[0] = ROUNDF(ctx->EvalMap.Map1Texture1.u1);
1891 	       v[1] = ROUNDF(ctx->EvalMap.Map1Texture1.u2);
1892 	       break;
1893 	    case GL_MAP1_TEXTURE_COORD_2:
1894 	       v[0] = ROUNDF(ctx->EvalMap.Map1Texture2.u1);
1895 	       v[1] = ROUNDF(ctx->EvalMap.Map1Texture2.u2);
1896 	       break;
1897 	    case GL_MAP1_TEXTURE_COORD_3:
1898 	       v[0] = ROUNDF(ctx->EvalMap.Map1Texture3.u1);
1899 	       v[1] = ROUNDF(ctx->EvalMap.Map1Texture3.u2);
1900 	       break;
1901 	    case GL_MAP1_TEXTURE_COORD_4:
1902 	       v[0] = ROUNDF(ctx->EvalMap.Map1Texture4.u1);
1903 	       v[1] = ROUNDF(ctx->EvalMap.Map1Texture4.u2);
1904 	       break;
1905 	    case GL_MAP1_VERTEX_3:
1906 	       v[0] = ROUNDF(ctx->EvalMap.Map1Vertex3.u1);
1907 	       v[1] = ROUNDF(ctx->EvalMap.Map1Vertex3.u2);
1908 	       break;
1909 	    case GL_MAP1_VERTEX_4:
1910 	       v[0] = ROUNDF(ctx->EvalMap.Map1Vertex4.u1);
1911 	       v[1] = ROUNDF(ctx->EvalMap.Map1Vertex4.u2);
1912 	       break;
1913 	    case GL_MAP2_COLOR_4:
1914 	       v[0] = ROUNDF(ctx->EvalMap.Map2Color4.u1);
1915 	       v[1] = ROUNDF(ctx->EvalMap.Map2Color4.u2);
1916 	       v[2] = ROUNDF(ctx->EvalMap.Map2Color4.v1);
1917 	       v[3] = ROUNDF(ctx->EvalMap.Map2Color4.v2);
1918 	       break;
1919 	    case GL_MAP2_INDEX:
1920 	       v[0] = ROUNDF(ctx->EvalMap.Map2Index.u1);
1921 	       v[1] = ROUNDF(ctx->EvalMap.Map2Index.u2);
1922 	       v[2] = ROUNDF(ctx->EvalMap.Map2Index.v1);
1923 	       v[3] = ROUNDF(ctx->EvalMap.Map2Index.v2);
1924 	       break;
1925 	    case GL_MAP2_NORMAL:
1926 	       v[0] = ROUNDF(ctx->EvalMap.Map2Normal.u1);
1927 	       v[1] = ROUNDF(ctx->EvalMap.Map2Normal.u2);
1928 	       v[2] = ROUNDF(ctx->EvalMap.Map2Normal.v1);
1929 	       v[3] = ROUNDF(ctx->EvalMap.Map2Normal.v2);
1930 	       break;
1931 	    case GL_MAP2_TEXTURE_COORD_1:
1932 	       v[0] = ROUNDF(ctx->EvalMap.Map2Texture1.u1);
1933 	       v[1] = ROUNDF(ctx->EvalMap.Map2Texture1.u2);
1934 	       v[2] = ROUNDF(ctx->EvalMap.Map2Texture1.v1);
1935 	       v[3] = ROUNDF(ctx->EvalMap.Map2Texture1.v2);
1936 	       break;
1937 	    case GL_MAP2_TEXTURE_COORD_2:
1938 	       v[0] = ROUNDF(ctx->EvalMap.Map2Texture2.u1);
1939 	       v[1] = ROUNDF(ctx->EvalMap.Map2Texture2.u2);
1940 	       v[2] = ROUNDF(ctx->EvalMap.Map2Texture2.v1);
1941 	       v[3] = ROUNDF(ctx->EvalMap.Map2Texture2.v2);
1942 	       break;
1943 	    case GL_MAP2_TEXTURE_COORD_3:
1944 	       v[0] = ROUNDF(ctx->EvalMap.Map2Texture3.u1);
1945 	       v[1] = ROUNDF(ctx->EvalMap.Map2Texture3.u2);
1946 	       v[2] = ROUNDF(ctx->EvalMap.Map2Texture3.v1);
1947 	       v[3] = ROUNDF(ctx->EvalMap.Map2Texture3.v2);
1948 	       break;
1949 	    case GL_MAP2_TEXTURE_COORD_4:
1950 	       v[0] = ROUNDF(ctx->EvalMap.Map2Texture4.u1);
1951 	       v[1] = ROUNDF(ctx->EvalMap.Map2Texture4.u2);
1952 	       v[2] = ROUNDF(ctx->EvalMap.Map2Texture4.v1);
1953 	       v[3] = ROUNDF(ctx->EvalMap.Map2Texture4.v2);
1954 	       break;
1955 	    case GL_MAP2_VERTEX_3:
1956 	       v[0] = ROUNDF(ctx->EvalMap.Map2Vertex3.u1);
1957 	       v[1] = ROUNDF(ctx->EvalMap.Map2Vertex3.u2);
1958 	       v[2] = ROUNDF(ctx->EvalMap.Map2Vertex3.v1);
1959 	       v[3] = ROUNDF(ctx->EvalMap.Map2Vertex3.v2);
1960 	       break;
1961 	    case GL_MAP2_VERTEX_4:
1962 	       v[0] = ROUNDF(ctx->EvalMap.Map2Vertex4.u1);
1963 	       v[1] = ROUNDF(ctx->EvalMap.Map2Vertex4.u2);
1964 	       v[2] = ROUNDF(ctx->EvalMap.Map2Vertex4.v1);
1965 	       v[3] = ROUNDF(ctx->EvalMap.Map2Vertex4.v2);
1966 	       break;
1967 	    default:
1968 	       gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1969 	 }
1970          break;
1971       default:
1972          gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
1973    }
1974 }
1975 
1976 
1977 
gl_EvalCoord1f(GLcontext * ctx,GLfloat u)1978 void gl_EvalCoord1f(GLcontext* ctx, GLfloat u)
1979 {
1980   GLfloat vertex[4];
1981   GLfloat normal[3];
1982   GLfloat fcolor[4];
1983   GLubyte icolor[4];
1984   GLubyte *colorptr;
1985   GLfloat texcoord[4];
1986   GLuint index;
1987   register GLfloat uu;
1988 
1989   /** Vertex **/
1990   if (ctx->Eval.Map1Vertex4)
1991   {
1992      struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex4;
1993      uu = (u - map->u1) / (map->u2 - map->u1);
1994      horner_bezier_curve(map->Points, vertex, uu, 4, map->Order);
1995   }
1996   else if (ctx->Eval.Map1Vertex3)
1997   {
1998      struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex3;
1999      uu = (u - map->u1) / (map->u2 - map->u1);
2000      horner_bezier_curve(map->Points, vertex, uu, 3, map->Order);
2001      vertex[3] = 1.0;
2002   }
2003 
2004   /** Color Index **/
2005   if (ctx->Eval.Map1Index)
2006   {
2007      struct gl_1d_map *map = &ctx->EvalMap.Map1Index;
2008      GLfloat findex;
2009      uu = (u - map->u1) / (map->u2 - map->u1);
2010      horner_bezier_curve(map->Points, &findex, uu, 1, map->Order);
2011      index = (GLuint) (GLint) findex;
2012   }
2013   else {
2014      index = ctx->Current.Index;
2015   }
2016 
2017   /** Color **/
2018   if (ctx->Eval.Map1Color4) {
2019      struct gl_1d_map *map = &ctx->EvalMap.Map1Color4;
2020      uu = (u - map->u1) / (map->u2 - map->u1);
2021      horner_bezier_curve(map->Points, fcolor, uu, 4, map->Order);
2022      icolor[0] = (GLint) (fcolor[0] * ctx->Visual->RedScale);
2023      icolor[1] = (GLint) (fcolor[1] * ctx->Visual->GreenScale);
2024      icolor[2] = (GLint) (fcolor[2] * ctx->Visual->BlueScale);
2025      icolor[3] = (GLint) (fcolor[3] * ctx->Visual->AlphaScale);
2026      colorptr = icolor;
2027   }
2028   else {
2029      GLubyte col[4];
2030      COPY_4V(col, ctx->Current.ByteColor );
2031      colorptr = col;
2032   }
2033 
2034   /** Normal Vector **/
2035   if (ctx->Eval.Map1Normal) {
2036      struct gl_1d_map *map = &ctx->EvalMap.Map1Normal;
2037      uu = (u - map->u1) / (map->u2 - map->u1);
2038      horner_bezier_curve(map->Points, normal, uu, 3, map->Order);
2039   }
2040   else {
2041     normal[0] = ctx->Current.Normal[0];
2042     normal[1] = ctx->Current.Normal[1];
2043     normal[2] = ctx->Current.Normal[2];
2044   }
2045 
2046   /** Texture Coordinates **/
2047   if (ctx->Eval.Map1TextureCoord4) {
2048      struct gl_1d_map *map = &ctx->EvalMap.Map1Texture4;
2049      uu = (u - map->u1) / (map->u2 - map->u1);
2050      horner_bezier_curve(map->Points, texcoord, uu, 4, map->Order);
2051   }
2052   else if (ctx->Eval.Map1TextureCoord3) {
2053      struct gl_1d_map *map = &ctx->EvalMap.Map1Texture3;
2054      uu = (u - map->u1) / (map->u2 - map->u1);
2055      horner_bezier_curve(map->Points, texcoord, uu, 3, map->Order);
2056      texcoord[3] = 1.0;
2057   }
2058   else if (ctx->Eval.Map1TextureCoord2) {
2059      struct gl_1d_map *map = &ctx->EvalMap.Map1Texture2;
2060      uu = (u - map->u1) / (map->u2 - map->u1);
2061      horner_bezier_curve(map->Points, texcoord, uu, 2, map->Order);
2062      texcoord[2] = 0.0;
2063      texcoord[3] = 1.0;
2064   }
2065   else if (ctx->Eval.Map1TextureCoord1) {
2066      struct gl_1d_map *map = &ctx->EvalMap.Map1Texture1;
2067      uu = (u - map->u1) / (map->u2 - map->u1);
2068      horner_bezier_curve(map->Points, texcoord, uu, 1, map->Order);
2069      texcoord[1] = 0.0;
2070      texcoord[2] = 0.0;
2071      texcoord[3] = 1.0;
2072   }
2073   else {
2074      texcoord[0] = ctx->Current.TexCoord[0];
2075      texcoord[1] = ctx->Current.TexCoord[1];
2076      texcoord[2] = ctx->Current.TexCoord[2];
2077      texcoord[3] = ctx->Current.TexCoord[3];
2078   }
2079 
2080   gl_eval_vertex( ctx, vertex, normal, colorptr, index, texcoord );
2081 }
2082 
2083 
gl_EvalCoord2f(GLcontext * ctx,GLfloat u,GLfloat v)2084 void gl_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v )
2085 {
2086    GLfloat vertex[4];
2087    GLfloat normal[3];
2088    GLfloat fcolor[4];
2089    GLubyte icolor[4];
2090    GLubyte *colorptr;
2091    GLfloat texcoord[4];
2092    GLuint index;
2093    register GLfloat uu, vv;
2094 
2095 #define CROSS_PROD(n, u, v) \
2096   (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
2097   (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
2098   (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
2099 
2100    /** Vertex **/
2101    if(ctx->Eval.Map2Vertex4) {
2102       struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex4;
2103       uu = (u - map->u1) / (map->u2 - map->u1);
2104       vv = (v - map->v1) / (map->v2 - map->v1);
2105 
2106       if (ctx->Eval.AutoNormal) {
2107          GLfloat du[4], dv[4];
2108 
2109          de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 4,
2110                            map->Uorder, map->Vorder);
2111 
2112          CROSS_PROD(normal, du, dv);
2113          NORMALIZE_3FV(normal);
2114       }
2115       else {
2116          horner_bezier_surf(map->Points, vertex, uu, vv, 4,
2117                             map->Uorder, map->Vorder);
2118       }
2119    }
2120    else if (ctx->Eval.Map2Vertex3) {
2121       struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex3;
2122       uu = (u - map->u1) / (map->u2 - map->u1);
2123       vv = (v - map->v1) / (map->v2 - map->v1);
2124       if (ctx->Eval.AutoNormal) {
2125          GLfloat du[3], dv[3];
2126          de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 3,
2127                            map->Uorder, map->Vorder);
2128          CROSS_PROD(normal, du, dv);
2129          NORMALIZE_3FV(normal);
2130       }
2131       else {
2132          horner_bezier_surf(map->Points, vertex, uu, vv, 3,
2133                             map->Uorder, map->Vorder);
2134       }
2135       vertex[3] = 1.0;
2136    }
2137 #undef CROSS_PROD
2138 
2139    /** Color Index **/
2140    if (ctx->Eval.Map2Index) {
2141       GLfloat findex;
2142       struct gl_2d_map *map = &ctx->EvalMap.Map2Index;
2143       uu = (u - map->u1) / (map->u2 - map->u1);
2144       vv = (v - map->v1) / (map->v2 - map->v1);
2145       horner_bezier_surf(map->Points, &findex, uu, vv, 1,
2146                          map->Uorder, map->Vorder);
2147       index = (GLuint) (GLint) findex;
2148    }
2149    else {
2150       index = ctx->Current.Index;
2151    }
2152 
2153    /** Color **/
2154    if (ctx->Eval.Map2Color4) {
2155       struct gl_2d_map *map = &ctx->EvalMap.Map2Color4;
2156       uu = (u - map->u1) / (map->u2 - map->u1);
2157       vv = (v - map->v1) / (map->v2 - map->v1);
2158       horner_bezier_surf(map->Points, fcolor, uu, vv, 4,
2159                          map->Uorder, map->Vorder);
2160       icolor[0] = (GLint) (fcolor[0] * ctx->Visual->RedScale);
2161       icolor[1] = (GLint) (fcolor[1] * ctx->Visual->GreenScale);
2162       icolor[2] = (GLint) (fcolor[2] * ctx->Visual->BlueScale);
2163       icolor[3] = (GLint) (fcolor[3] * ctx->Visual->AlphaScale);
2164       colorptr = icolor;
2165    }
2166    else {
2167      GLubyte col[4];
2168      COPY_4V(col, ctx->Current.ByteColor );
2169      colorptr = col;
2170    }
2171 
2172    /** Normal **/
2173    if (!ctx->Eval.AutoNormal
2174        || (!ctx->Eval.Map2Vertex3 && !ctx->Eval.Map2Vertex4)) {
2175       if (ctx->Eval.Map2Normal) {
2176          struct gl_2d_map *map = &ctx->EvalMap.Map2Normal;
2177          uu = (u - map->u1) / (map->u2 - map->u1);
2178          vv = (v - map->v1) / (map->v2 - map->v1);
2179          horner_bezier_surf(map->Points, normal, uu, vv, 3,
2180                             map->Uorder, map->Vorder);
2181       }
2182       else {
2183          normal[0] = ctx->Current.Normal[0];
2184          normal[1] = ctx->Current.Normal[1];
2185          normal[2] = ctx->Current.Normal[2];
2186       }
2187    }
2188 
2189    /** Texture Coordinates **/
2190    if (ctx->Eval.Map2TextureCoord4) {
2191       struct gl_2d_map *map = &ctx->EvalMap.Map2Texture4;
2192       uu = (u - map->u1) / (map->u2 - map->u1);
2193       vv = (v - map->v1) / (map->v2 - map->v1);
2194       horner_bezier_surf(map->Points, texcoord, uu, vv, 4,
2195                          map->Uorder, map->Vorder);
2196    }
2197    else if (ctx->Eval.Map2TextureCoord3) {
2198       struct gl_2d_map *map = &ctx->EvalMap.Map2Texture3;
2199       uu = (u - map->u1) / (map->u2 - map->u1);
2200       vv = (v - map->v1) / (map->v2 - map->v1);
2201       horner_bezier_surf(map->Points, texcoord, uu, vv, 3,
2202                          map->Uorder, map->Vorder);
2203      texcoord[3] = 1.0;
2204    }
2205    else if (ctx->Eval.Map2TextureCoord2) {
2206       struct gl_2d_map *map = &ctx->EvalMap.Map2Texture2;
2207       uu = (u - map->u1) / (map->u2 - map->u1);
2208       vv = (v - map->v1) / (map->v2 - map->v1);
2209       horner_bezier_surf(map->Points, texcoord, uu, vv, 2,
2210                          map->Uorder, map->Vorder);
2211      texcoord[2] = 0.0;
2212      texcoord[3] = 1.0;
2213    }
2214    else if (ctx->Eval.Map2TextureCoord1) {
2215       struct gl_2d_map *map = &ctx->EvalMap.Map2Texture1;
2216       uu = (u - map->u1) / (map->u2 - map->u1);
2217       vv = (v - map->v1) / (map->v2 - map->v1);
2218       horner_bezier_surf(map->Points, texcoord, uu, vv, 1,
2219                          map->Uorder, map->Vorder);
2220      texcoord[1] = 0.0;
2221      texcoord[2] = 0.0;
2222      texcoord[3] = 1.0;
2223    }
2224    else
2225    {
2226      texcoord[0] = ctx->Current.TexCoord[0];
2227      texcoord[1] = ctx->Current.TexCoord[1];
2228      texcoord[2] = ctx->Current.TexCoord[2];
2229      texcoord[3] = ctx->Current.TexCoord[3];
2230    }
2231 
2232    gl_eval_vertex( ctx, vertex, normal, colorptr, index, texcoord );
2233 }
2234 
2235 
gl_MapGrid1f(GLcontext * ctx,GLint un,GLfloat u1,GLfloat u2)2236 void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 )
2237 {
2238    if (INSIDE_BEGIN_END(ctx)) {
2239       gl_error( ctx, GL_INVALID_OPERATION, "glMapGrid1f" );
2240       return;
2241    }
2242    if (un<1) {
2243       gl_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
2244       return;
2245    }
2246    ctx->Eval.MapGrid1un = un;
2247    ctx->Eval.MapGrid1u1 = u1;
2248    ctx->Eval.MapGrid1u2 = u2;
2249 }
2250 
2251 
gl_MapGrid2f(GLcontext * ctx,GLint un,GLfloat u1,GLfloat u2,GLint vn,GLfloat v1,GLfloat v2)2252 void gl_MapGrid2f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2,
2253 		  GLint vn, GLfloat v1, GLfloat v2 )
2254 {
2255    if (INSIDE_BEGIN_END(ctx)) {
2256       gl_error( ctx, GL_INVALID_OPERATION, "glMapGrid2f" );
2257       return;
2258    }
2259    if (un<1) {
2260       gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
2261       return;
2262    }
2263    if (vn<1) {
2264       gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
2265       return;
2266    }
2267    ctx->Eval.MapGrid2un = un;
2268    ctx->Eval.MapGrid2u1 = u1;
2269    ctx->Eval.MapGrid2u2 = u2;
2270    ctx->Eval.MapGrid2vn = vn;
2271    ctx->Eval.MapGrid2v1 = v1;
2272    ctx->Eval.MapGrid2v2 = v2;
2273 }
2274 
2275 
gl_EvalPoint1(GLcontext * ctx,GLint i)2276 void gl_EvalPoint1( GLcontext* ctx, GLint i )
2277 {
2278 	GLfloat u, du;
2279 
2280 	if (i==0) {
2281 		u = ctx->Eval.MapGrid1u1;
2282 	}
2283 	else if (i==ctx->Eval.MapGrid1un) {
2284 		u = ctx->Eval.MapGrid1u2;
2285 	}
2286 	else {
2287 		du = (ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1)
2288 			/ (GLfloat) ctx->Eval.MapGrid1un;
2289 		u = i * du + ctx->Eval.MapGrid1u1;
2290 	}
2291 	gl_EvalCoord1f( ctx, u );
2292 }
2293 
2294 
2295 
gl_EvalPoint2(GLcontext * ctx,GLint i,GLint j)2296 void gl_EvalPoint2( GLcontext* ctx, GLint i, GLint j )
2297 {
2298 	GLfloat u, du;
2299 	GLfloat v, dv;
2300 
2301 	if (i==0) {
2302 		u = ctx->Eval.MapGrid2u1;
2303 	}
2304 	else if (i==ctx->Eval.MapGrid2un) {
2305 		u = ctx->Eval.MapGrid2u2;
2306 	}
2307 	else {
2308 		du = (ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1)
2309 			/ (GLfloat) ctx->Eval.MapGrid2un;
2310 		u = i * du + ctx->Eval.MapGrid2u1;
2311 	}
2312 
2313 	if (j==0) {
2314 		v = ctx->Eval.MapGrid2v1;
2315 	}
2316 	else if (j==ctx->Eval.MapGrid2vn) {
2317 		v = ctx->Eval.MapGrid2v2;
2318 	}
2319 	else {
2320 		dv = (ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1)
2321 			/ (GLfloat) ctx->Eval.MapGrid2vn;
2322 		v = j * dv + ctx->Eval.MapGrid2v1;
2323 	}
2324 
2325 	gl_EvalCoord2f( ctx, u, v );
2326 }
2327 
2328 
2329 
gl_EvalMesh1(GLcontext * ctx,GLenum mode,GLint i1,GLint i2)2330 void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 )
2331 {
2332    GLint i;
2333    GLfloat u, du;
2334    GLenum prim;
2335 
2336 	if (INSIDE_BEGIN_END(ctx)) {
2337 		gl_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
2338 		return;
2339 	}
2340 
2341 	switch (mode) {
2342 	case GL_POINT:
2343 		prim = GL_POINTS;
2344 		break;
2345 	case GL_LINE:
2346 		prim = GL_LINE_STRIP;
2347 		break;
2348 	default:
2349 		gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
2350 		return;
2351 	}
2352 
2353 	du = (ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1)
2354 		/ (GLfloat) ctx->Eval.MapGrid1un;
2355 
2356 	gl_Begin( ctx, prim );
2357 	for (i=i1;i<=i2;i++) {
2358 		if (i==0) {
2359 			u = ctx->Eval.MapGrid1u1;
2360 		}
2361 		else if (i==ctx->Eval.MapGrid1un) {
2362 			u = ctx->Eval.MapGrid1u2;
2363 		}
2364 		else {
2365 			u = i * du + ctx->Eval.MapGrid1u1;
2366 		}
2367 		gl_EvalCoord1f( ctx, u );
2368 	}
2369 	gl_End(ctx);
2370 }
2371 
2372 
2373 
gl_EvalMesh2(GLcontext * ctx,GLenum mode,GLint i1,GLint i2,GLint j1,GLint j2)2374 void gl_EvalMesh2( GLcontext* ctx, GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
2375 {
2376 	GLint i, j;
2377 	GLfloat u, du, v, dv, v1, v2;
2378 
2379 	if (INSIDE_BEGIN_END(ctx)) {
2380 		gl_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
2381 		return;
2382 	}
2383 
2384 	du = (ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1)
2385 		/ (GLfloat) ctx->Eval.MapGrid2un;
2386 	dv = (ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1)
2387 		/ (GLfloat) ctx->Eval.MapGrid2vn;
2388 
2389 #define I_TO_U( I, U )				\
2390 	if ((I)==0) {		       	\
2391 		U = ctx->Eval.MapGrid2u1;		\
2392 	}					\
2393 	else if ((I)==ctx->Eval.MapGrid2un) {	\
2394 		U = ctx->Eval.MapGrid2u2;		\
2395 	}					\
2396 	else {				\
2397 		U = (I) * du + ctx->Eval.MapGrid2u1;\
2398 	}
2399 
2400 #define J_TO_V( J, V )				\
2401 	if ((J)==0) {			\
2402 		V = ctx->Eval.MapGrid2v1;		\
2403 	}					\
2404 	else if ((J)==ctx->Eval.MapGrid2vn) {	\
2405 		V = ctx->Eval.MapGrid2v2;		\
2406 	}					\
2407 	else {				\
2408 		V = (J) * dv + ctx->Eval.MapGrid2v1;\
2409 	}
2410 
2411 	switch (mode) {
2412 	case GL_POINT:
2413 		gl_Begin( ctx, GL_POINTS );
2414 		for (j=j1;j<=j2;j++) {
2415 			J_TO_V( j, v );
2416 			for (i=i1;i<=i2;i++) {
2417 				I_TO_U( i, u );
2418 				gl_EvalCoord2f( ctx, u, v );
2419 			}
2420 		}
2421 		gl_End(ctx);
2422 		break;
2423 	case GL_LINE:
2424 		for (j=j1;j<=j2;j++) {
2425 			J_TO_V( j, v );
2426 			gl_Begin( ctx, GL_LINE_STRIP );
2427 			for (i=i1;i<=i2;i++) {
2428 				I_TO_U( i, u );
2429 				gl_EvalCoord2f( ctx, u, v );
2430 			}
2431 			gl_End(ctx);
2432 		}
2433 		for (i=i1;i<=i2;i++) {
2434 			I_TO_U( i, u );
2435 			gl_Begin( ctx, GL_LINE_STRIP );
2436 			for (j=j1;j<=j2;j++) {
2437 				J_TO_V( j, v );
2438 				gl_EvalCoord2f( ctx, u, v );
2439 			}
2440 			gl_End(ctx);
2441 		}
2442 		break;
2443 	case GL_FILL:
2444 		for (j=j1;j<j2;j++) {
2445 			/* NOTE: a quad strip can't be used because the four */
2446 			/* can't be guaranteed to be coplanar! */
2447 			gl_Begin( ctx, GL_TRIANGLE_STRIP );
2448 			J_TO_V( j, v1 );
2449 			J_TO_V( j+1, v2 );
2450 			for (i=i1;i<=i2;i++) {
2451 				I_TO_U( i, u );
2452 				gl_EvalCoord2f( ctx, u, v1 );
2453 				gl_EvalCoord2f( ctx, u, v2 );
2454 			}
2455 			gl_End(ctx);
2456 		}
2457 		break;
2458 	default:
2459 		gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
2460 		return;
2461 	}
2462 
2463 #undef I_TO_U
2464 #undef J_TO_V
2465 }
2466 
2467