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