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