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