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