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