dispatch: Delete unused init_dispatch functions.
[mesa.git] / src / mesa / main / eval.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 5.1
5 *
6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 /*
28 * eval.c was written by
29 * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
30 * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
31 *
32 * My original implementation of evaluators was simplistic and didn't
33 * compute surface normal vectors properly. Bernd and Volker applied
34 * used more sophisticated methods to get better results.
35 *
36 * Thanks guys!
37 */
38
39
40 #include "glheader.h"
41 #include "imports.h"
42 #include "colormac.h"
43 #include "context.h"
44 #include "eval.h"
45 #include "macros.h"
46 #include "mfeatures.h"
47 #include "mtypes.h"
48 #include "main/dispatch.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 return 0;
81 }
82
83
84 /*
85 * Return pointer to the gl_1d_map struct for the named target.
86 */
87 static struct gl_1d_map *
88 get_1d_map( struct gl_context *ctx, GLenum target )
89 {
90 switch (target) {
91 case GL_MAP1_VERTEX_3:
92 return &ctx->EvalMap.Map1Vertex3;
93 case GL_MAP1_VERTEX_4:
94 return &ctx->EvalMap.Map1Vertex4;
95 case GL_MAP1_INDEX:
96 return &ctx->EvalMap.Map1Index;
97 case GL_MAP1_COLOR_4:
98 return &ctx->EvalMap.Map1Color4;
99 case GL_MAP1_NORMAL:
100 return &ctx->EvalMap.Map1Normal;
101 case GL_MAP1_TEXTURE_COORD_1:
102 return &ctx->EvalMap.Map1Texture1;
103 case GL_MAP1_TEXTURE_COORD_2:
104 return &ctx->EvalMap.Map1Texture2;
105 case GL_MAP1_TEXTURE_COORD_3:
106 return &ctx->EvalMap.Map1Texture3;
107 case GL_MAP1_TEXTURE_COORD_4:
108 return &ctx->EvalMap.Map1Texture4;
109 default:
110 return NULL;
111 }
112 }
113
114
115 /*
116 * Return pointer to the gl_2d_map struct for the named target.
117 */
118 static struct gl_2d_map *
119 get_2d_map( struct gl_context *ctx, GLenum target )
120 {
121 switch (target) {
122 case GL_MAP2_VERTEX_3:
123 return &ctx->EvalMap.Map2Vertex3;
124 case GL_MAP2_VERTEX_4:
125 return &ctx->EvalMap.Map2Vertex4;
126 case GL_MAP2_INDEX:
127 return &ctx->EvalMap.Map2Index;
128 case GL_MAP2_COLOR_4:
129 return &ctx->EvalMap.Map2Color4;
130 case GL_MAP2_NORMAL:
131 return &ctx->EvalMap.Map2Normal;
132 case GL_MAP2_TEXTURE_COORD_1:
133 return &ctx->EvalMap.Map2Texture1;
134 case GL_MAP2_TEXTURE_COORD_2:
135 return &ctx->EvalMap.Map2Texture2;
136 case GL_MAP2_TEXTURE_COORD_3:
137 return &ctx->EvalMap.Map2Texture3;
138 case GL_MAP2_TEXTURE_COORD_4:
139 return &ctx->EvalMap.Map2Texture4;
140 default:
141 return NULL;
142 }
143 }
144
145
146 /**********************************************************************/
147 /*** Copy and deallocate control points ***/
148 /**********************************************************************/
149
150
151 /*
152 * Copy 1-parametric evaluator control points from user-specified
153 * memory space to a buffer of contiguous control points.
154 * \param see glMap1f for details
155 * \return pointer to buffer of contiguous control points or NULL if out
156 * of memory.
157 */
158 GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
159 const GLfloat *points )
160 {
161 GLfloat *buffer, *p;
162 GLint i, k, size = _mesa_evaluator_components(target);
163
164 if (!points || !size)
165 return NULL;
166
167 buffer = malloc(uorder * size * sizeof(GLfloat));
168
169 if (buffer)
170 for (i = 0, p = buffer; i < uorder; i++, points += ustride)
171 for (k = 0; k < size; k++)
172 *p++ = points[k];
173
174 return buffer;
175 }
176
177
178
179 /*
180 * Same as above but convert doubles to floats.
181 */
182 GLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
183 const GLdouble *points )
184 {
185 GLfloat *buffer, *p;
186 GLint i, k, size = _mesa_evaluator_components(target);
187
188 if (!points || !size)
189 return NULL;
190
191 buffer = malloc(uorder * size * sizeof(GLfloat));
192
193 if (buffer)
194 for (i = 0, p = buffer; i < uorder; i++, points += ustride)
195 for (k = 0; k < size; k++)
196 *p++ = (GLfloat) points[k];
197
198 return buffer;
199 }
200
201
202
203 /*
204 * Copy 2-parametric evaluator control points from user-specified
205 * memory space to a buffer of contiguous control points.
206 * Additional memory is allocated to be used by the horner and
207 * de Casteljau evaluation schemes.
208 *
209 * \param see glMap2f for details
210 * \return pointer to buffer of contiguous control points or NULL if out
211 * of memory.
212 */
213 GLfloat *_mesa_copy_map_points2f( GLenum target,
214 GLint ustride, GLint uorder,
215 GLint vstride, GLint vorder,
216 const GLfloat *points )
217 {
218 GLfloat *buffer, *p;
219 GLint i, j, k, size, dsize, hsize;
220 GLint uinc;
221
222 size = _mesa_evaluator_components(target);
223
224 if (!points || size==0) {
225 return NULL;
226 }
227
228 /* max(uorder, vorder) additional points are used in */
229 /* horner evaluation and uorder*vorder additional */
230 /* values are needed for de Casteljau */
231 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
232 hsize = (uorder > vorder ? uorder : vorder)*size;
233
234 if(hsize>dsize)
235 buffer = malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
236 else
237 buffer = malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
238
239 /* compute the increment value for the u-loop */
240 uinc = ustride - vorder*vstride;
241
242 if (buffer)
243 for (i=0, p=buffer; i<uorder; i++, points += uinc)
244 for (j=0; j<vorder; j++, points += vstride)
245 for (k=0; k<size; k++)
246 *p++ = points[k];
247
248 return buffer;
249 }
250
251
252
253 /*
254 * Same as above but convert doubles to floats.
255 */
256 GLfloat *_mesa_copy_map_points2d(GLenum target,
257 GLint ustride, GLint uorder,
258 GLint vstride, GLint vorder,
259 const GLdouble *points )
260 {
261 GLfloat *buffer, *p;
262 GLint i, j, k, size, hsize, dsize;
263 GLint uinc;
264
265 size = _mesa_evaluator_components(target);
266
267 if (!points || size==0) {
268 return NULL;
269 }
270
271 /* max(uorder, vorder) additional points are used in */
272 /* horner evaluation and uorder*vorder additional */
273 /* values are needed for de Casteljau */
274 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
275 hsize = (uorder > vorder ? uorder : vorder)*size;
276
277 if(hsize>dsize)
278 buffer = malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
279 else
280 buffer = malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
281
282 /* compute the increment value for the u-loop */
283 uinc = ustride - vorder*vstride;
284
285 if (buffer)
286 for (i=0, p=buffer; i<uorder; i++, points += uinc)
287 for (j=0; j<vorder; j++, points += vstride)
288 for (k=0; k<size; k++)
289 *p++ = (GLfloat) points[k];
290
291 return buffer;
292 }
293
294
295
296
297 /**********************************************************************/
298 /*** API entry points ***/
299 /**********************************************************************/
300
301
302 /*
303 * This does the work of glMap1[fd].
304 */
305 static void
306 map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
307 GLint uorder, const GLvoid *points, GLenum type )
308 {
309 GET_CURRENT_CONTEXT(ctx);
310 GLint k;
311 GLfloat *pnts;
312 struct gl_1d_map *map = NULL;
313
314 ASSERT_OUTSIDE_BEGIN_END(ctx);
315 ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
316
317 if (u1 == u2) {
318 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
319 return;
320 }
321 if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
322 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
323 return;
324 }
325 if (!points) {
326 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
327 return;
328 }
329
330 k = _mesa_evaluator_components( target );
331 if (k == 0) {
332 _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
333 return;
334 }
335
336 if (ustride < k) {
337 _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
338 return;
339 }
340
341 if (ctx->Texture.CurrentUnit != 0) {
342 /* See OpenGL 1.2.1 spec, section F.2.13 */
343 _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
344 return;
345 }
346
347 map = get_1d_map(ctx, target);
348 if (!map) {
349 _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
350 return;
351 }
352
353 /* make copy of the control points */
354 if (type == GL_FLOAT)
355 pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
356 else
357 pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
358
359
360 FLUSH_VERTICES(ctx, _NEW_EVAL);
361 map->Order = uorder;
362 map->u1 = u1;
363 map->u2 = u2;
364 map->du = 1.0F / (u2 - u1);
365 free(map->Points);
366 map->Points = pnts;
367 }
368
369
370
371 void GLAPIENTRY
372 _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
373 GLint order, const GLfloat *points )
374 {
375 map1(target, u1, u2, stride, order, points, GL_FLOAT);
376 }
377
378
379 void GLAPIENTRY
380 _mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
381 GLint order, const GLdouble *points )
382 {
383 map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE);
384 }
385
386
387 static void
388 map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
389 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
390 const GLvoid *points, GLenum type )
391 {
392 GET_CURRENT_CONTEXT(ctx);
393 GLint k;
394 GLfloat *pnts;
395 struct gl_2d_map *map = NULL;
396
397 ASSERT_OUTSIDE_BEGIN_END(ctx);
398 ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
399
400 if (u1==u2) {
401 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
402 return;
403 }
404
405 if (v1==v2) {
406 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
407 return;
408 }
409
410 if (uorder<1 || uorder>MAX_EVAL_ORDER) {
411 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
412 return;
413 }
414
415 if (vorder<1 || vorder>MAX_EVAL_ORDER) {
416 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
417 return;
418 }
419
420 k = _mesa_evaluator_components( target );
421 if (k==0) {
422 _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
423 return;
424 }
425
426 if (ustride < k) {
427 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
428 return;
429 }
430 if (vstride < k) {
431 _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
432 return;
433 }
434
435 if (ctx->Texture.CurrentUnit != 0) {
436 /* See OpenGL 1.2.1 spec, section F.2.13 */
437 _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
438 return;
439 }
440
441 map = get_2d_map(ctx, target);
442 if (!map) {
443 _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
444 return;
445 }
446
447 /* make copy of the control points */
448 if (type == GL_FLOAT)
449 pnts = _mesa_copy_map_points2f(target, ustride, uorder,
450 vstride, vorder, (GLfloat*) points);
451 else
452 pnts = _mesa_copy_map_points2d(target, ustride, uorder,
453 vstride, vorder, (GLdouble*) points);
454
455
456 FLUSH_VERTICES(ctx, _NEW_EVAL);
457 map->Uorder = uorder;
458 map->u1 = u1;
459 map->u2 = u2;
460 map->du = 1.0F / (u2 - u1);
461 map->Vorder = vorder;
462 map->v1 = v1;
463 map->v2 = v2;
464 map->dv = 1.0F / (v2 - v1);
465 free(map->Points);
466 map->Points = pnts;
467 }
468
469
470 void GLAPIENTRY
471 _mesa_Map2f( GLenum target,
472 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
473 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
474 const GLfloat *points)
475 {
476 map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
477 points, GL_FLOAT);
478 }
479
480
481 void GLAPIENTRY
482 _mesa_Map2d( GLenum target,
483 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
484 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
485 const GLdouble *points )
486 {
487 map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder,
488 (GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE);
489 }
490
491
492
493 void GLAPIENTRY
494 _mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, GLdouble *v )
495 {
496 GET_CURRENT_CONTEXT(ctx);
497 struct gl_1d_map *map1d;
498 struct gl_2d_map *map2d;
499 GLint i, n;
500 GLfloat *data;
501 GLuint comps;
502 GLsizei numBytes;
503
504 ASSERT_OUTSIDE_BEGIN_END(ctx);
505
506 comps = _mesa_evaluator_components(target);
507 if (!comps) {
508 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
509 return;
510 }
511
512 map1d = get_1d_map(ctx, target);
513 map2d = get_2d_map(ctx, target);
514 ASSERT(map1d || map2d);
515
516 switch (query) {
517 case GL_COEFF:
518 if (map1d) {
519 data = map1d->Points;
520 n = map1d->Order * comps;
521 }
522 else {
523 data = map2d->Points;
524 n = map2d->Uorder * map2d->Vorder * comps;
525 }
526 if (data) {
527 numBytes = n * sizeof *v;
528 if (bufSize < numBytes)
529 goto overflow;
530 for (i=0;i<n;i++) {
531 v[i] = data[i];
532 }
533 }
534 break;
535 case GL_ORDER:
536 if (map1d) {
537 numBytes = 1 * sizeof *v;
538 if (bufSize < numBytes)
539 goto overflow;
540 v[0] = (GLdouble) map1d->Order;
541 }
542 else {
543 numBytes = 2 * sizeof *v;
544 if (bufSize < numBytes)
545 goto overflow;
546 v[0] = (GLdouble) map2d->Uorder;
547 v[1] = (GLdouble) map2d->Vorder;
548 }
549 break;
550 case GL_DOMAIN:
551 if (map1d) {
552 numBytes = 2 * sizeof *v;
553 if (bufSize < numBytes)
554 goto overflow;
555 v[0] = (GLdouble) map1d->u1;
556 v[1] = (GLdouble) map1d->u2;
557 }
558 else {
559 numBytes = 4 * sizeof *v;
560 if (bufSize < numBytes)
561 goto overflow;
562 v[0] = (GLdouble) map2d->u1;
563 v[1] = (GLdouble) map2d->u2;
564 v[2] = (GLdouble) map2d->v1;
565 v[3] = (GLdouble) map2d->v2;
566 }
567 break;
568 default:
569 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
570 }
571 return;
572
573 overflow:
574 _mesa_error( ctx, GL_INVALID_OPERATION,
575 "glGetnMapdvARB(out of bounds: bufSize is %d,"
576 " but %d bytes are required)", bufSize, numBytes );
577 }
578
579 void GLAPIENTRY
580 _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
581 {
582 _mesa_GetnMapdvARB(target, query, INT_MAX, v);
583 }
584
585 void GLAPIENTRY
586 _mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v )
587 {
588 GET_CURRENT_CONTEXT(ctx);
589 struct gl_1d_map *map1d;
590 struct gl_2d_map *map2d;
591 GLint i, n;
592 GLfloat *data;
593 GLuint comps;
594 GLsizei numBytes;
595
596 ASSERT_OUTSIDE_BEGIN_END(ctx);
597
598 comps = _mesa_evaluator_components(target);
599 if (!comps) {
600 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
601 return;
602 }
603
604 map1d = get_1d_map(ctx, target);
605 map2d = get_2d_map(ctx, target);
606 ASSERT(map1d || map2d);
607
608 switch (query) {
609 case GL_COEFF:
610 if (map1d) {
611 data = map1d->Points;
612 n = map1d->Order * comps;
613 }
614 else {
615 data = map2d->Points;
616 n = map2d->Uorder * map2d->Vorder * comps;
617 }
618 if (data) {
619 numBytes = n * sizeof *v;
620 if (bufSize < numBytes)
621 goto overflow;
622 for (i=0;i<n;i++) {
623 v[i] = data[i];
624 }
625 }
626 break;
627 case GL_ORDER:
628 if (map1d) {
629 numBytes = 1 * sizeof *v;
630 if (bufSize < numBytes)
631 goto overflow;
632 v[0] = (GLfloat) map1d->Order;
633 }
634 else {
635 numBytes = 2 * sizeof *v;
636 if (bufSize < numBytes)
637 goto overflow;
638 v[0] = (GLfloat) map2d->Uorder;
639 v[1] = (GLfloat) map2d->Vorder;
640 }
641 break;
642 case GL_DOMAIN:
643 if (map1d) {
644 numBytes = 2 * sizeof *v;
645 if (bufSize < numBytes)
646 goto overflow;
647 v[0] = map1d->u1;
648 v[1] = map1d->u2;
649 }
650 else {
651 numBytes = 4 * sizeof *v;
652 if (bufSize < numBytes)
653 goto overflow;
654 v[0] = map2d->u1;
655 v[1] = map2d->u2;
656 v[2] = map2d->v1;
657 v[3] = map2d->v2;
658 }
659 break;
660 default:
661 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
662 }
663 return;
664
665 overflow:
666 _mesa_error( ctx, GL_INVALID_OPERATION,
667 "glGetnMapfvARB(out of bounds: bufSize is %d,"
668 " but %d bytes are required)", bufSize, numBytes );
669 }
670
671
672 void GLAPIENTRY
673 _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
674 {
675 _mesa_GetnMapfvARB(target, query, INT_MAX, v);
676 }
677
678
679 void GLAPIENTRY
680 _mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v )
681 {
682 GET_CURRENT_CONTEXT(ctx);
683 struct gl_1d_map *map1d;
684 struct gl_2d_map *map2d;
685 GLuint i, n;
686 GLfloat *data;
687 GLuint comps;
688 GLsizei numBytes;
689
690 ASSERT_OUTSIDE_BEGIN_END(ctx);
691
692 comps = _mesa_evaluator_components(target);
693 if (!comps) {
694 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
695 return;
696 }
697
698 map1d = get_1d_map(ctx, target);
699 map2d = get_2d_map(ctx, target);
700 ASSERT(map1d || map2d);
701
702 switch (query) {
703 case GL_COEFF:
704 if (map1d) {
705 data = map1d->Points;
706 n = map1d->Order * comps;
707 }
708 else {
709 data = map2d->Points;
710 n = map2d->Uorder * map2d->Vorder * comps;
711 }
712 if (data) {
713 numBytes = n * sizeof *v;
714 if (bufSize < numBytes)
715 goto overflow;
716 for (i=0;i<n;i++) {
717 v[i] = IROUND(data[i]);
718 }
719 }
720 break;
721 case GL_ORDER:
722 if (map1d) {
723 numBytes = 1 * sizeof *v;
724 if (bufSize < numBytes)
725 goto overflow;
726 v[0] = map1d->Order;
727 }
728 else {
729 numBytes = 2 * sizeof *v;
730 if (bufSize < numBytes)
731 goto overflow;
732 v[0] = map2d->Uorder;
733 v[1] = map2d->Vorder;
734 }
735 break;
736 case GL_DOMAIN:
737 if (map1d) {
738 numBytes = 2 * sizeof *v;
739 if (bufSize < numBytes)
740 goto overflow;
741 v[0] = IROUND(map1d->u1);
742 v[1] = IROUND(map1d->u2);
743 }
744 else {
745 numBytes = 4 * sizeof *v;
746 if (bufSize < numBytes)
747 goto overflow;
748 v[0] = IROUND(map2d->u1);
749 v[1] = IROUND(map2d->u2);
750 v[2] = IROUND(map2d->v1);
751 v[3] = IROUND(map2d->v2);
752 }
753 break;
754 default:
755 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
756 }
757 return;
758
759 overflow:
760 _mesa_error( ctx, GL_INVALID_OPERATION,
761 "glGetnMapivARB(out of bounds: bufSize is %d,"
762 " but %d bytes are required)", bufSize, numBytes );
763 }
764
765
766 void GLAPIENTRY
767 _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
768 {
769 _mesa_GetnMapivARB(target, query, INT_MAX, v);
770 }
771
772
773 void GLAPIENTRY
774 _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
775 {
776 GET_CURRENT_CONTEXT(ctx);
777 ASSERT_OUTSIDE_BEGIN_END(ctx);
778
779 if (un<1) {
780 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
781 return;
782 }
783 FLUSH_VERTICES(ctx, _NEW_EVAL);
784 ctx->Eval.MapGrid1un = un;
785 ctx->Eval.MapGrid1u1 = u1;
786 ctx->Eval.MapGrid1u2 = u2;
787 ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
788 }
789
790
791 void GLAPIENTRY
792 _mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
793 {
794 _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 );
795 }
796
797
798 void GLAPIENTRY
799 _mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
800 GLint vn, GLfloat v1, GLfloat v2 )
801 {
802 GET_CURRENT_CONTEXT(ctx);
803 ASSERT_OUTSIDE_BEGIN_END(ctx);
804
805 if (un<1) {
806 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
807 return;
808 }
809 if (vn<1) {
810 _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
811 return;
812 }
813
814 FLUSH_VERTICES(ctx, _NEW_EVAL);
815 ctx->Eval.MapGrid2un = un;
816 ctx->Eval.MapGrid2u1 = u1;
817 ctx->Eval.MapGrid2u2 = u2;
818 ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
819 ctx->Eval.MapGrid2vn = vn;
820 ctx->Eval.MapGrid2v1 = v1;
821 ctx->Eval.MapGrid2v2 = v2;
822 ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
823 }
824
825
826 void GLAPIENTRY
827 _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
828 GLint vn, GLdouble v1, GLdouble v2 )
829 {
830 _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2,
831 vn, (GLfloat) v1, (GLfloat) v2 );
832 }
833
834
835 void
836 _mesa_install_eval_vtxfmt(struct _glapi_table *disp,
837 const GLvertexformat *vfmt)
838 {
839 SET_EvalCoord1f(disp, vfmt->EvalCoord1f);
840 SET_EvalCoord1fv(disp, vfmt->EvalCoord1fv);
841 SET_EvalCoord2f(disp, vfmt->EvalCoord2f);
842 SET_EvalCoord2fv(disp, vfmt->EvalCoord2fv);
843 SET_EvalPoint1(disp, vfmt->EvalPoint1);
844 SET_EvalPoint2(disp, vfmt->EvalPoint2);
845
846 SET_EvalMesh1(disp, vfmt->EvalMesh1);
847 SET_EvalMesh2(disp, vfmt->EvalMesh2);
848 }
849
850
851 /**********************************************************************/
852 /***** Initialization *****/
853 /**********************************************************************/
854
855 /**
856 * Initialize a 1-D evaluator map.
857 */
858 static void
859 init_1d_map( struct gl_1d_map *map, int n, const float *initial )
860 {
861 map->Order = 1;
862 map->u1 = 0.0;
863 map->u2 = 1.0;
864 map->Points = malloc(n * sizeof(GLfloat));
865 if (map->Points) {
866 GLint i;
867 for (i=0;i<n;i++)
868 map->Points[i] = initial[i];
869 }
870 }
871
872
873 /**
874 * Initialize a 2-D evaluator map
875 */
876 static void
877 init_2d_map( struct gl_2d_map *map, int n, const float *initial )
878 {
879 map->Uorder = 1;
880 map->Vorder = 1;
881 map->u1 = 0.0;
882 map->u2 = 1.0;
883 map->v1 = 0.0;
884 map->v2 = 1.0;
885 map->Points = malloc(n * sizeof(GLfloat));
886 if (map->Points) {
887 GLint i;
888 for (i=0;i<n;i++)
889 map->Points[i] = initial[i];
890 }
891 }
892
893
894 void _mesa_init_eval( struct gl_context *ctx )
895 {
896 /* Evaluators group */
897 ctx->Eval.Map1Color4 = GL_FALSE;
898 ctx->Eval.Map1Index = GL_FALSE;
899 ctx->Eval.Map1Normal = GL_FALSE;
900 ctx->Eval.Map1TextureCoord1 = GL_FALSE;
901 ctx->Eval.Map1TextureCoord2 = GL_FALSE;
902 ctx->Eval.Map1TextureCoord3 = GL_FALSE;
903 ctx->Eval.Map1TextureCoord4 = GL_FALSE;
904 ctx->Eval.Map1Vertex3 = GL_FALSE;
905 ctx->Eval.Map1Vertex4 = GL_FALSE;
906 ctx->Eval.Map2Color4 = GL_FALSE;
907 ctx->Eval.Map2Index = GL_FALSE;
908 ctx->Eval.Map2Normal = GL_FALSE;
909 ctx->Eval.Map2TextureCoord1 = GL_FALSE;
910 ctx->Eval.Map2TextureCoord2 = GL_FALSE;
911 ctx->Eval.Map2TextureCoord3 = GL_FALSE;
912 ctx->Eval.Map2TextureCoord4 = GL_FALSE;
913 ctx->Eval.Map2Vertex3 = GL_FALSE;
914 ctx->Eval.Map2Vertex4 = GL_FALSE;
915 ctx->Eval.AutoNormal = GL_FALSE;
916 ctx->Eval.MapGrid1un = 1;
917 ctx->Eval.MapGrid1u1 = 0.0;
918 ctx->Eval.MapGrid1u2 = 1.0;
919 ctx->Eval.MapGrid2un = 1;
920 ctx->Eval.MapGrid2vn = 1;
921 ctx->Eval.MapGrid2u1 = 0.0;
922 ctx->Eval.MapGrid2u2 = 1.0;
923 ctx->Eval.MapGrid2v1 = 0.0;
924 ctx->Eval.MapGrid2v2 = 1.0;
925
926 /* Evaluator data */
927 {
928 static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
929 static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
930 static GLfloat index[1] = { 1.0 };
931 static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
932 static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
933
934 init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
935 init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
936 init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
937 init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
938 init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
939 init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
940 init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
941 init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
942 init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
943
944 init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
945 init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
946 init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
947 init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
948 init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
949 init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
950 init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
951 init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
952 init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
953 }
954 }
955
956
957 void _mesa_free_eval_data( struct gl_context *ctx )
958 {
959 /* Free evaluator data */
960 free(ctx->EvalMap.Map1Vertex3.Points);
961 free(ctx->EvalMap.Map1Vertex4.Points);
962 free(ctx->EvalMap.Map1Index.Points);
963 free(ctx->EvalMap.Map1Color4.Points);
964 free(ctx->EvalMap.Map1Normal.Points);
965 free(ctx->EvalMap.Map1Texture1.Points);
966 free(ctx->EvalMap.Map1Texture2.Points);
967 free(ctx->EvalMap.Map1Texture3.Points);
968 free(ctx->EvalMap.Map1Texture4.Points);
969
970 free(ctx->EvalMap.Map2Vertex3.Points);
971 free(ctx->EvalMap.Map2Vertex4.Points);
972 free(ctx->EvalMap.Map2Index.Points);
973 free(ctx->EvalMap.Map2Color4.Points);
974 free(ctx->EvalMap.Map2Normal.Points);
975 free(ctx->EvalMap.Map2Texture1.Points);
976 free(ctx->EvalMap.Map2Texture2.Points);
977 free(ctx->EvalMap.Map2Texture3.Points);
978 free(ctx->EvalMap.Map2Texture4.Points);
979 }