eval.c revision 6dc85575000127630489b407c50a4b3ea87c9acb
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 * \param 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 * \param 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 799 800 801/**********************************************************************/ 802/***** Initialization *****/ 803/**********************************************************************/ 804 805/** 806 * Initialize a 1-D evaluator map. 807 */ 808static void 809init_1d_map( struct gl_1d_map *map, int n, const float *initial ) 810{ 811 map->Order = 1; 812 map->u1 = 0.0; 813 map->u2 = 1.0; 814 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); 815 if (map->Points) { 816 GLint i; 817 for (i=0;i<n;i++) 818 map->Points[i] = initial[i]; 819 } 820} 821 822 823/** 824 * Initialize a 2-D evaluator map 825 */ 826static void 827init_2d_map( struct gl_2d_map *map, int n, const float *initial ) 828{ 829 map->Uorder = 1; 830 map->Vorder = 1; 831 map->u1 = 0.0; 832 map->u2 = 1.0; 833 map->v1 = 0.0; 834 map->v2 = 1.0; 835 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); 836 if (map->Points) { 837 GLint i; 838 for (i=0;i<n;i++) 839 map->Points[i] = initial[i]; 840 } 841} 842 843 844void _mesa_init_eval( GLcontext *ctx ) 845{ 846 int i; 847 848 /* Evaluators group */ 849 ctx->Eval.Map1Color4 = GL_FALSE; 850 ctx->Eval.Map1Index = GL_FALSE; 851 ctx->Eval.Map1Normal = GL_FALSE; 852 ctx->Eval.Map1TextureCoord1 = GL_FALSE; 853 ctx->Eval.Map1TextureCoord2 = GL_FALSE; 854 ctx->Eval.Map1TextureCoord3 = GL_FALSE; 855 ctx->Eval.Map1TextureCoord4 = GL_FALSE; 856 ctx->Eval.Map1Vertex3 = GL_FALSE; 857 ctx->Eval.Map1Vertex4 = GL_FALSE; 858 MEMSET(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib)); 859 ctx->Eval.Map2Color4 = GL_FALSE; 860 ctx->Eval.Map2Index = GL_FALSE; 861 ctx->Eval.Map2Normal = GL_FALSE; 862 ctx->Eval.Map2TextureCoord1 = GL_FALSE; 863 ctx->Eval.Map2TextureCoord2 = GL_FALSE; 864 ctx->Eval.Map2TextureCoord3 = GL_FALSE; 865 ctx->Eval.Map2TextureCoord4 = GL_FALSE; 866 ctx->Eval.Map2Vertex3 = GL_FALSE; 867 ctx->Eval.Map2Vertex4 = GL_FALSE; 868 MEMSET(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib)); 869 ctx->Eval.AutoNormal = GL_FALSE; 870 ctx->Eval.MapGrid1un = 1; 871 ctx->Eval.MapGrid1u1 = 0.0; 872 ctx->Eval.MapGrid1u2 = 1.0; 873 ctx->Eval.MapGrid2un = 1; 874 ctx->Eval.MapGrid2vn = 1; 875 ctx->Eval.MapGrid2u1 = 0.0; 876 ctx->Eval.MapGrid2u2 = 1.0; 877 ctx->Eval.MapGrid2v1 = 0.0; 878 ctx->Eval.MapGrid2v2 = 1.0; 879 880 /* Evaluator data */ 881 { 882 static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 }; 883 static GLfloat normal[3] = { 0.0, 0.0, 1.0 }; 884 static GLfloat index[1] = { 1.0 }; 885 static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 }; 886 static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 }; 887 static GLfloat attrib[4] = { 0.0, 0.0, 0.0, 1.0 }; 888 889 init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex ); 890 init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex ); 891 init_1d_map( &ctx->EvalMap.Map1Index, 1, index ); 892 init_1d_map( &ctx->EvalMap.Map1Color4, 4, color ); 893 init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal ); 894 init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord ); 895 init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord ); 896 init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord ); 897 init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord ); 898 for (i = 0; i < 16; i++) 899 init_1d_map( ctx->EvalMap.Map1Attrib + i, 4, attrib ); 900 901 init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex ); 902 init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex ); 903 init_2d_map( &ctx->EvalMap.Map2Index, 1, index ); 904 init_2d_map( &ctx->EvalMap.Map2Color4, 4, color ); 905 init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal ); 906 init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord ); 907 init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord ); 908 init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord ); 909 init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord ); 910 for (i = 0; i < 16; i++) 911 init_2d_map( ctx->EvalMap.Map2Attrib + i, 4, attrib ); 912 } 913} 914 915 916void _mesa_free_eval_data( GLcontext *ctx ) 917{ 918 int i; 919 920 /* Free evaluator data */ 921 if (ctx->EvalMap.Map1Vertex3.Points) 922 FREE( ctx->EvalMap.Map1Vertex3.Points ); 923 if (ctx->EvalMap.Map1Vertex4.Points) 924 FREE( ctx->EvalMap.Map1Vertex4.Points ); 925 if (ctx->EvalMap.Map1Index.Points) 926 FREE( ctx->EvalMap.Map1Index.Points ); 927 if (ctx->EvalMap.Map1Color4.Points) 928 FREE( ctx->EvalMap.Map1Color4.Points ); 929 if (ctx->EvalMap.Map1Normal.Points) 930 FREE( ctx->EvalMap.Map1Normal.Points ); 931 if (ctx->EvalMap.Map1Texture1.Points) 932 FREE( ctx->EvalMap.Map1Texture1.Points ); 933 if (ctx->EvalMap.Map1Texture2.Points) 934 FREE( ctx->EvalMap.Map1Texture2.Points ); 935 if (ctx->EvalMap.Map1Texture3.Points) 936 FREE( ctx->EvalMap.Map1Texture3.Points ); 937 if (ctx->EvalMap.Map1Texture4.Points) 938 FREE( ctx->EvalMap.Map1Texture4.Points ); 939 for (i = 0; i < 16; i++) 940 FREE((ctx->EvalMap.Map1Attrib[i].Points)); 941 942 if (ctx->EvalMap.Map2Vertex3.Points) 943 FREE( ctx->EvalMap.Map2Vertex3.Points ); 944 if (ctx->EvalMap.Map2Vertex4.Points) 945 FREE( ctx->EvalMap.Map2Vertex4.Points ); 946 if (ctx->EvalMap.Map2Index.Points) 947 FREE( ctx->EvalMap.Map2Index.Points ); 948 if (ctx->EvalMap.Map2Color4.Points) 949 FREE( ctx->EvalMap.Map2Color4.Points ); 950 if (ctx->EvalMap.Map2Normal.Points) 951 FREE( ctx->EvalMap.Map2Normal.Points ); 952 if (ctx->EvalMap.Map2Texture1.Points) 953 FREE( ctx->EvalMap.Map2Texture1.Points ); 954 if (ctx->EvalMap.Map2Texture2.Points) 955 FREE( ctx->EvalMap.Map2Texture2.Points ); 956 if (ctx->EvalMap.Map2Texture3.Points) 957 FREE( ctx->EvalMap.Map2Texture3.Points ); 958 if (ctx->EvalMap.Map2Texture4.Points) 959 FREE( ctx->EvalMap.Map2Texture4.Points ); 960 for (i = 0; i < 16; i++) 961 FREE((ctx->EvalMap.Map2Attrib[i].Points)); 962} 963