source: trunk/src/opengl/mesa/eval.c@ 3597

Last change on this file since 3597 was 2962, checked in by jeroen, 25 years ago

* empty log message *

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