minor clean-ups
[mesa.git] / src / mesa / main / eval.c
1 /* $Id: eval.c,v 1.23 2002/01/05 21:58:42 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 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 "mtypes.h"
52 #endif
53
54
55 /*
56 * Return the number of components per control point for any type of
57 * evaluator. Return 0 if bad target.
58 * See table 5.1 in the OpenGL 1.2 spec.
59 */
60 GLuint _mesa_evaluator_components( GLenum target )
61 {
62 switch (target) {
63 case GL_MAP1_VERTEX_3: return 3;
64 case GL_MAP1_VERTEX_4: return 4;
65 case GL_MAP1_INDEX: return 1;
66 case GL_MAP1_COLOR_4: return 4;
67 case GL_MAP1_NORMAL: return 3;
68 case GL_MAP1_TEXTURE_COORD_1: return 1;
69 case GL_MAP1_TEXTURE_COORD_2: return 2;
70 case GL_MAP1_TEXTURE_COORD_3: return 3;
71 case GL_MAP1_TEXTURE_COORD_4: return 4;
72 case GL_MAP2_VERTEX_3: return 3;
73 case GL_MAP2_VERTEX_4: return 4;
74 case GL_MAP2_INDEX: return 1;
75 case GL_MAP2_COLOR_4: return 4;
76 case GL_MAP2_NORMAL: return 3;
77 case GL_MAP2_TEXTURE_COORD_1: return 1;
78 case GL_MAP2_TEXTURE_COORD_2: return 2;
79 case GL_MAP2_TEXTURE_COORD_3: return 3;
80 case GL_MAP2_TEXTURE_COORD_4: return 4;
81 default: break;
82 }
83
84 /* XXX need to check for the vertex program extension
85 if (!ctx->Extensions.NV_vertex_program)
86 return 0;
87 */
88
89 if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV &&
90 target <= GL_MAP1_VERTEX_ATTRIB15_4_NV)
91 return 4;
92
93 if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV &&
94 target <= GL_MAP2_VERTEX_ATTRIB15_4_NV)
95 return 4;
96
97 return 0;
98 }
99
100
101 /*
102 * Return pointer to the gl_1d_map struct for the named target.
103 */
104 static struct gl_1d_map *
105 get_1d_map( GLcontext *ctx, GLenum target )
106 {
107 switch (target) {
108 case GL_MAP1_VERTEX_3:
109 return &ctx->EvalMap.Map1Vertex3;
110 case GL_MAP1_VERTEX_4:
111 return &ctx->EvalMap.Map1Vertex4;
112 case GL_MAP1_INDEX:
113 return &ctx->EvalMap.Map1Index;
114 case GL_MAP1_COLOR_4:
115 return &ctx->EvalMap.Map1Color4;
116 case GL_MAP1_NORMAL:
117 return &ctx->EvalMap.Map1Normal;
118 case GL_MAP1_TEXTURE_COORD_1:
119 return &ctx->EvalMap.Map1Texture1;
120 case GL_MAP1_TEXTURE_COORD_2:
121 return &ctx->EvalMap.Map1Texture2;
122 case GL_MAP1_TEXTURE_COORD_3:
123 return &ctx->EvalMap.Map1Texture3;
124 case GL_MAP1_TEXTURE_COORD_4:
125 return &ctx->EvalMap.Map1Texture4;
126 case GL_MAP1_VERTEX_ATTRIB0_4_NV:
127 case GL_MAP1_VERTEX_ATTRIB1_4_NV:
128 case GL_MAP1_VERTEX_ATTRIB2_4_NV:
129 case GL_MAP1_VERTEX_ATTRIB3_4_NV:
130 case GL_MAP1_VERTEX_ATTRIB4_4_NV:
131 case GL_MAP1_VERTEX_ATTRIB5_4_NV:
132 case GL_MAP1_VERTEX_ATTRIB6_4_NV:
133 case GL_MAP1_VERTEX_ATTRIB7_4_NV:
134 case GL_MAP1_VERTEX_ATTRIB8_4_NV:
135 case GL_MAP1_VERTEX_ATTRIB9_4_NV:
136 case GL_MAP1_VERTEX_ATTRIB10_4_NV:
137 case GL_MAP1_VERTEX_ATTRIB11_4_NV:
138 case GL_MAP1_VERTEX_ATTRIB12_4_NV:
139 case GL_MAP1_VERTEX_ATTRIB13_4_NV:
140 case GL_MAP1_VERTEX_ATTRIB14_4_NV:
141 case GL_MAP1_VERTEX_ATTRIB15_4_NV:
142 if (!ctx->Extensions.NV_vertex_program)
143 return NULL;
144 return &ctx->EvalMap.Map1Attrib[target - GL_MAP1_VERTEX_ATTRIB0_4_NV];
145 default:
146 return NULL;
147 }
148 }
149
150
151 /*
152 * Return pointer to the gl_2d_map struct for the named target.
153 */
154 static struct gl_2d_map *
155 get_2d_map( GLcontext *ctx, GLenum target )
156 {
157 switch (target) {
158 case GL_MAP2_VERTEX_3:
159 return &ctx->EvalMap.Map2Vertex3;
160 case GL_MAP2_VERTEX_4:
161 return &ctx->EvalMap.Map2Vertex4;
162 case GL_MAP2_INDEX:
163 return &ctx->EvalMap.Map2Index;
164 case GL_MAP2_COLOR_4:
165 return &ctx->EvalMap.Map2Color4;
166 case GL_MAP2_NORMAL:
167 return &ctx->EvalMap.Map2Normal;
168 case GL_MAP2_TEXTURE_COORD_1:
169 return &ctx->EvalMap.Map2Texture1;
170 case GL_MAP2_TEXTURE_COORD_2:
171 return &ctx->EvalMap.Map2Texture2;
172 case GL_MAP2_TEXTURE_COORD_3:
173 return &ctx->EvalMap.Map2Texture3;
174 case GL_MAP2_TEXTURE_COORD_4:
175 return &ctx->EvalMap.Map2Texture4;
176 case GL_MAP2_VERTEX_ATTRIB0_4_NV:
177 case GL_MAP2_VERTEX_ATTRIB1_4_NV:
178 case GL_MAP2_VERTEX_ATTRIB2_4_NV:
179 case GL_MAP2_VERTEX_ATTRIB3_4_NV:
180 case GL_MAP2_VERTEX_ATTRIB4_4_NV:
181 case GL_MAP2_VERTEX_ATTRIB5_4_NV:
182 case GL_MAP2_VERTEX_ATTRIB6_4_NV:
183 case GL_MAP2_VERTEX_ATTRIB7_4_NV:
184 case GL_MAP2_VERTEX_ATTRIB8_4_NV:
185 case GL_MAP2_VERTEX_ATTRIB9_4_NV:
186 case GL_MAP2_VERTEX_ATTRIB10_4_NV:
187 case GL_MAP2_VERTEX_ATTRIB11_4_NV:
188 case GL_MAP2_VERTEX_ATTRIB12_4_NV:
189 case GL_MAP2_VERTEX_ATTRIB13_4_NV:
190 case GL_MAP2_VERTEX_ATTRIB14_4_NV:
191 case GL_MAP2_VERTEX_ATTRIB15_4_NV:
192 if (!ctx->Extensions.NV_vertex_program)
193 return NULL;
194 return &ctx->EvalMap.Map2Attrib[target - GL_MAP2_VERTEX_ATTRIB0_4_NV];
195 default:
196 return NULL;
197 }
198 }
199
200
201 /**********************************************************************/
202 /*** Copy and deallocate control points ***/
203 /**********************************************************************/
204
205
206 /*
207 * Copy 1-parametric evaluator control points from user-specified
208 * memory space to a buffer of contiguous control points.
209 * Input: see glMap1f for details
210 * Return: pointer to buffer of contiguous control points or NULL if out
211 * of memory.
212 */
213 GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
214 const GLfloat *points )
215 {
216 GLfloat *buffer, *p;
217 GLint i, k, size = _mesa_evaluator_components(target);
218
219 if (!points || !size)
220 return NULL;
221
222 buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
223
224 if (buffer)
225 for (i = 0, p = buffer; i < uorder; i++, points += ustride)
226 for (k = 0; k < size; k++)
227 *p++ = points[k];
228
229 return buffer;
230 }
231
232
233
234 /*
235 * Same as above but convert doubles to floats.
236 */
237 GLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
238 const GLdouble *points )
239 {
240 GLfloat *buffer, *p;
241 GLint i, k, size = _mesa_evaluator_components(target);
242
243 if (!points || !size)
244 return NULL;
245
246 buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
247
248 if (buffer)
249 for (i = 0, p = buffer; i < uorder; i++, points += ustride)
250 for (k = 0; k < size; k++)
251 *p++ = (GLfloat) points[k];
252
253 return buffer;
254 }
255
256
257
258 /*
259 * Copy 2-parametric evaluator control points from user-specified
260 * memory space to a buffer of contiguous control points.
261 * Additional memory is allocated to be used by the horner and
262 * de Casteljau evaluation schemes.
263 *
264 * Input: see glMap2f for details
265 * Return: pointer to buffer of contiguous control points or NULL if out
266 * of memory.
267 */
268 GLfloat *_mesa_copy_map_points2f( GLenum target,
269 GLint ustride, GLint uorder,
270 GLint vstride, GLint vorder,
271 const GLfloat *points )
272 {
273 GLfloat *buffer, *p;
274 GLint i, j, k, size, dsize, hsize;
275 GLint uinc;
276
277 size = _mesa_evaluator_components(target);
278
279 if (!points || size==0) {
280 return NULL;
281 }
282
283 /* max(uorder, vorder) additional points are used in */
284 /* horner evaluation and uorder*vorder additional */
285 /* values are needed for de Casteljau */
286 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
287 hsize = (uorder > vorder ? uorder : vorder)*size;
288
289 if(hsize>dsize)
290 buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
291 else
292 buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
293
294 /* compute the increment value for the u-loop */
295 uinc = ustride - vorder*vstride;
296
297 if (buffer)
298 for (i=0, p=buffer; i<uorder; i++, points += uinc)
299 for (j=0; j<vorder; j++, points += vstride)
300 for (k=0; k<size; k++)
301 *p++ = points[k];
302
303 return buffer;
304 }
305
306
307
308 /*
309 * Same as above but convert doubles to floats.
310 */
311 GLfloat *_mesa_copy_map_points2d(GLenum target,
312 GLint ustride, GLint uorder,
313 GLint vstride, GLint vorder,
314 const GLdouble *points )
315 {
316 GLfloat *buffer, *p;
317 GLint i, j, k, size, hsize, dsize;
318 GLint uinc;
319
320 size = _mesa_evaluator_components(target);
321
322 if (!points || size==0) {
323 return NULL;
324 }
325
326 /* max(uorder, vorder) additional points are used in */
327 /* horner evaluation and uorder*vorder additional */
328 /* values are needed for de Casteljau */
329 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
330 hsize = (uorder > vorder ? uorder : vorder)*size;
331
332 if(hsize>dsize)
333 buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
334 else
335 buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
336
337 /* compute the increment value for the u-loop */
338 uinc = ustride - vorder*vstride;
339
340 if (buffer)
341 for (i=0, p=buffer; i<uorder; i++, points += uinc)
342 for (j=0; j<vorder; j++, points += vstride)
343 for (k=0; k<size; k++)
344 *p++ = (GLfloat) points[k];
345
346 return buffer;
347 }
348
349
350
351
352 /**********************************************************************/
353 /*** API entry points ***/
354 /**********************************************************************/
355
356
357 /*
358 * This does the work of glMap1[fd].
359 */
360 static void
361 map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
362 GLint uorder, const GLvoid *points, GLenum type )
363 {
364 GET_CURRENT_CONTEXT(ctx);
365 GLint k;
366 GLfloat *pnts;
367 struct gl_1d_map *map = NULL;
368
369 ASSERT_OUTSIDE_BEGIN_END(ctx);
370 ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
371
372 if (u1 == u2) {
373 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
374 return;
375 }
376 if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
377 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
378 return;
379 }
380 if (!points) {
381 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
382 return;
383 }
384
385 k = _mesa_evaluator_components( target );
386 if (k == 0) {
387 _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
388 }
389
390 if (ustride < k) {
391 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
392 return;
393 }
394
395 if (ctx->Texture.CurrentUnit != 0) {
396 /* See OpenGL 1.2.1 spec, section F.2.13 */
397 _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
398 return;
399 }
400
401 map = get_1d_map(ctx, target);
402 if (!map) {
403 _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
404 return;
405 }
406
407 /* make copy of the control points */
408 if (type == GL_FLOAT)
409 pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
410 else
411 pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
412
413
414 FLUSH_VERTICES(ctx, _NEW_EVAL);
415 map->Order = uorder;
416 map->u1 = u1;
417 map->u2 = u2;
418 map->du = 1.0F / (u2 - u1);
419 if (map->Points)
420 FREE( map->Points );
421 map->Points = pnts;
422 }
423
424
425
426 void
427 _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
428 GLint order, const GLfloat *points )
429 {
430 map1(target, u1, u2, stride, order, points, GL_FLOAT);
431 }
432
433
434 void
435 _mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
436 GLint order, const GLdouble *points )
437 {
438 map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE);
439 }
440
441
442 static void
443 map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
444 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
445 const GLvoid *points, GLenum type )
446 {
447 GET_CURRENT_CONTEXT(ctx);
448 GLint k;
449 GLfloat *pnts;
450 struct gl_2d_map *map = NULL;
451
452 ASSERT_OUTSIDE_BEGIN_END(ctx);
453 ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
454
455 if (u1==u2) {
456 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
457 return;
458 }
459
460 if (v1==v2) {
461 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
462 return;
463 }
464
465 if (uorder<1 || uorder>MAX_EVAL_ORDER) {
466 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
467 return;
468 }
469
470 if (vorder<1 || vorder>MAX_EVAL_ORDER) {
471 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
472 return;
473 }
474
475 k = _mesa_evaluator_components( target );
476 if (k==0) {
477 _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
478 }
479
480 if (ustride < k) {
481 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
482 return;
483 }
484 if (vstride < k) {
485 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
486 return;
487 }
488
489 if (ctx->Texture.CurrentUnit != 0) {
490 /* See OpenGL 1.2.1 spec, section F.2.13 */
491 _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
492 return;
493 }
494
495 map = get_2d_map(ctx, target);
496 if (!map) {
497 _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
498 return;
499 }
500
501 /* make copy of the control points */
502 if (type == GL_FLOAT)
503 pnts = _mesa_copy_map_points2f(target, ustride, uorder,
504 vstride, vorder, (GLfloat*) points);
505 else
506 pnts = _mesa_copy_map_points2d(target, ustride, uorder,
507 vstride, vorder, (GLdouble*) points);
508
509
510 FLUSH_VERTICES(ctx, _NEW_EVAL);
511 map->Uorder = uorder;
512 map->u1 = u1;
513 map->u2 = u2;
514 map->du = 1.0F / (u2 - u1);
515 map->Vorder = vorder;
516 map->v1 = v1;
517 map->v2 = v2;
518 map->dv = 1.0F / (v2 - v1);
519 if (map->Points)
520 FREE( map->Points );
521 map->Points = pnts;
522 }
523
524
525 void
526 _mesa_Map2f( GLenum target,
527 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
528 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
529 const GLfloat *points)
530 {
531 map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
532 points, GL_FLOAT);
533 }
534
535
536 void
537 _mesa_Map2d( GLenum target,
538 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
539 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
540 const GLdouble *points )
541 {
542 map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder,
543 (GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE);
544 }
545
546
547
548 void
549 _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
550 {
551 GET_CURRENT_CONTEXT(ctx);
552 struct gl_1d_map *map1d;
553 struct gl_2d_map *map2d;
554 GLint i, n;
555 GLfloat *data;
556 GLuint comps;
557
558 ASSERT_OUTSIDE_BEGIN_END(ctx);
559
560 comps = _mesa_evaluator_components(target);
561 if (!comps) {
562 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
563 return;
564 }
565
566 map1d = get_1d_map(ctx, target);
567 map2d = get_2d_map(ctx, target);
568 ASSERT(map1d || map2d);
569
570 switch (query) {
571 case GL_COEFF:
572 if (map1d) {
573 data = map1d->Points;
574 n = map1d->Order * comps;
575 }
576 else {
577 data = map2d->Points;
578 n = map2d->Uorder * map2d->Vorder * comps;
579 }
580 if (data) {
581 for (i=0;i<n;i++) {
582 v[i] = data[i];
583 }
584 }
585 break;
586 case GL_ORDER:
587 if (map1d) {
588 v[0] = (GLdouble) map1d->Order;
589 }
590 else {
591 v[0] = (GLdouble) map2d->Uorder;
592 v[1] = (GLdouble) map2d->Vorder;
593 }
594 break;
595 case GL_DOMAIN:
596 if (map1d) {
597 v[0] = (GLdouble) map1d->u1;
598 v[1] = (GLdouble) map1d->u2;
599 }
600 else {
601 v[0] = (GLdouble) map2d->u1;
602 v[1] = (GLdouble) map2d->u2;
603 v[2] = (GLdouble) map2d->v1;
604 v[3] = (GLdouble) map2d->v2;
605 }
606 break;
607 default:
608 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
609 }
610 }
611
612
613 void
614 _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
615 {
616 GET_CURRENT_CONTEXT(ctx);
617 struct gl_1d_map *map1d;
618 struct gl_2d_map *map2d;
619 GLint i, n;
620 GLfloat *data;
621 GLuint comps;
622
623 ASSERT_OUTSIDE_BEGIN_END(ctx);
624
625 comps = _mesa_evaluator_components(target);
626 if (!comps) {
627 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
628 return;
629 }
630
631 map1d = get_1d_map(ctx, target);
632 map2d = get_2d_map(ctx, target);
633 ASSERT(map1d || map2d);
634
635 switch (query) {
636 case GL_COEFF:
637 if (map1d) {
638 data = map1d->Points;
639 n = map1d->Order * comps;
640 }
641 else {
642 data = map2d->Points;
643 n = map2d->Uorder * map2d->Vorder * comps;
644 }
645 if (data) {
646 for (i=0;i<n;i++) {
647 v[i] = data[i];
648 }
649 }
650 break;
651 case GL_ORDER:
652 if (map1d) {
653 v[0] = (GLfloat) map1d->Order;
654 }
655 else {
656 v[0] = (GLfloat) map2d->Uorder;
657 v[1] = (GLfloat) map2d->Vorder;
658 }
659 break;
660 case GL_DOMAIN:
661 if (map1d) {
662 v[0] = map1d->u1;
663 v[1] = map1d->u2;
664 }
665 else {
666 v[0] = map2d->u1;
667 v[1] = map2d->u2;
668 v[2] = map2d->v1;
669 v[3] = map2d->v2;
670 }
671 break;
672 default:
673 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
674 }
675 }
676
677
678 void
679 _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
680 {
681 GET_CURRENT_CONTEXT(ctx);
682 struct gl_1d_map *map1d;
683 struct gl_2d_map *map2d;
684 GLuint i, n;
685 GLfloat *data;
686 GLuint comps;
687
688 ASSERT_OUTSIDE_BEGIN_END(ctx);
689
690 comps = _mesa_evaluator_components(target);
691 if (!comps) {
692 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
693 return;
694 }
695
696 map1d = get_1d_map(ctx, target);
697 map2d = get_2d_map(ctx, target);
698 ASSERT(map1d || map2d);
699
700 switch (query) {
701 case GL_COEFF:
702 if (map1d) {
703 data = map1d->Points;
704 n = map1d->Order * comps;
705 }
706 else {
707 data = map2d->Points;
708 n = map2d->Uorder * map2d->Vorder * comps;
709 }
710 if (data) {
711 for (i=0;i<n;i++) {
712 v[i] = ROUNDF(data[i]);
713 }
714 }
715 break;
716 case GL_ORDER:
717 if (map1d) {
718 v[0] = map1d->Order;
719 }
720 else {
721 v[0] = map2d->Uorder;
722 v[1] = map2d->Vorder;
723 }
724 break;
725 case GL_DOMAIN:
726 if (map1d) {
727 v[0] = ROUNDF(map1d->u1);
728 v[1] = ROUNDF(map1d->u2);
729 }
730 else {
731 v[0] = ROUNDF(map2d->u1);
732 v[1] = ROUNDF(map2d->u2);
733 v[2] = ROUNDF(map2d->v1);
734 v[3] = ROUNDF(map2d->v2);
735 }
736 break;
737 default:
738 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
739 }
740 }
741
742
743
744 void
745 _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
746 {
747 GET_CURRENT_CONTEXT(ctx);
748 ASSERT_OUTSIDE_BEGIN_END(ctx);
749
750 if (un<1) {
751 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
752 return;
753 }
754 FLUSH_VERTICES(ctx, _NEW_EVAL);
755 ctx->Eval.MapGrid1un = un;
756 ctx->Eval.MapGrid1u1 = u1;
757 ctx->Eval.MapGrid1u2 = u2;
758 ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
759 }
760
761
762 void
763 _mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
764 {
765 _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 );
766 }
767
768
769 void
770 _mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
771 GLint vn, GLfloat v1, GLfloat v2 )
772 {
773 GET_CURRENT_CONTEXT(ctx);
774 ASSERT_OUTSIDE_BEGIN_END(ctx);
775
776 if (un<1) {
777 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
778 return;
779 }
780 if (vn<1) {
781 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
782 return;
783 }
784
785 FLUSH_VERTICES(ctx, _NEW_EVAL);
786 ctx->Eval.MapGrid2un = un;
787 ctx->Eval.MapGrid2u1 = u1;
788 ctx->Eval.MapGrid2u2 = u2;
789 ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
790 ctx->Eval.MapGrid2vn = vn;
791 ctx->Eval.MapGrid2v1 = v1;
792 ctx->Eval.MapGrid2v2 = v2;
793 ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
794 }
795
796
797 void
798 _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
799 GLint vn, GLdouble v1, GLdouble v2 )
800 {
801 _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2,
802 vn, (GLfloat) v1, (GLfloat) v2 );
803 }