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