Move the transform and lighting code to two new directories
[mesa.git] / src / mesa / main / eval.c
1 /* $Id: eval.c,v 1.15 2000/11/16 21:05:35 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 /*
29 * eval.c was written by
30 * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
31 * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
32 *
33 * My original implementation of evaluators was simplistic and didn't
34 * compute surface normal vectors properly. Bernd and Volker applied
35 * used more sophisticated methods to get better results.
36 *
37 * Thanks guys!
38 */
39
40
41 #ifdef PC_HEADER
42 #include "all.h"
43 #else
44 #include "glheader.h"
45 #include "colormac.h"
46 #include "context.h"
47 #include "eval.h"
48 #include "macros.h"
49 #include "mem.h"
50 #include "mmath.h"
51 #include "types.h"
52 #endif
53
54
55 /*
56 * Return the number of components per control point for any type of
57 * evaluator. Return 0 if bad target.
58 * See table 5.1 in the OpenGL 1.2 spec.
59 */
60 GLuint _mesa_evaluator_components( GLenum target )
61 {
62 switch (target) {
63 case GL_MAP1_VERTEX_3: return 3;
64 case GL_MAP1_VERTEX_4: return 4;
65 case GL_MAP1_INDEX: return 1;
66 case GL_MAP1_COLOR_4: return 4;
67 case GL_MAP1_NORMAL: return 3;
68 case GL_MAP1_TEXTURE_COORD_1: return 1;
69 case GL_MAP1_TEXTURE_COORD_2: return 2;
70 case GL_MAP1_TEXTURE_COORD_3: return 3;
71 case GL_MAP1_TEXTURE_COORD_4: return 4;
72 case GL_MAP2_VERTEX_3: return 3;
73 case GL_MAP2_VERTEX_4: return 4;
74 case GL_MAP2_INDEX: return 1;
75 case GL_MAP2_COLOR_4: return 4;
76 case GL_MAP2_NORMAL: return 3;
77 case GL_MAP2_TEXTURE_COORD_1: return 1;
78 case GL_MAP2_TEXTURE_COORD_2: return 2;
79 case GL_MAP2_TEXTURE_COORD_3: return 3;
80 case GL_MAP2_TEXTURE_COORD_4: return 4;
81 default: return 0;
82 }
83 }
84
85
86 /**********************************************************************/
87 /*** Copy and deallocate control points ***/
88 /**********************************************************************/
89
90
91 /*
92 * Copy 1-parametric evaluator control points from user-specified
93 * memory space to a buffer of contiguous control points.
94 * Input: see glMap1f for details
95 * Return: pointer to buffer of contiguous control points or NULL if out
96 * of memory.
97 */
98 GLfloat *gl_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
99 const GLfloat *points )
100 {
101 GLfloat *buffer, *p;
102 GLint i, k, size = _mesa_evaluator_components(target);
103
104 if (!points || size==0) {
105 return NULL;
106 }
107
108 buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
109
110 if(buffer)
111 for(i=0, p=buffer; i<uorder; i++, points+=ustride)
112 for(k=0; k<size; k++)
113 *p++ = points[k];
114
115 return buffer;
116 }
117
118
119
120 /*
121 * Same as above but convert doubles to floats.
122 */
123 GLfloat *gl_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
124 const GLdouble *points )
125 {
126 GLfloat *buffer, *p;
127 GLint i, k, size = _mesa_evaluator_components(target);
128
129 if (!points || size==0) {
130 return NULL;
131 }
132
133 buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
134
135 if(buffer)
136 for(i=0, p=buffer; i<uorder; i++, points+=ustride)
137 for(k=0; k<size; k++)
138 *p++ = (GLfloat) points[k];
139
140 return buffer;
141 }
142
143
144
145 /*
146 * Copy 2-parametric evaluator control points from user-specified
147 * memory space to a buffer of contiguous control points.
148 * Additional memory is allocated to be used by the horner and
149 * de Casteljau evaluation schemes.
150 *
151 * Input: see glMap2f for details
152 * Return: pointer to buffer of contiguous control points or NULL if out
153 * of memory.
154 */
155 GLfloat *gl_copy_map_points2f( GLenum target,
156 GLint ustride, GLint uorder,
157 GLint vstride, GLint vorder,
158 const GLfloat *points )
159 {
160 GLfloat *buffer, *p;
161 GLint i, j, k, size, dsize, hsize;
162 GLint uinc;
163
164 size = _mesa_evaluator_components(target);
165
166 if (!points || size==0) {
167 return NULL;
168 }
169
170 /* max(uorder, vorder) additional points are used in */
171 /* horner evaluation and uorder*vorder additional */
172 /* values are needed for de Casteljau */
173 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
174 hsize = (uorder > vorder ? uorder : vorder)*size;
175
176 if(hsize>dsize)
177 buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
178 else
179 buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
180
181 /* compute the increment value for the u-loop */
182 uinc = ustride - vorder*vstride;
183
184 if (buffer)
185 for (i=0, p=buffer; i<uorder; i++, points += uinc)
186 for (j=0; j<vorder; j++, points += vstride)
187 for (k=0; k<size; k++)
188 *p++ = points[k];
189
190 return buffer;
191 }
192
193
194
195 /*
196 * Same as above but convert doubles to floats.
197 */
198 GLfloat *gl_copy_map_points2d(GLenum target,
199 GLint ustride, GLint uorder,
200 GLint vstride, GLint vorder,
201 const GLdouble *points )
202 {
203 GLfloat *buffer, *p;
204 GLint i, j, k, size, hsize, dsize;
205 GLint uinc;
206
207 size = _mesa_evaluator_components(target);
208
209 if (!points || size==0) {
210 return NULL;
211 }
212
213 /* max(uorder, vorder) additional points are used in */
214 /* horner evaluation and uorder*vorder additional */
215 /* values are needed for de Casteljau */
216 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
217 hsize = (uorder > vorder ? uorder : vorder)*size;
218
219 if(hsize>dsize)
220 buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
221 else
222 buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
223
224 /* compute the increment value for the u-loop */
225 uinc = ustride - vorder*vstride;
226
227 if (buffer)
228 for (i=0, p=buffer; i<uorder; i++, points += uinc)
229 for (j=0; j<vorder; j++, points += vstride)
230 for (k=0; k<size; k++)
231 *p++ = (GLfloat) points[k];
232
233 return buffer;
234 }
235
236
237 #if 00
238 /*
239 * This function is called by the display list deallocator function to
240 * specify that a given set of control points are no longer needed.
241 */
242 void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
243 {
244 struct gl_1d_map *map1 = NULL;
245 struct gl_2d_map *map2 = NULL;
246
247 switch (target) {
248 case GL_MAP1_VERTEX_3:
249 map1 = &ctx->EvalMap.Map1Vertex3;
250 break;
251 case GL_MAP1_VERTEX_4:
252 map1 = &ctx->EvalMap.Map1Vertex4;
253 break;
254 case GL_MAP1_INDEX:
255 map1 = &ctx->EvalMap.Map1Index;
256 break;
257 case GL_MAP1_COLOR_4:
258 map1 = &ctx->EvalMap.Map1Color4;
259 break;
260 case GL_MAP1_NORMAL:
261 map1 = &ctx->EvalMap.Map1Normal;
262 break;
263 case GL_MAP1_TEXTURE_COORD_1:
264 map1 = &ctx->EvalMap.Map1Texture1;
265 break;
266 case GL_MAP1_TEXTURE_COORD_2:
267 map1 = &ctx->EvalMap.Map1Texture2;
268 break;
269 case GL_MAP1_TEXTURE_COORD_3:
270 map1 = &ctx->EvalMap.Map1Texture3;
271 break;
272 case GL_MAP1_TEXTURE_COORD_4:
273 map1 = &ctx->EvalMap.Map1Texture4;
274 break;
275 case GL_MAP2_VERTEX_3:
276 map2 = &ctx->EvalMap.Map2Vertex3;
277 break;
278 case GL_MAP2_VERTEX_4:
279 map2 = &ctx->EvalMap.Map2Vertex4;
280 break;
281 case GL_MAP2_INDEX:
282 map2 = &ctx->EvalMap.Map2Index;
283 break;
284 case GL_MAP2_COLOR_4:
285 map2 = &ctx->EvalMap.Map2Color4;
286 break;
287 case GL_MAP2_NORMAL:
288 map2 = &ctx->EvalMap.Map2Normal;
289 break;
290 case GL_MAP2_TEXTURE_COORD_1:
291 map2 = &ctx->EvalMap.Map2Texture1;
292 break;
293 case GL_MAP2_TEXTURE_COORD_2:
294 map2 = &ctx->EvalMap.Map2Texture2;
295 break;
296 case GL_MAP2_TEXTURE_COORD_3:
297 map2 = &ctx->EvalMap.Map2Texture3;
298 break;
299 case GL_MAP2_TEXTURE_COORD_4:
300 map2 = &ctx->EvalMap.Map2Texture4;
301 break;
302 default:
303 gl_error( ctx, GL_INVALID_ENUM, "gl_free_control_points" );
304 return;
305 }
306
307 if (map1) {
308 if (data==map1->Points) {
309 /* The control points in the display list are currently */
310 /* being used so we can mark them as discard-able. */
311 map1->Retain = GL_FALSE;
312 }
313 else {
314 /* The control points in the display list are not currently */
315 /* being used. */
316 FREE( data );
317 }
318 }
319 if (map2) {
320 if (data==map2->Points) {
321 /* The control points in the display list are currently */
322 /* being used so we can mark them as discard-able. */
323 map2->Retain = GL_FALSE;
324 }
325 else {
326 /* The control points in the display list are not currently */
327 /* being used. */
328 FREE( data );
329 }
330 }
331
332 }
333 #endif
334
335
336
337 /**********************************************************************/
338 /*** API entry points ***/
339 /**********************************************************************/
340
341
342 /*
343 * This does the work of glMap1[fd].
344 */
345 static void
346 map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
347 GLint uorder, const GLvoid *points, GLenum type )
348 {
349 GET_CURRENT_CONTEXT(ctx);
350 GLint k;
351 GLfloat *pnts;
352
353 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap1");
354
355 assert(type == GL_FLOAT || type == GL_DOUBLE);
356
357 if (u1 == u2) {
358 gl_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
359 return;
360 }
361 if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
362 gl_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
363 return;
364 }
365 if (!points) {
366 gl_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
367 return;
368 }
369
370 k = _mesa_evaluator_components( target );
371 if (k == 0) {
372 gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
373 }
374
375 if (ustride < k) {
376 gl_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
377 return;
378 }
379
380 /* make copy of the control points */
381 if (type == GL_FLOAT)
382 pnts = gl_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
383 else
384 pnts = gl_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
385
386 switch (target) {
387 case GL_MAP1_VERTEX_3:
388 ctx->EvalMap.Map1Vertex3.Order = uorder;
389 ctx->EvalMap.Map1Vertex3.u1 = u1;
390 ctx->EvalMap.Map1Vertex3.u2 = u2;
391 ctx->EvalMap.Map1Vertex3.du = 1.0 / (u2 - u1);
392 if (ctx->EvalMap.Map1Vertex3.Points)
393 FREE( ctx->EvalMap.Map1Vertex3.Points );
394 ctx->EvalMap.Map1Vertex3.Points = pnts;
395 break;
396 case GL_MAP1_VERTEX_4:
397 ctx->EvalMap.Map1Vertex4.Order = uorder;
398 ctx->EvalMap.Map1Vertex4.u1 = u1;
399 ctx->EvalMap.Map1Vertex4.u2 = u2;
400 ctx->EvalMap.Map1Vertex4.du = 1.0 / (u2 - u1);
401 if (ctx->EvalMap.Map1Vertex4.Points)
402 FREE( ctx->EvalMap.Map1Vertex4.Points );
403 ctx->EvalMap.Map1Vertex4.Points = pnts;
404 break;
405 case GL_MAP1_INDEX:
406 ctx->EvalMap.Map1Index.Order = uorder;
407 ctx->EvalMap.Map1Index.u1 = u1;
408 ctx->EvalMap.Map1Index.u2 = u2;
409 ctx->EvalMap.Map1Index.du = 1.0 / (u2 - u1);
410 if (ctx->EvalMap.Map1Index.Points)
411 FREE( ctx->EvalMap.Map1Index.Points );
412 ctx->EvalMap.Map1Index.Points = pnts;
413 break;
414 case GL_MAP1_COLOR_4:
415 ctx->EvalMap.Map1Color4.Order = uorder;
416 ctx->EvalMap.Map1Color4.u1 = u1;
417 ctx->EvalMap.Map1Color4.u2 = u2;
418 ctx->EvalMap.Map1Color4.du = 1.0 / (u2 - u1);
419 if (ctx->EvalMap.Map1Color4.Points)
420 FREE( ctx->EvalMap.Map1Color4.Points );
421 ctx->EvalMap.Map1Color4.Points = pnts;
422 break;
423 case GL_MAP1_NORMAL:
424 ctx->EvalMap.Map1Normal.Order = uorder;
425 ctx->EvalMap.Map1Normal.u1 = u1;
426 ctx->EvalMap.Map1Normal.u2 = u2;
427 ctx->EvalMap.Map1Normal.du = 1.0 / (u2 - u1);
428 if (ctx->EvalMap.Map1Normal.Points)
429 FREE( ctx->EvalMap.Map1Normal.Points );
430 ctx->EvalMap.Map1Normal.Points = pnts;
431 break;
432 case GL_MAP1_TEXTURE_COORD_1:
433 ctx->EvalMap.Map1Texture1.Order = uorder;
434 ctx->EvalMap.Map1Texture1.u1 = u1;
435 ctx->EvalMap.Map1Texture1.u2 = u2;
436 ctx->EvalMap.Map1Texture1.du = 1.0 / (u2 - u1);
437 if (ctx->EvalMap.Map1Texture1.Points)
438 FREE( ctx->EvalMap.Map1Texture1.Points );
439 ctx->EvalMap.Map1Texture1.Points = pnts;
440 break;
441 case GL_MAP1_TEXTURE_COORD_2:
442 ctx->EvalMap.Map1Texture2.Order = uorder;
443 ctx->EvalMap.Map1Texture2.u1 = u1;
444 ctx->EvalMap.Map1Texture2.u2 = u2;
445 ctx->EvalMap.Map1Texture2.du = 1.0 / (u2 - u1);
446 if (ctx->EvalMap.Map1Texture2.Points)
447 FREE( ctx->EvalMap.Map1Texture2.Points );
448 ctx->EvalMap.Map1Texture2.Points = pnts;
449 break;
450 case GL_MAP1_TEXTURE_COORD_3:
451 ctx->EvalMap.Map1Texture3.Order = uorder;
452 ctx->EvalMap.Map1Texture3.u1 = u1;
453 ctx->EvalMap.Map1Texture3.u2 = u2;
454 ctx->EvalMap.Map1Texture3.du = 1.0 / (u2 - u1);
455 if (ctx->EvalMap.Map1Texture3.Points)
456 FREE( ctx->EvalMap.Map1Texture3.Points );
457 ctx->EvalMap.Map1Texture3.Points = pnts;
458 break;
459 case GL_MAP1_TEXTURE_COORD_4:
460 ctx->EvalMap.Map1Texture4.Order = uorder;
461 ctx->EvalMap.Map1Texture4.u1 = u1;
462 ctx->EvalMap.Map1Texture4.u2 = u2;
463 ctx->EvalMap.Map1Texture4.du = 1.0 / (u2 - u1);
464 if (ctx->EvalMap.Map1Texture4.Points)
465 FREE( ctx->EvalMap.Map1Texture4.Points );
466 ctx->EvalMap.Map1Texture4.Points = pnts;
467 break;
468 default:
469 gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
470 }
471
472 ctx->NewState |= _NEW_EVAL;
473 }
474
475
476
477 void
478 _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
479 GLint order, const GLfloat *points )
480 {
481 map1(target, u1, u2, stride, order, points, GL_FLOAT);
482 }
483
484
485 void
486 _mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
487 GLint order, const GLdouble *points )
488 {
489 map1(target, u1, u2, stride, order, points, GL_DOUBLE);
490 }
491
492
493 static void
494 map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
495 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
496 const GLvoid *points, GLenum type )
497 {
498 GET_CURRENT_CONTEXT(ctx);
499 GLint k;
500 GLfloat *pnts;
501
502 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap2");
503
504 if (u1==u2) {
505 gl_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
506 return;
507 }
508
509 if (v1==v2) {
510 gl_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
511 return;
512 }
513
514 if (uorder<1 || uorder>MAX_EVAL_ORDER) {
515 gl_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
516 return;
517 }
518
519 if (vorder<1 || vorder>MAX_EVAL_ORDER) {
520 gl_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
521 return;
522 }
523
524 k = _mesa_evaluator_components( target );
525 if (k==0) {
526 gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
527 }
528
529 if (ustride < k) {
530 gl_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
531 return;
532 }
533 if (vstride < k) {
534 gl_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
535 return;
536 }
537
538 /* make copy of the control points */
539 if (type == GL_FLOAT)
540 pnts = gl_copy_map_points2f(target, ustride, uorder,
541 vstride, vorder, (GLfloat*) points);
542 else
543 pnts = gl_copy_map_points2d(target, ustride, uorder,
544 vstride, vorder, (GLdouble*) points);
545
546 switch (target) {
547 case GL_MAP2_VERTEX_3:
548 ctx->EvalMap.Map2Vertex3.Uorder = uorder;
549 ctx->EvalMap.Map2Vertex3.u1 = u1;
550 ctx->EvalMap.Map2Vertex3.u2 = u2;
551 ctx->EvalMap.Map2Vertex3.du = 1.0 / (u2 - u1);
552 ctx->EvalMap.Map2Vertex3.Vorder = vorder;
553 ctx->EvalMap.Map2Vertex3.v1 = v1;
554 ctx->EvalMap.Map2Vertex3.v2 = v2;
555 ctx->EvalMap.Map2Vertex3.dv = 1.0 / (v2 - v1);
556 if (ctx->EvalMap.Map2Vertex3.Points)
557 FREE( ctx->EvalMap.Map2Vertex3.Points );
558 ctx->EvalMap.Map2Vertex3.Points = pnts;
559 break;
560 case GL_MAP2_VERTEX_4:
561 ctx->EvalMap.Map2Vertex4.Uorder = uorder;
562 ctx->EvalMap.Map2Vertex4.u1 = u1;
563 ctx->EvalMap.Map2Vertex4.u2 = u2;
564 ctx->EvalMap.Map2Vertex4.du = 1.0 / (u2 - u1);
565 ctx->EvalMap.Map2Vertex4.Vorder = vorder;
566 ctx->EvalMap.Map2Vertex4.v1 = v1;
567 ctx->EvalMap.Map2Vertex4.v2 = v2;
568 ctx->EvalMap.Map2Vertex4.dv = 1.0 / (v2 - v1);
569 if (ctx->EvalMap.Map2Vertex4.Points)
570 FREE( ctx->EvalMap.Map2Vertex4.Points );
571 ctx->EvalMap.Map2Vertex4.Points = pnts;
572 break;
573 case GL_MAP2_INDEX:
574 ctx->EvalMap.Map2Index.Uorder = uorder;
575 ctx->EvalMap.Map2Index.u1 = u1;
576 ctx->EvalMap.Map2Index.u2 = u2;
577 ctx->EvalMap.Map2Index.du = 1.0 / (u2 - u1);
578 ctx->EvalMap.Map2Index.Vorder = vorder;
579 ctx->EvalMap.Map2Index.v1 = v1;
580 ctx->EvalMap.Map2Index.v2 = v2;
581 ctx->EvalMap.Map2Index.dv = 1.0 / (v2 - v1);
582 if (ctx->EvalMap.Map2Index.Points)
583 FREE( ctx->EvalMap.Map2Index.Points );
584 ctx->EvalMap.Map2Index.Points = pnts;
585 break;
586 case GL_MAP2_COLOR_4:
587 ctx->EvalMap.Map2Color4.Uorder = uorder;
588 ctx->EvalMap.Map2Color4.u1 = u1;
589 ctx->EvalMap.Map2Color4.u2 = u2;
590 ctx->EvalMap.Map2Color4.du = 1.0 / (u2 - u1);
591 ctx->EvalMap.Map2Color4.Vorder = vorder;
592 ctx->EvalMap.Map2Color4.v1 = v1;
593 ctx->EvalMap.Map2Color4.v2 = v2;
594 ctx->EvalMap.Map2Color4.dv = 1.0 / (v2 - v1);
595 if (ctx->EvalMap.Map2Color4.Points)
596 FREE( ctx->EvalMap.Map2Color4.Points );
597 ctx->EvalMap.Map2Color4.Points = pnts;
598 break;
599 case GL_MAP2_NORMAL:
600 ctx->EvalMap.Map2Normal.Uorder = uorder;
601 ctx->EvalMap.Map2Normal.u1 = u1;
602 ctx->EvalMap.Map2Normal.u2 = u2;
603 ctx->EvalMap.Map2Normal.du = 1.0 / (u2 - u1);
604 ctx->EvalMap.Map2Normal.Vorder = vorder;
605 ctx->EvalMap.Map2Normal.v1 = v1;
606 ctx->EvalMap.Map2Normal.v2 = v2;
607 ctx->EvalMap.Map2Normal.dv = 1.0 / (v2 - v1);
608 if (ctx->EvalMap.Map2Normal.Points)
609 FREE( ctx->EvalMap.Map2Normal.Points );
610 ctx->EvalMap.Map2Normal.Points = pnts;
611 break;
612 case GL_MAP2_TEXTURE_COORD_1:
613 ctx->EvalMap.Map2Texture1.Uorder = uorder;
614 ctx->EvalMap.Map2Texture1.u1 = u1;
615 ctx->EvalMap.Map2Texture1.u2 = u2;
616 ctx->EvalMap.Map2Texture1.du = 1.0 / (u2 - u1);
617 ctx->EvalMap.Map2Texture1.Vorder = vorder;
618 ctx->EvalMap.Map2Texture1.v1 = v1;
619 ctx->EvalMap.Map2Texture1.v2 = v2;
620 ctx->EvalMap.Map2Texture1.dv = 1.0 / (v2 - v1);
621 if (ctx->EvalMap.Map2Texture1.Points)
622 FREE( ctx->EvalMap.Map2Texture1.Points );
623 ctx->EvalMap.Map2Texture1.Points = pnts;
624 break;
625 case GL_MAP2_TEXTURE_COORD_2:
626 ctx->EvalMap.Map2Texture2.Uorder = uorder;
627 ctx->EvalMap.Map2Texture2.u1 = u1;
628 ctx->EvalMap.Map2Texture2.u2 = u2;
629 ctx->EvalMap.Map2Texture2.du = 1.0 / (u2 - u1);
630 ctx->EvalMap.Map2Texture2.Vorder = vorder;
631 ctx->EvalMap.Map2Texture2.v1 = v1;
632 ctx->EvalMap.Map2Texture2.v2 = v2;
633 ctx->EvalMap.Map2Texture2.dv = 1.0 / (v2 - v1);
634 if (ctx->EvalMap.Map2Texture2.Points)
635 FREE( ctx->EvalMap.Map2Texture2.Points );
636 ctx->EvalMap.Map2Texture2.Points = pnts;
637 break;
638 case GL_MAP2_TEXTURE_COORD_3:
639 ctx->EvalMap.Map2Texture3.Uorder = uorder;
640 ctx->EvalMap.Map2Texture3.u1 = u1;
641 ctx->EvalMap.Map2Texture3.u2 = u2;
642 ctx->EvalMap.Map2Texture3.du = 1.0 / (u2 - u1);
643 ctx->EvalMap.Map2Texture3.Vorder = vorder;
644 ctx->EvalMap.Map2Texture3.v1 = v1;
645 ctx->EvalMap.Map2Texture3.v2 = v2;
646 ctx->EvalMap.Map2Texture3.dv = 1.0 / (v2 - v1);
647 if (ctx->EvalMap.Map2Texture3.Points)
648 FREE( ctx->EvalMap.Map2Texture3.Points );
649 ctx->EvalMap.Map2Texture3.Points = pnts;
650 break;
651 case GL_MAP2_TEXTURE_COORD_4:
652 ctx->EvalMap.Map2Texture4.Uorder = uorder;
653 ctx->EvalMap.Map2Texture4.u1 = u1;
654 ctx->EvalMap.Map2Texture4.u2 = u2;
655 ctx->EvalMap.Map2Texture4.du = 1.0 / (u2 - u1);
656 ctx->EvalMap.Map2Texture4.Vorder = vorder;
657 ctx->EvalMap.Map2Texture4.v1 = v1;
658 ctx->EvalMap.Map2Texture4.v2 = v2;
659 ctx->EvalMap.Map2Texture4.dv = 1.0 / (v2 - v1);
660 if (ctx->EvalMap.Map2Texture4.Points)
661 FREE( ctx->EvalMap.Map2Texture4.Points );
662 ctx->EvalMap.Map2Texture4.Points = pnts;
663 break;
664 default:
665 gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
666 }
667
668 ctx->NewState |= _NEW_EVAL;
669 }
670
671
672 void
673 _mesa_Map2f( GLenum target,
674 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
675 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
676 const GLfloat *points)
677 {
678 map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
679 points, GL_FLOAT);
680 }
681
682
683 void
684 _mesa_Map2d( GLenum target,
685 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
686 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
687 const GLdouble *points )
688 {
689 map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
690 points, GL_DOUBLE);
691 }
692
693
694
695 void
696 _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
697 {
698 GET_CURRENT_CONTEXT(ctx);
699 GLint i, n;
700 GLfloat *data;
701
702 switch (query) {
703 case GL_COEFF:
704 switch (target) {
705 case GL_MAP1_COLOR_4:
706 data = ctx->EvalMap.Map1Color4.Points;
707 n = ctx->EvalMap.Map1Color4.Order * 4;
708 break;
709 case GL_MAP1_INDEX:
710 data = ctx->EvalMap.Map1Index.Points;
711 n = ctx->EvalMap.Map1Index.Order;
712 break;
713 case GL_MAP1_NORMAL:
714 data = ctx->EvalMap.Map1Normal.Points;
715 n = ctx->EvalMap.Map1Normal.Order * 3;
716 break;
717 case GL_MAP1_TEXTURE_COORD_1:
718 data = ctx->EvalMap.Map1Texture1.Points;
719 n = ctx->EvalMap.Map1Texture1.Order * 1;
720 break;
721 case GL_MAP1_TEXTURE_COORD_2:
722 data = ctx->EvalMap.Map1Texture2.Points;
723 n = ctx->EvalMap.Map1Texture2.Order * 2;
724 break;
725 case GL_MAP1_TEXTURE_COORD_3:
726 data = ctx->EvalMap.Map1Texture3.Points;
727 n = ctx->EvalMap.Map1Texture3.Order * 3;
728 break;
729 case GL_MAP1_TEXTURE_COORD_4:
730 data = ctx->EvalMap.Map1Texture4.Points;
731 n = ctx->EvalMap.Map1Texture4.Order * 4;
732 break;
733 case GL_MAP1_VERTEX_3:
734 data = ctx->EvalMap.Map1Vertex3.Points;
735 n = ctx->EvalMap.Map1Vertex3.Order * 3;
736 break;
737 case GL_MAP1_VERTEX_4:
738 data = ctx->EvalMap.Map1Vertex4.Points;
739 n = ctx->EvalMap.Map1Vertex4.Order * 4;
740 break;
741 case GL_MAP2_COLOR_4:
742 data = ctx->EvalMap.Map2Color4.Points;
743 n = ctx->EvalMap.Map2Color4.Uorder
744 * ctx->EvalMap.Map2Color4.Vorder * 4;
745 break;
746 case GL_MAP2_INDEX:
747 data = ctx->EvalMap.Map2Index.Points;
748 n = ctx->EvalMap.Map2Index.Uorder
749 * ctx->EvalMap.Map2Index.Vorder;
750 break;
751 case GL_MAP2_NORMAL:
752 data = ctx->EvalMap.Map2Normal.Points;
753 n = ctx->EvalMap.Map2Normal.Uorder
754 * ctx->EvalMap.Map2Normal.Vorder * 3;
755 break;
756 case GL_MAP2_TEXTURE_COORD_1:
757 data = ctx->EvalMap.Map2Texture1.Points;
758 n = ctx->EvalMap.Map2Texture1.Uorder
759 * ctx->EvalMap.Map2Texture1.Vorder * 1;
760 break;
761 case GL_MAP2_TEXTURE_COORD_2:
762 data = ctx->EvalMap.Map2Texture2.Points;
763 n = ctx->EvalMap.Map2Texture2.Uorder
764 * ctx->EvalMap.Map2Texture2.Vorder * 2;
765 break;
766 case GL_MAP2_TEXTURE_COORD_3:
767 data = ctx->EvalMap.Map2Texture3.Points;
768 n = ctx->EvalMap.Map2Texture3.Uorder
769 * ctx->EvalMap.Map2Texture3.Vorder * 3;
770 break;
771 case GL_MAP2_TEXTURE_COORD_4:
772 data = ctx->EvalMap.Map2Texture4.Points;
773 n = ctx->EvalMap.Map2Texture4.Uorder
774 * ctx->EvalMap.Map2Texture4.Vorder * 4;
775 break;
776 case GL_MAP2_VERTEX_3:
777 data = ctx->EvalMap.Map2Vertex3.Points;
778 n = ctx->EvalMap.Map2Vertex3.Uorder
779 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
780 break;
781 case GL_MAP2_VERTEX_4:
782 data = ctx->EvalMap.Map2Vertex4.Points;
783 n = ctx->EvalMap.Map2Vertex4.Uorder
784 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
785 break;
786 default:
787 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
788 return;
789 }
790 if (data) {
791 for (i=0;i<n;i++) {
792 v[i] = data[i];
793 }
794 }
795 break;
796 case GL_ORDER:
797 switch (target) {
798 case GL_MAP1_COLOR_4:
799 *v = ctx->EvalMap.Map1Color4.Order;
800 break;
801 case GL_MAP1_INDEX:
802 *v = ctx->EvalMap.Map1Index.Order;
803 break;
804 case GL_MAP1_NORMAL:
805 *v = ctx->EvalMap.Map1Normal.Order;
806 break;
807 case GL_MAP1_TEXTURE_COORD_1:
808 *v = ctx->EvalMap.Map1Texture1.Order;
809 break;
810 case GL_MAP1_TEXTURE_COORD_2:
811 *v = ctx->EvalMap.Map1Texture2.Order;
812 break;
813 case GL_MAP1_TEXTURE_COORD_3:
814 *v = ctx->EvalMap.Map1Texture3.Order;
815 break;
816 case GL_MAP1_TEXTURE_COORD_4:
817 *v = ctx->EvalMap.Map1Texture4.Order;
818 break;
819 case GL_MAP1_VERTEX_3:
820 *v = ctx->EvalMap.Map1Vertex3.Order;
821 break;
822 case GL_MAP1_VERTEX_4:
823 *v = ctx->EvalMap.Map1Vertex4.Order;
824 break;
825 case GL_MAP2_COLOR_4:
826 v[0] = ctx->EvalMap.Map2Color4.Uorder;
827 v[1] = ctx->EvalMap.Map2Color4.Vorder;
828 break;
829 case GL_MAP2_INDEX:
830 v[0] = ctx->EvalMap.Map2Index.Uorder;
831 v[1] = ctx->EvalMap.Map2Index.Vorder;
832 break;
833 case GL_MAP2_NORMAL:
834 v[0] = ctx->EvalMap.Map2Normal.Uorder;
835 v[1] = ctx->EvalMap.Map2Normal.Vorder;
836 break;
837 case GL_MAP2_TEXTURE_COORD_1:
838 v[0] = ctx->EvalMap.Map2Texture1.Uorder;
839 v[1] = ctx->EvalMap.Map2Texture1.Vorder;
840 break;
841 case GL_MAP2_TEXTURE_COORD_2:
842 v[0] = ctx->EvalMap.Map2Texture2.Uorder;
843 v[1] = ctx->EvalMap.Map2Texture2.Vorder;
844 break;
845 case GL_MAP2_TEXTURE_COORD_3:
846 v[0] = ctx->EvalMap.Map2Texture3.Uorder;
847 v[1] = ctx->EvalMap.Map2Texture3.Vorder;
848 break;
849 case GL_MAP2_TEXTURE_COORD_4:
850 v[0] = ctx->EvalMap.Map2Texture4.Uorder;
851 v[1] = ctx->EvalMap.Map2Texture4.Vorder;
852 break;
853 case GL_MAP2_VERTEX_3:
854 v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
855 v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
856 break;
857 case GL_MAP2_VERTEX_4:
858 v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
859 v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
860 break;
861 default:
862 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
863 return;
864 }
865 break;
866 case GL_DOMAIN:
867 switch (target) {
868 case GL_MAP1_COLOR_4:
869 v[0] = ctx->EvalMap.Map1Color4.u1;
870 v[1] = ctx->EvalMap.Map1Color4.u2;
871 break;
872 case GL_MAP1_INDEX:
873 v[0] = ctx->EvalMap.Map1Index.u1;
874 v[1] = ctx->EvalMap.Map1Index.u2;
875 break;
876 case GL_MAP1_NORMAL:
877 v[0] = ctx->EvalMap.Map1Normal.u1;
878 v[1] = ctx->EvalMap.Map1Normal.u2;
879 break;
880 case GL_MAP1_TEXTURE_COORD_1:
881 v[0] = ctx->EvalMap.Map1Texture1.u1;
882 v[1] = ctx->EvalMap.Map1Texture1.u2;
883 break;
884 case GL_MAP1_TEXTURE_COORD_2:
885 v[0] = ctx->EvalMap.Map1Texture2.u1;
886 v[1] = ctx->EvalMap.Map1Texture2.u2;
887 break;
888 case GL_MAP1_TEXTURE_COORD_3:
889 v[0] = ctx->EvalMap.Map1Texture3.u1;
890 v[1] = ctx->EvalMap.Map1Texture3.u2;
891 break;
892 case GL_MAP1_TEXTURE_COORD_4:
893 v[0] = ctx->EvalMap.Map1Texture4.u1;
894 v[1] = ctx->EvalMap.Map1Texture4.u2;
895 break;
896 case GL_MAP1_VERTEX_3:
897 v[0] = ctx->EvalMap.Map1Vertex3.u1;
898 v[1] = ctx->EvalMap.Map1Vertex3.u2;
899 break;
900 case GL_MAP1_VERTEX_4:
901 v[0] = ctx->EvalMap.Map1Vertex4.u1;
902 v[1] = ctx->EvalMap.Map1Vertex4.u2;
903 break;
904 case GL_MAP2_COLOR_4:
905 v[0] = ctx->EvalMap.Map2Color4.u1;
906 v[1] = ctx->EvalMap.Map2Color4.u2;
907 v[2] = ctx->EvalMap.Map2Color4.v1;
908 v[3] = ctx->EvalMap.Map2Color4.v2;
909 break;
910 case GL_MAP2_INDEX:
911 v[0] = ctx->EvalMap.Map2Index.u1;
912 v[1] = ctx->EvalMap.Map2Index.u2;
913 v[2] = ctx->EvalMap.Map2Index.v1;
914 v[3] = ctx->EvalMap.Map2Index.v2;
915 break;
916 case GL_MAP2_NORMAL:
917 v[0] = ctx->EvalMap.Map2Normal.u1;
918 v[1] = ctx->EvalMap.Map2Normal.u2;
919 v[2] = ctx->EvalMap.Map2Normal.v1;
920 v[3] = ctx->EvalMap.Map2Normal.v2;
921 break;
922 case GL_MAP2_TEXTURE_COORD_1:
923 v[0] = ctx->EvalMap.Map2Texture1.u1;
924 v[1] = ctx->EvalMap.Map2Texture1.u2;
925 v[2] = ctx->EvalMap.Map2Texture1.v1;
926 v[3] = ctx->EvalMap.Map2Texture1.v2;
927 break;
928 case GL_MAP2_TEXTURE_COORD_2:
929 v[0] = ctx->EvalMap.Map2Texture2.u1;
930 v[1] = ctx->EvalMap.Map2Texture2.u2;
931 v[2] = ctx->EvalMap.Map2Texture2.v1;
932 v[3] = ctx->EvalMap.Map2Texture2.v2;
933 break;
934 case GL_MAP2_TEXTURE_COORD_3:
935 v[0] = ctx->EvalMap.Map2Texture3.u1;
936 v[1] = ctx->EvalMap.Map2Texture3.u2;
937 v[2] = ctx->EvalMap.Map2Texture3.v1;
938 v[3] = ctx->EvalMap.Map2Texture3.v2;
939 break;
940 case GL_MAP2_TEXTURE_COORD_4:
941 v[0] = ctx->EvalMap.Map2Texture4.u1;
942 v[1] = ctx->EvalMap.Map2Texture4.u2;
943 v[2] = ctx->EvalMap.Map2Texture4.v1;
944 v[3] = ctx->EvalMap.Map2Texture4.v2;
945 break;
946 case GL_MAP2_VERTEX_3:
947 v[0] = ctx->EvalMap.Map2Vertex3.u1;
948 v[1] = ctx->EvalMap.Map2Vertex3.u2;
949 v[2] = ctx->EvalMap.Map2Vertex3.v1;
950 v[3] = ctx->EvalMap.Map2Vertex3.v2;
951 break;
952 case GL_MAP2_VERTEX_4:
953 v[0] = ctx->EvalMap.Map2Vertex4.u1;
954 v[1] = ctx->EvalMap.Map2Vertex4.u2;
955 v[2] = ctx->EvalMap.Map2Vertex4.v1;
956 v[3] = ctx->EvalMap.Map2Vertex4.v2;
957 break;
958 default:
959 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
960 }
961 break;
962 default:
963 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
964 }
965 }
966
967
968 void
969 _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
970 {
971 GET_CURRENT_CONTEXT(ctx);
972 GLint i, n;
973 GLfloat *data;
974
975 switch (query) {
976 case GL_COEFF:
977 switch (target) {
978 case GL_MAP1_COLOR_4:
979 data = ctx->EvalMap.Map1Color4.Points;
980 n = ctx->EvalMap.Map1Color4.Order * 4;
981 break;
982 case GL_MAP1_INDEX:
983 data = ctx->EvalMap.Map1Index.Points;
984 n = ctx->EvalMap.Map1Index.Order;
985 break;
986 case GL_MAP1_NORMAL:
987 data = ctx->EvalMap.Map1Normal.Points;
988 n = ctx->EvalMap.Map1Normal.Order * 3;
989 break;
990 case GL_MAP1_TEXTURE_COORD_1:
991 data = ctx->EvalMap.Map1Texture1.Points;
992 n = ctx->EvalMap.Map1Texture1.Order * 1;
993 break;
994 case GL_MAP1_TEXTURE_COORD_2:
995 data = ctx->EvalMap.Map1Texture2.Points;
996 n = ctx->EvalMap.Map1Texture2.Order * 2;
997 break;
998 case GL_MAP1_TEXTURE_COORD_3:
999 data = ctx->EvalMap.Map1Texture3.Points;
1000 n = ctx->EvalMap.Map1Texture3.Order * 3;
1001 break;
1002 case GL_MAP1_TEXTURE_COORD_4:
1003 data = ctx->EvalMap.Map1Texture4.Points;
1004 n = ctx->EvalMap.Map1Texture4.Order * 4;
1005 break;
1006 case GL_MAP1_VERTEX_3:
1007 data = ctx->EvalMap.Map1Vertex3.Points;
1008 n = ctx->EvalMap.Map1Vertex3.Order * 3;
1009 break;
1010 case GL_MAP1_VERTEX_4:
1011 data = ctx->EvalMap.Map1Vertex4.Points;
1012 n = ctx->EvalMap.Map1Vertex4.Order * 4;
1013 break;
1014 case GL_MAP2_COLOR_4:
1015 data = ctx->EvalMap.Map2Color4.Points;
1016 n = ctx->EvalMap.Map2Color4.Uorder
1017 * ctx->EvalMap.Map2Color4.Vorder * 4;
1018 break;
1019 case GL_MAP2_INDEX:
1020 data = ctx->EvalMap.Map2Index.Points;
1021 n = ctx->EvalMap.Map2Index.Uorder
1022 * ctx->EvalMap.Map2Index.Vorder;
1023 break;
1024 case GL_MAP2_NORMAL:
1025 data = ctx->EvalMap.Map2Normal.Points;
1026 n = ctx->EvalMap.Map2Normal.Uorder
1027 * ctx->EvalMap.Map2Normal.Vorder * 3;
1028 break;
1029 case GL_MAP2_TEXTURE_COORD_1:
1030 data = ctx->EvalMap.Map2Texture1.Points;
1031 n = ctx->EvalMap.Map2Texture1.Uorder
1032 * ctx->EvalMap.Map2Texture1.Vorder * 1;
1033 break;
1034 case GL_MAP2_TEXTURE_COORD_2:
1035 data = ctx->EvalMap.Map2Texture2.Points;
1036 n = ctx->EvalMap.Map2Texture2.Uorder
1037 * ctx->EvalMap.Map2Texture2.Vorder * 2;
1038 break;
1039 case GL_MAP2_TEXTURE_COORD_3:
1040 data = ctx->EvalMap.Map2Texture3.Points;
1041 n = ctx->EvalMap.Map2Texture3.Uorder
1042 * ctx->EvalMap.Map2Texture3.Vorder * 3;
1043 break;
1044 case GL_MAP2_TEXTURE_COORD_4:
1045 data = ctx->EvalMap.Map2Texture4.Points;
1046 n = ctx->EvalMap.Map2Texture4.Uorder
1047 * ctx->EvalMap.Map2Texture4.Vorder * 4;
1048 break;
1049 case GL_MAP2_VERTEX_3:
1050 data = ctx->EvalMap.Map2Vertex3.Points;
1051 n = ctx->EvalMap.Map2Vertex3.Uorder
1052 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
1053 break;
1054 case GL_MAP2_VERTEX_4:
1055 data = ctx->EvalMap.Map2Vertex4.Points;
1056 n = ctx->EvalMap.Map2Vertex4.Uorder
1057 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
1058 break;
1059 default:
1060 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1061 return;
1062 }
1063 if (data) {
1064 for (i=0;i<n;i++) {
1065 v[i] = data[i];
1066 }
1067 }
1068 break;
1069 case GL_ORDER:
1070 switch (target) {
1071 case GL_MAP1_COLOR_4:
1072 *v = ctx->EvalMap.Map1Color4.Order;
1073 break;
1074 case GL_MAP1_INDEX:
1075 *v = ctx->EvalMap.Map1Index.Order;
1076 break;
1077 case GL_MAP1_NORMAL:
1078 *v = ctx->EvalMap.Map1Normal.Order;
1079 break;
1080 case GL_MAP1_TEXTURE_COORD_1:
1081 *v = ctx->EvalMap.Map1Texture1.Order;
1082 break;
1083 case GL_MAP1_TEXTURE_COORD_2:
1084 *v = ctx->EvalMap.Map1Texture2.Order;
1085 break;
1086 case GL_MAP1_TEXTURE_COORD_3:
1087 *v = ctx->EvalMap.Map1Texture3.Order;
1088 break;
1089 case GL_MAP1_TEXTURE_COORD_4:
1090 *v = ctx->EvalMap.Map1Texture4.Order;
1091 break;
1092 case GL_MAP1_VERTEX_3:
1093 *v = ctx->EvalMap.Map1Vertex3.Order;
1094 break;
1095 case GL_MAP1_VERTEX_4:
1096 *v = ctx->EvalMap.Map1Vertex4.Order;
1097 break;
1098 case GL_MAP2_COLOR_4:
1099 v[0] = ctx->EvalMap.Map2Color4.Uorder;
1100 v[1] = ctx->EvalMap.Map2Color4.Vorder;
1101 break;
1102 case GL_MAP2_INDEX:
1103 v[0] = ctx->EvalMap.Map2Index.Uorder;
1104 v[1] = ctx->EvalMap.Map2Index.Vorder;
1105 break;
1106 case GL_MAP2_NORMAL:
1107 v[0] = ctx->EvalMap.Map2Normal.Uorder;
1108 v[1] = ctx->EvalMap.Map2Normal.Vorder;
1109 break;
1110 case GL_MAP2_TEXTURE_COORD_1:
1111 v[0] = ctx->EvalMap.Map2Texture1.Uorder;
1112 v[1] = ctx->EvalMap.Map2Texture1.Vorder;
1113 break;
1114 case GL_MAP2_TEXTURE_COORD_2:
1115 v[0] = ctx->EvalMap.Map2Texture2.Uorder;
1116 v[1] = ctx->EvalMap.Map2Texture2.Vorder;
1117 break;
1118 case GL_MAP2_TEXTURE_COORD_3:
1119 v[0] = ctx->EvalMap.Map2Texture3.Uorder;
1120 v[1] = ctx->EvalMap.Map2Texture3.Vorder;
1121 break;
1122 case GL_MAP2_TEXTURE_COORD_4:
1123 v[0] = ctx->EvalMap.Map2Texture4.Uorder;
1124 v[1] = ctx->EvalMap.Map2Texture4.Vorder;
1125 break;
1126 case GL_MAP2_VERTEX_3:
1127 v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
1128 v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
1129 break;
1130 case GL_MAP2_VERTEX_4:
1131 v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
1132 v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
1133 break;
1134 default:
1135 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1136 return;
1137 }
1138 break;
1139 case GL_DOMAIN:
1140 switch (target) {
1141 case GL_MAP1_COLOR_4:
1142 v[0] = ctx->EvalMap.Map1Color4.u1;
1143 v[1] = ctx->EvalMap.Map1Color4.u2;
1144 break;
1145 case GL_MAP1_INDEX:
1146 v[0] = ctx->EvalMap.Map1Index.u1;
1147 v[1] = ctx->EvalMap.Map1Index.u2;
1148 break;
1149 case GL_MAP1_NORMAL:
1150 v[0] = ctx->EvalMap.Map1Normal.u1;
1151 v[1] = ctx->EvalMap.Map1Normal.u2;
1152 break;
1153 case GL_MAP1_TEXTURE_COORD_1:
1154 v[0] = ctx->EvalMap.Map1Texture1.u1;
1155 v[1] = ctx->EvalMap.Map1Texture1.u2;
1156 break;
1157 case GL_MAP1_TEXTURE_COORD_2:
1158 v[0] = ctx->EvalMap.Map1Texture2.u1;
1159 v[1] = ctx->EvalMap.Map1Texture2.u2;
1160 break;
1161 case GL_MAP1_TEXTURE_COORD_3:
1162 v[0] = ctx->EvalMap.Map1Texture3.u1;
1163 v[1] = ctx->EvalMap.Map1Texture3.u2;
1164 break;
1165 case GL_MAP1_TEXTURE_COORD_4:
1166 v[0] = ctx->EvalMap.Map1Texture4.u1;
1167 v[1] = ctx->EvalMap.Map1Texture4.u2;
1168 break;
1169 case GL_MAP1_VERTEX_3:
1170 v[0] = ctx->EvalMap.Map1Vertex3.u1;
1171 v[1] = ctx->EvalMap.Map1Vertex3.u2;
1172 break;
1173 case GL_MAP1_VERTEX_4:
1174 v[0] = ctx->EvalMap.Map1Vertex4.u1;
1175 v[1] = ctx->EvalMap.Map1Vertex4.u2;
1176 break;
1177 case GL_MAP2_COLOR_4:
1178 v[0] = ctx->EvalMap.Map2Color4.u1;
1179 v[1] = ctx->EvalMap.Map2Color4.u2;
1180 v[2] = ctx->EvalMap.Map2Color4.v1;
1181 v[3] = ctx->EvalMap.Map2Color4.v2;
1182 break;
1183 case GL_MAP2_INDEX:
1184 v[0] = ctx->EvalMap.Map2Index.u1;
1185 v[1] = ctx->EvalMap.Map2Index.u2;
1186 v[2] = ctx->EvalMap.Map2Index.v1;
1187 v[3] = ctx->EvalMap.Map2Index.v2;
1188 break;
1189 case GL_MAP2_NORMAL:
1190 v[0] = ctx->EvalMap.Map2Normal.u1;
1191 v[1] = ctx->EvalMap.Map2Normal.u2;
1192 v[2] = ctx->EvalMap.Map2Normal.v1;
1193 v[3] = ctx->EvalMap.Map2Normal.v2;
1194 break;
1195 case GL_MAP2_TEXTURE_COORD_1:
1196 v[0] = ctx->EvalMap.Map2Texture1.u1;
1197 v[1] = ctx->EvalMap.Map2Texture1.u2;
1198 v[2] = ctx->EvalMap.Map2Texture1.v1;
1199 v[3] = ctx->EvalMap.Map2Texture1.v2;
1200 break;
1201 case GL_MAP2_TEXTURE_COORD_2:
1202 v[0] = ctx->EvalMap.Map2Texture2.u1;
1203 v[1] = ctx->EvalMap.Map2Texture2.u2;
1204 v[2] = ctx->EvalMap.Map2Texture2.v1;
1205 v[3] = ctx->EvalMap.Map2Texture2.v2;
1206 break;
1207 case GL_MAP2_TEXTURE_COORD_3:
1208 v[0] = ctx->EvalMap.Map2Texture3.u1;
1209 v[1] = ctx->EvalMap.Map2Texture3.u2;
1210 v[2] = ctx->EvalMap.Map2Texture3.v1;
1211 v[3] = ctx->EvalMap.Map2Texture3.v2;
1212 break;
1213 case GL_MAP2_TEXTURE_COORD_4:
1214 v[0] = ctx->EvalMap.Map2Texture4.u1;
1215 v[1] = ctx->EvalMap.Map2Texture4.u2;
1216 v[2] = ctx->EvalMap.Map2Texture4.v1;
1217 v[3] = ctx->EvalMap.Map2Texture4.v2;
1218 break;
1219 case GL_MAP2_VERTEX_3:
1220 v[0] = ctx->EvalMap.Map2Vertex3.u1;
1221 v[1] = ctx->EvalMap.Map2Vertex3.u2;
1222 v[2] = ctx->EvalMap.Map2Vertex3.v1;
1223 v[3] = ctx->EvalMap.Map2Vertex3.v2;
1224 break;
1225 case GL_MAP2_VERTEX_4:
1226 v[0] = ctx->EvalMap.Map2Vertex4.u1;
1227 v[1] = ctx->EvalMap.Map2Vertex4.u2;
1228 v[2] = ctx->EvalMap.Map2Vertex4.v1;
1229 v[3] = ctx->EvalMap.Map2Vertex4.v2;
1230 break;
1231 default:
1232 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
1233 }
1234 break;
1235 default:
1236 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
1237 }
1238 }
1239
1240
1241 void
1242 _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
1243 {
1244 GET_CURRENT_CONTEXT(ctx);
1245 GLuint i, n;
1246 GLfloat *data;
1247
1248 switch (query) {
1249 case GL_COEFF:
1250 switch (target) {
1251 case GL_MAP1_COLOR_4:
1252 data = ctx->EvalMap.Map1Color4.Points;
1253 n = ctx->EvalMap.Map1Color4.Order * 4;
1254 break;
1255 case GL_MAP1_INDEX:
1256 data = ctx->EvalMap.Map1Index.Points;
1257 n = ctx->EvalMap.Map1Index.Order;
1258 break;
1259 case GL_MAP1_NORMAL:
1260 data = ctx->EvalMap.Map1Normal.Points;
1261 n = ctx->EvalMap.Map1Normal.Order * 3;
1262 break;
1263 case GL_MAP1_TEXTURE_COORD_1:
1264 data = ctx->EvalMap.Map1Texture1.Points;
1265 n = ctx->EvalMap.Map1Texture1.Order * 1;
1266 break;
1267 case GL_MAP1_TEXTURE_COORD_2:
1268 data = ctx->EvalMap.Map1Texture2.Points;
1269 n = ctx->EvalMap.Map1Texture2.Order * 2;
1270 break;
1271 case GL_MAP1_TEXTURE_COORD_3:
1272 data = ctx->EvalMap.Map1Texture3.Points;
1273 n = ctx->EvalMap.Map1Texture3.Order * 3;
1274 break;
1275 case GL_MAP1_TEXTURE_COORD_4:
1276 data = ctx->EvalMap.Map1Texture4.Points;
1277 n = ctx->EvalMap.Map1Texture4.Order * 4;
1278 break;
1279 case GL_MAP1_VERTEX_3:
1280 data = ctx->EvalMap.Map1Vertex3.Points;
1281 n = ctx->EvalMap.Map1Vertex3.Order * 3;
1282 break;
1283 case GL_MAP1_VERTEX_4:
1284 data = ctx->EvalMap.Map1Vertex4.Points;
1285 n = ctx->EvalMap.Map1Vertex4.Order * 4;
1286 break;
1287 case GL_MAP2_COLOR_4:
1288 data = ctx->EvalMap.Map2Color4.Points;
1289 n = ctx->EvalMap.Map2Color4.Uorder
1290 * ctx->EvalMap.Map2Color4.Vorder * 4;
1291 break;
1292 case GL_MAP2_INDEX:
1293 data = ctx->EvalMap.Map2Index.Points;
1294 n = ctx->EvalMap.Map2Index.Uorder
1295 * ctx->EvalMap.Map2Index.Vorder;
1296 break;
1297 case GL_MAP2_NORMAL:
1298 data = ctx->EvalMap.Map2Normal.Points;
1299 n = ctx->EvalMap.Map2Normal.Uorder
1300 * ctx->EvalMap.Map2Normal.Vorder * 3;
1301 break;
1302 case GL_MAP2_TEXTURE_COORD_1:
1303 data = ctx->EvalMap.Map2Texture1.Points;
1304 n = ctx->EvalMap.Map2Texture1.Uorder
1305 * ctx->EvalMap.Map2Texture1.Vorder * 1;
1306 break;
1307 case GL_MAP2_TEXTURE_COORD_2:
1308 data = ctx->EvalMap.Map2Texture2.Points;
1309 n = ctx->EvalMap.Map2Texture2.Uorder
1310 * ctx->EvalMap.Map2Texture2.Vorder * 2;
1311 break;
1312 case GL_MAP2_TEXTURE_COORD_3:
1313 data = ctx->EvalMap.Map2Texture3.Points;
1314 n = ctx->EvalMap.Map2Texture3.Uorder
1315 * ctx->EvalMap.Map2Texture3.Vorder * 3;
1316 break;
1317 case GL_MAP2_TEXTURE_COORD_4:
1318 data = ctx->EvalMap.Map2Texture4.Points;
1319 n = ctx->EvalMap.Map2Texture4.Uorder
1320 * ctx->EvalMap.Map2Texture4.Vorder * 4;
1321 break;
1322 case GL_MAP2_VERTEX_3:
1323 data = ctx->EvalMap.Map2Vertex3.Points;
1324 n = ctx->EvalMap.Map2Vertex3.Uorder
1325 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
1326 break;
1327 case GL_MAP2_VERTEX_4:
1328 data = ctx->EvalMap.Map2Vertex4.Points;
1329 n = ctx->EvalMap.Map2Vertex4.Uorder
1330 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
1331 break;
1332 default:
1333 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1334 return;
1335 }
1336 if (data) {
1337 for (i=0;i<n;i++) {
1338 v[i] = ROUNDF(data[i]);
1339 }
1340 }
1341 break;
1342 case GL_ORDER:
1343 switch (target) {
1344 case GL_MAP1_COLOR_4:
1345 *v = ctx->EvalMap.Map1Color4.Order;
1346 break;
1347 case GL_MAP1_INDEX:
1348 *v = ctx->EvalMap.Map1Index.Order;
1349 break;
1350 case GL_MAP1_NORMAL:
1351 *v = ctx->EvalMap.Map1Normal.Order;
1352 break;
1353 case GL_MAP1_TEXTURE_COORD_1:
1354 *v = ctx->EvalMap.Map1Texture1.Order;
1355 break;
1356 case GL_MAP1_TEXTURE_COORD_2:
1357 *v = ctx->EvalMap.Map1Texture2.Order;
1358 break;
1359 case GL_MAP1_TEXTURE_COORD_3:
1360 *v = ctx->EvalMap.Map1Texture3.Order;
1361 break;
1362 case GL_MAP1_TEXTURE_COORD_4:
1363 *v = ctx->EvalMap.Map1Texture4.Order;
1364 break;
1365 case GL_MAP1_VERTEX_3:
1366 *v = ctx->EvalMap.Map1Vertex3.Order;
1367 break;
1368 case GL_MAP1_VERTEX_4:
1369 *v = ctx->EvalMap.Map1Vertex4.Order;
1370 break;
1371 case GL_MAP2_COLOR_4:
1372 v[0] = ctx->EvalMap.Map2Color4.Uorder;
1373 v[1] = ctx->EvalMap.Map2Color4.Vorder;
1374 break;
1375 case GL_MAP2_INDEX:
1376 v[0] = ctx->EvalMap.Map2Index.Uorder;
1377 v[1] = ctx->EvalMap.Map2Index.Vorder;
1378 break;
1379 case GL_MAP2_NORMAL:
1380 v[0] = ctx->EvalMap.Map2Normal.Uorder;
1381 v[1] = ctx->EvalMap.Map2Normal.Vorder;
1382 break;
1383 case GL_MAP2_TEXTURE_COORD_1:
1384 v[0] = ctx->EvalMap.Map2Texture1.Uorder;
1385 v[1] = ctx->EvalMap.Map2Texture1.Vorder;
1386 break;
1387 case GL_MAP2_TEXTURE_COORD_2:
1388 v[0] = ctx->EvalMap.Map2Texture2.Uorder;
1389 v[1] = ctx->EvalMap.Map2Texture2.Vorder;
1390 break;
1391 case GL_MAP2_TEXTURE_COORD_3:
1392 v[0] = ctx->EvalMap.Map2Texture3.Uorder;
1393 v[1] = ctx->EvalMap.Map2Texture3.Vorder;
1394 break;
1395 case GL_MAP2_TEXTURE_COORD_4:
1396 v[0] = ctx->EvalMap.Map2Texture4.Uorder;
1397 v[1] = ctx->EvalMap.Map2Texture4.Vorder;
1398 break;
1399 case GL_MAP2_VERTEX_3:
1400 v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
1401 v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
1402 break;
1403 case GL_MAP2_VERTEX_4:
1404 v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
1405 v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
1406 break;
1407 default:
1408 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1409 return;
1410 }
1411 break;
1412 case GL_DOMAIN:
1413 switch (target) {
1414 case GL_MAP1_COLOR_4:
1415 v[0] = ROUNDF(ctx->EvalMap.Map1Color4.u1);
1416 v[1] = ROUNDF(ctx->EvalMap.Map1Color4.u2);
1417 break;
1418 case GL_MAP1_INDEX:
1419 v[0] = ROUNDF(ctx->EvalMap.Map1Index.u1);
1420 v[1] = ROUNDF(ctx->EvalMap.Map1Index.u2);
1421 break;
1422 case GL_MAP1_NORMAL:
1423 v[0] = ROUNDF(ctx->EvalMap.Map1Normal.u1);
1424 v[1] = ROUNDF(ctx->EvalMap.Map1Normal.u2);
1425 break;
1426 case GL_MAP1_TEXTURE_COORD_1:
1427 v[0] = ROUNDF(ctx->EvalMap.Map1Texture1.u1);
1428 v[1] = ROUNDF(ctx->EvalMap.Map1Texture1.u2);
1429 break;
1430 case GL_MAP1_TEXTURE_COORD_2:
1431 v[0] = ROUNDF(ctx->EvalMap.Map1Texture2.u1);
1432 v[1] = ROUNDF(ctx->EvalMap.Map1Texture2.u2);
1433 break;
1434 case GL_MAP1_TEXTURE_COORD_3:
1435 v[0] = ROUNDF(ctx->EvalMap.Map1Texture3.u1);
1436 v[1] = ROUNDF(ctx->EvalMap.Map1Texture3.u2);
1437 break;
1438 case GL_MAP1_TEXTURE_COORD_4:
1439 v[0] = ROUNDF(ctx->EvalMap.Map1Texture4.u1);
1440 v[1] = ROUNDF(ctx->EvalMap.Map1Texture4.u2);
1441 break;
1442 case GL_MAP1_VERTEX_3:
1443 v[0] = ROUNDF(ctx->EvalMap.Map1Vertex3.u1);
1444 v[1] = ROUNDF(ctx->EvalMap.Map1Vertex3.u2);
1445 break;
1446 case GL_MAP1_VERTEX_4:
1447 v[0] = ROUNDF(ctx->EvalMap.Map1Vertex4.u1);
1448 v[1] = ROUNDF(ctx->EvalMap.Map1Vertex4.u2);
1449 break;
1450 case GL_MAP2_COLOR_4:
1451 v[0] = ROUNDF(ctx->EvalMap.Map2Color4.u1);
1452 v[1] = ROUNDF(ctx->EvalMap.Map2Color4.u2);
1453 v[2] = ROUNDF(ctx->EvalMap.Map2Color4.v1);
1454 v[3] = ROUNDF(ctx->EvalMap.Map2Color4.v2);
1455 break;
1456 case GL_MAP2_INDEX:
1457 v[0] = ROUNDF(ctx->EvalMap.Map2Index.u1);
1458 v[1] = ROUNDF(ctx->EvalMap.Map2Index.u2);
1459 v[2] = ROUNDF(ctx->EvalMap.Map2Index.v1);
1460 v[3] = ROUNDF(ctx->EvalMap.Map2Index.v2);
1461 break;
1462 case GL_MAP2_NORMAL:
1463 v[0] = ROUNDF(ctx->EvalMap.Map2Normal.u1);
1464 v[1] = ROUNDF(ctx->EvalMap.Map2Normal.u2);
1465 v[2] = ROUNDF(ctx->EvalMap.Map2Normal.v1);
1466 v[3] = ROUNDF(ctx->EvalMap.Map2Normal.v2);
1467 break;
1468 case GL_MAP2_TEXTURE_COORD_1:
1469 v[0] = ROUNDF(ctx->EvalMap.Map2Texture1.u1);
1470 v[1] = ROUNDF(ctx->EvalMap.Map2Texture1.u2);
1471 v[2] = ROUNDF(ctx->EvalMap.Map2Texture1.v1);
1472 v[3] = ROUNDF(ctx->EvalMap.Map2Texture1.v2);
1473 break;
1474 case GL_MAP2_TEXTURE_COORD_2:
1475 v[0] = ROUNDF(ctx->EvalMap.Map2Texture2.u1);
1476 v[1] = ROUNDF(ctx->EvalMap.Map2Texture2.u2);
1477 v[2] = ROUNDF(ctx->EvalMap.Map2Texture2.v1);
1478 v[3] = ROUNDF(ctx->EvalMap.Map2Texture2.v2);
1479 break;
1480 case GL_MAP2_TEXTURE_COORD_3:
1481 v[0] = ROUNDF(ctx->EvalMap.Map2Texture3.u1);
1482 v[1] = ROUNDF(ctx->EvalMap.Map2Texture3.u2);
1483 v[2] = ROUNDF(ctx->EvalMap.Map2Texture3.v1);
1484 v[3] = ROUNDF(ctx->EvalMap.Map2Texture3.v2);
1485 break;
1486 case GL_MAP2_TEXTURE_COORD_4:
1487 v[0] = ROUNDF(ctx->EvalMap.Map2Texture4.u1);
1488 v[1] = ROUNDF(ctx->EvalMap.Map2Texture4.u2);
1489 v[2] = ROUNDF(ctx->EvalMap.Map2Texture4.v1);
1490 v[3] = ROUNDF(ctx->EvalMap.Map2Texture4.v2);
1491 break;
1492 case GL_MAP2_VERTEX_3:
1493 v[0] = ROUNDF(ctx->EvalMap.Map2Vertex3.u1);
1494 v[1] = ROUNDF(ctx->EvalMap.Map2Vertex3.u2);
1495 v[2] = ROUNDF(ctx->EvalMap.Map2Vertex3.v1);
1496 v[3] = ROUNDF(ctx->EvalMap.Map2Vertex3.v2);
1497 break;
1498 case GL_MAP2_VERTEX_4:
1499 v[0] = ROUNDF(ctx->EvalMap.Map2Vertex4.u1);
1500 v[1] = ROUNDF(ctx->EvalMap.Map2Vertex4.u2);
1501 v[2] = ROUNDF(ctx->EvalMap.Map2Vertex4.v1);
1502 v[3] = ROUNDF(ctx->EvalMap.Map2Vertex4.v2);
1503 break;
1504 default:
1505 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
1506 }
1507 break;
1508 default:
1509 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
1510 }
1511 }
1512
1513
1514
1515 void
1516 _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
1517 {
1518 GET_CURRENT_CONTEXT(ctx);
1519 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid1f");
1520
1521 if (un<1) {
1522 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
1523 return;
1524 }
1525 ctx->Eval.MapGrid1un = un;
1526 ctx->Eval.MapGrid1u1 = u1;
1527 ctx->Eval.MapGrid1u2 = u2;
1528 ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
1529
1530 ctx->NewState |= _NEW_EVAL;
1531 }
1532
1533
1534 void
1535 _mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
1536 {
1537 _mesa_MapGrid1f( un, u1, u2 );
1538 }
1539
1540
1541 void
1542 _mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
1543 GLint vn, GLfloat v1, GLfloat v2 )
1544 {
1545 GET_CURRENT_CONTEXT(ctx);
1546 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid2f");
1547 if (un<1) {
1548 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
1549 return;
1550 }
1551 if (vn<1) {
1552 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
1553 return;
1554 }
1555 ctx->Eval.MapGrid2un = un;
1556 ctx->Eval.MapGrid2u1 = u1;
1557 ctx->Eval.MapGrid2u2 = u2;
1558 ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
1559 ctx->Eval.MapGrid2vn = vn;
1560 ctx->Eval.MapGrid2v1 = v1;
1561 ctx->Eval.MapGrid2v2 = v2;
1562 ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
1563
1564 ctx->NewState |= _NEW_EVAL;
1565 }
1566
1567
1568 void
1569 _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
1570 GLint vn, GLdouble v1, GLdouble v2 )
1571 {
1572 _mesa_MapGrid2f( un, u1, u2, vn, v1, v2 );
1573 }
1574
1575
1576
1577