Subversion Repositories shark

Rev

Rev 55 | Details | Compare with Previous | Last modification | View Log | RSS feed

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