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