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