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