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