eval.c revision afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1c
1/* $Id: eval.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.1 6 * 7 * Copyright (C) 1999 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 30 31/* 32 * eval.c was written by 33 * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and 34 * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de). 35 * 36 * My original implementation of evaluators was simplistic and didn't 37 * compute surface normal vectors properly. Bernd and Volker applied 38 * used more sophisticated methods to get better results. 39 * 40 * Thanks guys! 41 */ 42 43 44#ifdef PC_HEADER 45#include "all.h" 46#else 47#include <math.h> 48#include <stdlib.h> 49#include <string.h> 50#include "context.h" 51#include "eval.h" 52#include "macros.h" 53#include "mmath.h" 54#include "types.h" 55#include "vbcull.h" 56#include "vbfill.h" 57#include "vbxform.h" 58#ifdef XFree86Server 59#include "GL/xf86glx.h" 60#endif 61#endif 62 63 64static GLfloat inv_tab[MAX_EVAL_ORDER]; 65 66/* 67 * Do one-time initialization for evaluators. 68 */ 69void gl_init_eval( void ) 70{ 71 static int init_flag = 0; 72 GLuint i; 73 74 /* Compute a table of nCr (combination) values used by the 75 * Bernstein polynomial generator. 76 */ 77 78 /* KW: precompute 1/x for useful x. 79 */ 80 if (init_flag==0) 81 { 82 for (i = 1 ; i < MAX_EVAL_ORDER ; i++) 83 inv_tab[i] = 1.0 / i; 84 } 85 86 init_flag = 1; 87} 88 89 90 91/* 92 * Horner scheme for Bezier curves 93 * 94 * Bezier curves can be computed via a Horner scheme. 95 * Horner is numerically less stable than the de Casteljau 96 * algorithm, but it is faster. For curves of degree n 97 * the complexity of Horner is O(n) and de Casteljau is O(n^2). 98 * Since stability is not important for displaying curve 99 * points I decided to use the Horner scheme. 100 * 101 * A cubic Bezier curve with control points b0, b1, b2, b3 can be 102 * written as 103 * 104 * (([3] [3] ) [3] ) [3] 105 * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3 106 * 107 * [n] 108 * where s=1-t and the binomial coefficients [i]. These can 109 * be computed iteratively using the identity: 110 * 111 * [n] [n ] [n] 112 * [i] = (n-i+1)/i * [i-1] and [0] = 1 113 */ 114 115 116static void 117horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t, 118 GLuint dim, GLuint order) 119{ 120 GLfloat s, powert; 121 GLuint i, k, bincoeff; 122 123 if(order >= 2) 124 { 125 bincoeff = order-1; 126 s = 1.0-t; 127 128 for(k=0; k<dim; k++) 129 out[k] = s*cp[k] + bincoeff*t*cp[dim+k]; 130 131 for(i=2, cp+=2*dim, powert=t*t; i<order; i++, powert*=t, cp +=dim) 132 { 133 bincoeff *= order-i; 134 bincoeff *= inv_tab[i]; 135 136 for(k=0; k<dim; k++) 137 out[k] = s*out[k] + bincoeff*powert*cp[k]; 138 } 139 } 140 else /* order=1 -> constant curve */ 141 { 142 for(k=0; k<dim; k++) 143 out[k] = cp[k]; 144 } 145} 146 147/* 148 * Tensor product Bezier surfaces 149 * 150 * Again the Horner scheme is used to compute a point on a 151 * TP Bezier surface. First a control polygon for a curve 152 * on the surface in one parameter direction is computed, 153 * then the point on the curve for the other parameter 154 * direction is evaluated. 155 * 156 * To store the curve control polygon additional storage 157 * for max(uorder,vorder) points is needed in the 158 * control net cn. 159 */ 160 161static void 162horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v, 163 GLuint dim, GLuint uorder, GLuint vorder) 164{ 165 GLfloat *cp = cn + uorder*vorder*dim; 166 GLuint i, uinc = vorder*dim; 167 168 if(vorder > uorder) 169 { 170 if(uorder >= 2) 171 { 172 GLfloat s, poweru; 173 GLuint j, k, bincoeff; 174 175 /* Compute the control polygon for the surface-curve in u-direction */ 176 for(j=0; j<vorder; j++) 177 { 178 GLfloat *ucp = &cn[j*dim]; 179 180 /* Each control point is the point for parameter u on a */ 181 /* curve defined by the control polygons in u-direction */ 182 bincoeff = uorder-1; 183 s = 1.0-u; 184 185 for(k=0; k<dim; k++) 186 cp[j*dim+k] = s*ucp[k] + bincoeff*u*ucp[uinc+k]; 187 188 for(i=2, ucp+=2*uinc, poweru=u*u; i<uorder; 189 i++, poweru*=u, ucp +=uinc) 190 { 191 bincoeff *= uorder-i; 192 bincoeff *= inv_tab[i]; 193 194 for(k=0; k<dim; k++) 195 cp[j*dim+k] = s*cp[j*dim+k] + bincoeff*poweru*ucp[k]; 196 } 197 } 198 199 /* Evaluate curve point in v */ 200 horner_bezier_curve(cp, out, v, dim, vorder); 201 } 202 else /* uorder=1 -> cn defines a curve in v */ 203 horner_bezier_curve(cn, out, v, dim, vorder); 204 } 205 else /* vorder <= uorder */ 206 { 207 if(vorder > 1) 208 { 209 GLuint i; 210 211 /* Compute the control polygon for the surface-curve in u-direction */ 212 for(i=0; i<uorder; i++, cn += uinc) 213 { 214 /* For constant i all cn[i][j] (j=0..vorder) are located */ 215 /* on consecutive memory locations, so we can use */ 216 /* horner_bezier_curve to compute the control points */ 217 218 horner_bezier_curve(cn, &cp[i*dim], v, dim, vorder); 219 } 220 221 /* Evaluate curve point in u */ 222 horner_bezier_curve(cp, out, u, dim, uorder); 223 } 224 else /* vorder=1 -> cn defines a curve in u */ 225 horner_bezier_curve(cn, out, u, dim, uorder); 226 } 227} 228 229/* 230 * The direct de Casteljau algorithm is used when a point on the 231 * surface and the tangent directions spanning the tangent plane 232 * should be computed (this is needed to compute normals to the 233 * surface). In this case the de Casteljau algorithm approach is 234 * nicer because a point and the partial derivatives can be computed 235 * at the same time. To get the correct tangent length du and dv 236 * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. 237 * Since only the directions are needed, this scaling step is omitted. 238 * 239 * De Casteljau needs additional storage for uorder*vorder 240 * values in the control net cn. 241 */ 242 243static void 244de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv, 245 GLfloat u, GLfloat v, GLuint dim, 246 GLuint uorder, GLuint vorder) 247{ 248 GLfloat *dcn = cn + uorder*vorder*dim; 249 GLfloat us = 1.0-u, vs = 1.0-v; 250 GLuint h, i, j, k; 251 GLuint minorder = uorder < vorder ? uorder : vorder; 252 GLuint uinc = vorder*dim; 253 GLuint dcuinc = vorder; 254 255 /* Each component is evaluated separately to save buffer space */ 256 /* This does not drasticaly decrease the performance of the */ 257 /* algorithm. If additional storage for (uorder-1)*(vorder-1) */ 258 /* points would be available, the components could be accessed */ 259 /* in the innermost loop which could lead to less cache misses. */ 260 261#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] 262#define DCN(I, J) dcn[(I)*dcuinc+(J)] 263 if(minorder < 3) 264 { 265 if(uorder==vorder) 266 { 267 for(k=0; k<dim; k++) 268 { 269 /* Derivative direction in u */ 270 du[k] = vs*(CN(1,0,k) - CN(0,0,k)) + 271 v*(CN(1,1,k) - CN(0,1,k)); 272 273 /* Derivative direction in v */ 274 dv[k] = us*(CN(0,1,k) - CN(0,0,k)) + 275 u*(CN(1,1,k) - CN(1,0,k)); 276 277 /* bilinear de Casteljau step */ 278 out[k] = us*(vs*CN(0,0,k) + v*CN(0,1,k)) + 279 u*(vs*CN(1,0,k) + v*CN(1,1,k)); 280 } 281 } 282 else if(minorder == uorder) 283 { 284 for(k=0; k<dim; k++) 285 { 286 /* bilinear de Casteljau step */ 287 DCN(1,0) = CN(1,0,k) - CN(0,0,k); 288 DCN(0,0) = us*CN(0,0,k) + u*CN(1,0,k); 289 290 for(j=0; j<vorder-1; j++) 291 { 292 /* for the derivative in u */ 293 DCN(1,j+1) = CN(1,j+1,k) - CN(0,j+1,k); 294 DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1); 295 296 /* for the `point' */ 297 DCN(0,j+1) = us*CN(0,j+1,k) + u*CN(1,j+1,k); 298 DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); 299 } 300 301 /* remaining linear de Casteljau steps until the second last step */ 302 for(h=minorder; h<vorder-1; h++) 303 for(j=0; j<vorder-h; j++) 304 { 305 /* for the derivative in u */ 306 DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1); 307 308 /* for the `point' */ 309 DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); 310 } 311 312 /* derivative direction in v */ 313 dv[k] = DCN(0,1) - DCN(0,0); 314 315 /* derivative direction in u */ 316 du[k] = vs*DCN(1,0) + v*DCN(1,1); 317 318 /* last linear de Casteljau step */ 319 out[k] = vs*DCN(0,0) + v*DCN(0,1); 320 } 321 } 322 else /* minorder == vorder */ 323 { 324 for(k=0; k<dim; k++) 325 { 326 /* bilinear de Casteljau step */ 327 DCN(0,1) = CN(0,1,k) - CN(0,0,k); 328 DCN(0,0) = vs*CN(0,0,k) + v*CN(0,1,k); 329 for(i=0; i<uorder-1; i++) 330 { 331 /* for the derivative in v */ 332 DCN(i+1,1) = CN(i+1,1,k) - CN(i+1,0,k); 333 DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1); 334 335 /* for the `point' */ 336 DCN(i+1,0) = vs*CN(i+1,0,k) + v*CN(i+1,1,k); 337 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 338 } 339 340 /* remaining linear de Casteljau steps until the second last step */ 341 for(h=minorder; h<uorder-1; h++) 342 for(i=0; i<uorder-h; i++) 343 { 344 /* for the derivative in v */ 345 DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1); 346 347 /* for the `point' */ 348 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 349 } 350 351 /* derivative direction in u */ 352 du[k] = DCN(1,0) - DCN(0,0); 353 354 /* derivative direction in v */ 355 dv[k] = us*DCN(0,1) + u*DCN(1,1); 356 357 /* last linear de Casteljau step */ 358 out[k] = us*DCN(0,0) + u*DCN(1,0); 359 } 360 } 361 } 362 else if(uorder == vorder) 363 { 364 for(k=0; k<dim; k++) 365 { 366 /* first bilinear de Casteljau step */ 367 for(i=0; i<uorder-1; i++) 368 { 369 DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); 370 for(j=0; j<vorder-1; j++) 371 { 372 DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); 373 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 374 } 375 } 376 377 /* remaining bilinear de Casteljau steps until the second last step */ 378 for(h=2; h<minorder-1; h++) 379 for(i=0; i<uorder-h; i++) 380 { 381 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 382 for(j=0; j<vorder-h; j++) 383 { 384 DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); 385 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 386 } 387 } 388 389 /* derivative direction in u */ 390 du[k] = vs*(DCN(1,0) - DCN(0,0)) + 391 v*(DCN(1,1) - DCN(0,1)); 392 393 /* derivative direction in v */ 394 dv[k] = us*(DCN(0,1) - DCN(0,0)) + 395 u*(DCN(1,1) - DCN(1,0)); 396 397 /* last bilinear de Casteljau step */ 398 out[k] = us*(vs*DCN(0,0) + v*DCN(0,1)) + 399 u*(vs*DCN(1,0) + v*DCN(1,1)); 400 } 401 } 402 else if(minorder == uorder) 403 { 404 for(k=0; k<dim; k++) 405 { 406 /* first bilinear de Casteljau step */ 407 for(i=0; i<uorder-1; i++) 408 { 409 DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); 410 for(j=0; j<vorder-1; j++) 411 { 412 DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); 413 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 414 } 415 } 416 417 /* remaining bilinear de Casteljau steps until the second last step */ 418 for(h=2; h<minorder-1; h++) 419 for(i=0; i<uorder-h; i++) 420 { 421 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 422 for(j=0; j<vorder-h; j++) 423 { 424 DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); 425 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 426 } 427 } 428 429 /* last bilinear de Casteljau step */ 430 DCN(2,0) = DCN(1,0) - DCN(0,0); 431 DCN(0,0) = us*DCN(0,0) + u*DCN(1,0); 432 for(j=0; j<vorder-1; j++) 433 { 434 /* for the derivative in u */ 435 DCN(2,j+1) = DCN(1,j+1) - DCN(0,j+1); 436 DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1); 437 438 /* for the `point' */ 439 DCN(0,j+1) = us*DCN(0,j+1 ) + u*DCN(1,j+1); 440 DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); 441 } 442 443 /* remaining linear de Casteljau steps until the second last step */ 444 for(h=minorder; h<vorder-1; h++) 445 for(j=0; j<vorder-h; j++) 446 { 447 /* for the derivative in u */ 448 DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1); 449 450 /* for the `point' */ 451 DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); 452 } 453 454 /* derivative direction in v */ 455 dv[k] = DCN(0,1) - DCN(0,0); 456 457 /* derivative direction in u */ 458 du[k] = vs*DCN(2,0) + v*DCN(2,1); 459 460 /* last linear de Casteljau step */ 461 out[k] = vs*DCN(0,0) + v*DCN(0,1); 462 } 463 } 464 else /* minorder == vorder */ 465 { 466 for(k=0; k<dim; k++) 467 { 468 /* first bilinear de Casteljau step */ 469 for(i=0; i<uorder-1; i++) 470 { 471 DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); 472 for(j=0; j<vorder-1; j++) 473 { 474 DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); 475 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 476 } 477 } 478 479 /* remaining bilinear de Casteljau steps until the second last step */ 480 for(h=2; h<minorder-1; h++) 481 for(i=0; i<uorder-h; i++) 482 { 483 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 484 for(j=0; j<vorder-h; j++) 485 { 486 DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); 487 DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); 488 } 489 } 490 491 /* last bilinear de Casteljau step */ 492 DCN(0,2) = DCN(0,1) - DCN(0,0); 493 DCN(0,0) = vs*DCN(0,0) + v*DCN(0,1); 494 for(i=0; i<uorder-1; i++) 495 { 496 /* for the derivative in v */ 497 DCN(i+1,2) = DCN(i+1,1) - DCN(i+1,0); 498 DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2); 499 500 /* for the `point' */ 501 DCN(i+1,0) = vs*DCN(i+1,0) + v*DCN(i+1,1); 502 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 503 } 504 505 /* remaining linear de Casteljau steps until the second last step */ 506 for(h=minorder; h<uorder-1; h++) 507 for(i=0; i<uorder-h; i++) 508 { 509 /* for the derivative in v */ 510 DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2); 511 512 /* for the `point' */ 513 DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); 514 } 515 516 /* derivative direction in u */ 517 du[k] = DCN(1,0) - DCN(0,0); 518 519 /* derivative direction in v */ 520 dv[k] = us*DCN(0,2) + u*DCN(1,2); 521 522 /* last linear de Casteljau step */ 523 out[k] = us*DCN(0,0) + u*DCN(1,0); 524 } 525 } 526#undef DCN 527#undef CN 528} 529 530/* 531 * Return the number of components per control point for any type of 532 * evaluator. Return 0 if bad target. 533 */ 534 535static GLint components( GLenum target ) 536{ 537 switch (target) { 538 case GL_MAP1_VERTEX_3: return 3; 539 case GL_MAP1_VERTEX_4: return 4; 540 case GL_MAP1_INDEX: return 1; 541 case GL_MAP1_COLOR_4: return 4; 542 case GL_MAP1_NORMAL: return 3; 543 case GL_MAP1_TEXTURE_COORD_1: return 1; 544 case GL_MAP1_TEXTURE_COORD_2: return 2; 545 case GL_MAP1_TEXTURE_COORD_3: return 3; 546 case GL_MAP1_TEXTURE_COORD_4: return 4; 547 case GL_MAP2_VERTEX_3: return 3; 548 case GL_MAP2_VERTEX_4: return 4; 549 case GL_MAP2_INDEX: return 1; 550 case GL_MAP2_COLOR_4: return 4; 551 case GL_MAP2_NORMAL: return 3; 552 case GL_MAP2_TEXTURE_COORD_1: return 1; 553 case GL_MAP2_TEXTURE_COORD_2: return 2; 554 case GL_MAP2_TEXTURE_COORD_3: return 3; 555 case GL_MAP2_TEXTURE_COORD_4: return 4; 556 default: return 0; 557 } 558} 559 560 561/**********************************************************************/ 562/*** Copy and deallocate control points ***/ 563/**********************************************************************/ 564 565 566/* 567 * Copy 1-parametric evaluator control points from user-specified 568 * memory space to a buffer of contiguous control points. 569 * Input: see glMap1f for details 570 * Return: pointer to buffer of contiguous control points or NULL if out 571 * of memory. 572 */ 573GLfloat *gl_copy_map_points1f( GLenum target, 574 GLint ustride, GLint uorder, 575 const GLfloat *points ) 576{ 577 GLfloat *buffer, *p; 578 GLint i, k, size = components(target); 579 580 if (!points || size==0) { 581 return NULL; 582 } 583 584 buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat)); 585 586 if(buffer) 587 for(i=0, p=buffer; i<uorder; i++, points+=ustride) 588 for(k=0; k<size; k++) 589 *p++ = points[k]; 590 591 return buffer; 592} 593 594 595 596/* 597 * Same as above but convert doubles to floats. 598 */ 599GLfloat *gl_copy_map_points1d( GLenum target, 600 GLint ustride, GLint uorder, 601 const GLdouble *points ) 602{ 603 GLfloat *buffer, *p; 604 GLint i, k, size = components(target); 605 606 if (!points || size==0) { 607 return NULL; 608 } 609 610 buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat)); 611 612 if(buffer) 613 for(i=0, p=buffer; i<uorder; i++, points+=ustride) 614 for(k=0; k<size; k++) 615 *p++ = (GLfloat) points[k]; 616 617 return buffer; 618} 619 620 621 622/* 623 * Copy 2-parametric evaluator control points from user-specified 624 * memory space to a buffer of contiguous control points. 625 * Additional memory is allocated to be used by the horner and 626 * de Casteljau evaluation schemes. 627 * 628 * Input: see glMap2f for details 629 * Return: pointer to buffer of contiguous control points or NULL if out 630 * of memory. 631 */ 632GLfloat *gl_copy_map_points2f( GLenum target, 633 GLint ustride, GLint uorder, 634 GLint vstride, GLint vorder, 635 const GLfloat *points ) 636{ 637 GLfloat *buffer, *p; 638 GLint i, j, k, size, dsize, hsize; 639 GLint uinc; 640 641 size = components(target); 642 643 if (!points || size==0) { 644 return NULL; 645 } 646 647 /* max(uorder, vorder) additional points are used in */ 648 /* horner evaluation and uorder*vorder additional */ 649 /* values are needed for de Casteljau */ 650 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder; 651 hsize = (uorder > vorder ? uorder : vorder)*size; 652 653 if(hsize>dsize) 654 buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat)); 655 else 656 buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat)); 657 658 /* compute the increment value for the u-loop */ 659 uinc = ustride - vorder*vstride; 660 661 if (buffer) 662 for (i=0, p=buffer; i<uorder; i++, points += uinc) 663 for (j=0; j<vorder; j++, points += vstride) 664 for (k=0; k<size; k++) 665 *p++ = points[k]; 666 667 return buffer; 668} 669 670 671 672/* 673 * Same as above but convert doubles to floats. 674 */ 675GLfloat *gl_copy_map_points2d(GLenum target, 676 GLint ustride, GLint uorder, 677 GLint vstride, GLint vorder, 678 const GLdouble *points ) 679{ 680 GLfloat *buffer, *p; 681 GLint i, j, k, size, hsize, dsize; 682 GLint uinc; 683 684 size = components(target); 685 686 if (!points || size==0) { 687 return NULL; 688 } 689 690 /* max(uorder, vorder) additional points are used in */ 691 /* horner evaluation and uorder*vorder additional */ 692 /* values are needed for de Casteljau */ 693 dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder; 694 hsize = (uorder > vorder ? uorder : vorder)*size; 695 696 if(hsize>dsize) 697 buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat)); 698 else 699 buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat)); 700 701 /* compute the increment value for the u-loop */ 702 uinc = ustride - vorder*vstride; 703 704 if (buffer) 705 for (i=0, p=buffer; i<uorder; i++, points += uinc) 706 for (j=0; j<vorder; j++, points += vstride) 707 for (k=0; k<size; k++) 708 *p++ = (GLfloat) points[k]; 709 710 return buffer; 711} 712 713 714/* 715 * This function is called by the display list deallocator function to 716 * specify that a given set of control points are no longer needed. 717 */ 718void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data ) 719{ 720 struct gl_1d_map *map1 = NULL; 721 struct gl_2d_map *map2 = NULL; 722 723 switch (target) { 724 case GL_MAP1_VERTEX_3: 725 map1 = &ctx->EvalMap.Map1Vertex3; 726 break; 727 case GL_MAP1_VERTEX_4: 728 map1 = &ctx->EvalMap.Map1Vertex4; 729 break; 730 case GL_MAP1_INDEX: 731 map1 = &ctx->EvalMap.Map1Index; 732 break; 733 case GL_MAP1_COLOR_4: 734 map1 = &ctx->EvalMap.Map1Color4; 735 break; 736 case GL_MAP1_NORMAL: 737 map1 = &ctx->EvalMap.Map1Normal; 738 break; 739 case GL_MAP1_TEXTURE_COORD_1: 740 map1 = &ctx->EvalMap.Map1Texture1; 741 break; 742 case GL_MAP1_TEXTURE_COORD_2: 743 map1 = &ctx->EvalMap.Map1Texture2; 744 break; 745 case GL_MAP1_TEXTURE_COORD_3: 746 map1 = &ctx->EvalMap.Map1Texture3; 747 break; 748 case GL_MAP1_TEXTURE_COORD_4: 749 map1 = &ctx->EvalMap.Map1Texture4; 750 break; 751 case GL_MAP2_VERTEX_3: 752 map2 = &ctx->EvalMap.Map2Vertex3; 753 break; 754 case GL_MAP2_VERTEX_4: 755 map2 = &ctx->EvalMap.Map2Vertex4; 756 break; 757 case GL_MAP2_INDEX: 758 map2 = &ctx->EvalMap.Map2Index; 759 break; 760 case GL_MAP2_COLOR_4: 761 map2 = &ctx->EvalMap.Map2Color4; 762 break; 763 case GL_MAP2_NORMAL: 764 map2 = &ctx->EvalMap.Map2Normal; 765 break; 766 case GL_MAP2_TEXTURE_COORD_1: 767 map2 = &ctx->EvalMap.Map2Texture1; 768 break; 769 case GL_MAP2_TEXTURE_COORD_2: 770 map2 = &ctx->EvalMap.Map2Texture2; 771 break; 772 case GL_MAP2_TEXTURE_COORD_3: 773 map2 = &ctx->EvalMap.Map2Texture3; 774 break; 775 case GL_MAP2_TEXTURE_COORD_4: 776 map2 = &ctx->EvalMap.Map2Texture4; 777 break; 778 default: 779 gl_error( ctx, GL_INVALID_ENUM, "gl_free_control_points" ); 780 return; 781 } 782 783 if (map1) { 784 if (data==map1->Points) { 785 /* The control points in the display list are currently */ 786 /* being used so we can mark them as discard-able. */ 787 map1->Retain = GL_FALSE; 788 } 789 else { 790 /* The control points in the display list are not currently */ 791 /* being used. */ 792 free( data ); 793 } 794 } 795 if (map2) { 796 if (data==map2->Points) { 797 /* The control points in the display list are currently */ 798 /* being used so we can mark them as discard-able. */ 799 map2->Retain = GL_FALSE; 800 } 801 else { 802 /* The control points in the display list are not currently */ 803 /* being used. */ 804 free( data ); 805 } 806 } 807 808} 809 810 811 812/**********************************************************************/ 813/*** API entry points ***/ 814/**********************************************************************/ 815 816 817/* 818 * Note that the array of control points must be 'unpacked' at this time. 819 * Input: retain - if TRUE, this control point data is also in a display 820 * list and can't be freed until the list is freed. 821 */ 822void gl_Map1f( GLcontext* ctx, GLenum target, 823 GLfloat u1, GLfloat u2, GLint stride, 824 GLint order, const GLfloat *points, GLboolean retain ) 825{ 826 GLint k; 827 828 if (!points) { 829 gl_error( ctx, GL_OUT_OF_MEMORY, "glMap1f" ); 830 return; 831 } 832 833 /* may be a new stride after copying control points */ 834 stride = components( target ); 835 836 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap1"); 837 838 if (u1==u2) { 839 gl_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" ); 840 return; 841 } 842 843 if (order<1 || order>MAX_EVAL_ORDER) { 844 gl_error( ctx, GL_INVALID_VALUE, "glMap1(order)" ); 845 return; 846 } 847 848 k = components( target ); 849 if (k==0) { 850 gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); 851 } 852 853 if (stride < k) { 854 gl_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" ); 855 return; 856 } 857 858 switch (target) { 859 case GL_MAP1_VERTEX_3: 860 ctx->EvalMap.Map1Vertex3.Order = order; 861 ctx->EvalMap.Map1Vertex3.u1 = u1; 862 ctx->EvalMap.Map1Vertex3.u2 = u2; 863 ctx->EvalMap.Map1Vertex3.du = 1.0 / (u2 - u1); 864 if (ctx->EvalMap.Map1Vertex3.Points 865 && !ctx->EvalMap.Map1Vertex3.Retain) { 866 free( ctx->EvalMap.Map1Vertex3.Points ); 867 } 868 ctx->EvalMap.Map1Vertex3.Points = (GLfloat *) points; 869 ctx->EvalMap.Map1Vertex3.Retain = retain; 870 break; 871 case GL_MAP1_VERTEX_4: 872 ctx->EvalMap.Map1Vertex4.Order = order; 873 ctx->EvalMap.Map1Vertex4.u1 = u1; 874 ctx->EvalMap.Map1Vertex4.u2 = u2; 875 ctx->EvalMap.Map1Vertex4.du = 1.0 / (u2 - u1); 876 if (ctx->EvalMap.Map1Vertex4.Points 877 && !ctx->EvalMap.Map1Vertex4.Retain) { 878 free( ctx->EvalMap.Map1Vertex4.Points ); 879 } 880 ctx->EvalMap.Map1Vertex4.Points = (GLfloat *) points; 881 ctx->EvalMap.Map1Vertex4.Retain = retain; 882 break; 883 case GL_MAP1_INDEX: 884 ctx->EvalMap.Map1Index.Order = order; 885 ctx->EvalMap.Map1Index.u1 = u1; 886 ctx->EvalMap.Map1Index.u2 = u2; 887 ctx->EvalMap.Map1Index.du = 1.0 / (u2 - u1); 888 if (ctx->EvalMap.Map1Index.Points 889 && !ctx->EvalMap.Map1Index.Retain) { 890 free( ctx->EvalMap.Map1Index.Points ); 891 } 892 ctx->EvalMap.Map1Index.Points = (GLfloat *) points; 893 ctx->EvalMap.Map1Index.Retain = retain; 894 break; 895 case GL_MAP1_COLOR_4: 896 ctx->EvalMap.Map1Color4.Order = order; 897 ctx->EvalMap.Map1Color4.u1 = u1; 898 ctx->EvalMap.Map1Color4.u2 = u2; 899 ctx->EvalMap.Map1Color4.du = 1.0 / (u2 - u1); 900 if (ctx->EvalMap.Map1Color4.Points 901 && !ctx->EvalMap.Map1Color4.Retain) { 902 free( ctx->EvalMap.Map1Color4.Points ); 903 } 904 ctx->EvalMap.Map1Color4.Points = (GLfloat *) points; 905 ctx->EvalMap.Map1Color4.Retain = retain; 906 break; 907 case GL_MAP1_NORMAL: 908 ctx->EvalMap.Map1Normal.Order = order; 909 ctx->EvalMap.Map1Normal.u1 = u1; 910 ctx->EvalMap.Map1Normal.u2 = u2; 911 ctx->EvalMap.Map1Normal.du = 1.0 / (u2 - u1); 912 if (ctx->EvalMap.Map1Normal.Points 913 && !ctx->EvalMap.Map1Normal.Retain) { 914 free( ctx->EvalMap.Map1Normal.Points ); 915 } 916 ctx->EvalMap.Map1Normal.Points = (GLfloat *) points; 917 ctx->EvalMap.Map1Normal.Retain = retain; 918 break; 919 case GL_MAP1_TEXTURE_COORD_1: 920 ctx->EvalMap.Map1Texture1.Order = order; 921 ctx->EvalMap.Map1Texture1.u1 = u1; 922 ctx->EvalMap.Map1Texture1.u2 = u2; 923 ctx->EvalMap.Map1Texture1.du = 1.0 / (u2 - u1); 924 if (ctx->EvalMap.Map1Texture1.Points 925 && !ctx->EvalMap.Map1Texture1.Retain) { 926 free( ctx->EvalMap.Map1Texture1.Points ); 927 } 928 ctx->EvalMap.Map1Texture1.Points = (GLfloat *) points; 929 ctx->EvalMap.Map1Texture1.Retain = retain; 930 break; 931 case GL_MAP1_TEXTURE_COORD_2: 932 ctx->EvalMap.Map1Texture2.Order = order; 933 ctx->EvalMap.Map1Texture2.u1 = u1; 934 ctx->EvalMap.Map1Texture2.u2 = u2; 935 ctx->EvalMap.Map1Texture2.du = 1.0 / (u2 - u1); 936 if (ctx->EvalMap.Map1Texture2.Points 937 && !ctx->EvalMap.Map1Texture2.Retain) { 938 free( ctx->EvalMap.Map1Texture2.Points ); 939 } 940 ctx->EvalMap.Map1Texture2.Points = (GLfloat *) points; 941 ctx->EvalMap.Map1Texture2.Retain = retain; 942 break; 943 case GL_MAP1_TEXTURE_COORD_3: 944 ctx->EvalMap.Map1Texture3.Order = order; 945 ctx->EvalMap.Map1Texture3.u1 = u1; 946 ctx->EvalMap.Map1Texture3.u2 = u2; 947 ctx->EvalMap.Map1Texture3.du = 1.0 / (u2 - u1); 948 if (ctx->EvalMap.Map1Texture3.Points 949 && !ctx->EvalMap.Map1Texture3.Retain) { 950 free( ctx->EvalMap.Map1Texture3.Points ); 951 } 952 ctx->EvalMap.Map1Texture3.Points = (GLfloat *) points; 953 ctx->EvalMap.Map1Texture3.Retain = retain; 954 break; 955 case GL_MAP1_TEXTURE_COORD_4: 956 ctx->EvalMap.Map1Texture4.Order = order; 957 ctx->EvalMap.Map1Texture4.u1 = u1; 958 ctx->EvalMap.Map1Texture4.u2 = u2; 959 ctx->EvalMap.Map1Texture4.du = 1.0 / (u2 - u1); 960 if (ctx->EvalMap.Map1Texture4.Points 961 && !ctx->EvalMap.Map1Texture4.Retain) { 962 free( ctx->EvalMap.Map1Texture4.Points ); 963 } 964 ctx->EvalMap.Map1Texture4.Points = (GLfloat *) points; 965 ctx->EvalMap.Map1Texture4.Retain = retain; 966 break; 967 default: 968 gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); 969 } 970} 971 972 973 974 975/* 976 * Note that the array of control points must be 'unpacked' at this time. 977 * Input: retain - if TRUE, this control point data is also in a display 978 * list and can't be freed until the list is freed. 979 */ 980void gl_Map2f( GLcontext* ctx, GLenum target, 981 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, 982 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, 983 const GLfloat *points, GLboolean retain ) 984{ 985 GLint k; 986 987 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap2"); 988 989 if (u1==u2) { 990 gl_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" ); 991 return; 992 } 993 994 if (v1==v2) { 995 gl_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" ); 996 return; 997 } 998 999 if (uorder<1 || uorder>MAX_EVAL_ORDER) { 1000 gl_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" ); 1001 return; 1002 } 1003 1004 if (vorder<1 || vorder>MAX_EVAL_ORDER) { 1005 gl_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" ); 1006 return; 1007 } 1008 1009 k = components( target ); 1010 if (k==0) { 1011 gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); 1012 } 1013 1014 if (ustride < k) { 1015 gl_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" ); 1016 return; 1017 } 1018 if (vstride < k) { 1019 gl_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" ); 1020 return; 1021 } 1022 1023 switch (target) { 1024 case GL_MAP2_VERTEX_3: 1025 ctx->EvalMap.Map2Vertex3.Uorder = uorder; 1026 ctx->EvalMap.Map2Vertex3.u1 = u1; 1027 ctx->EvalMap.Map2Vertex3.u2 = u2; 1028 ctx->EvalMap.Map2Vertex3.du = 1.0 / (u2 - u1); 1029 ctx->EvalMap.Map2Vertex3.Vorder = vorder; 1030 ctx->EvalMap.Map2Vertex3.v1 = v1; 1031 ctx->EvalMap.Map2Vertex3.v2 = v2; 1032 ctx->EvalMap.Map2Vertex3.dv = 1.0 / (v2 - v1); 1033 if (ctx->EvalMap.Map2Vertex3.Points 1034 && !ctx->EvalMap.Map2Vertex3.Retain) { 1035 free( ctx->EvalMap.Map2Vertex3.Points ); 1036 } 1037 ctx->EvalMap.Map2Vertex3.Retain = retain; 1038 ctx->EvalMap.Map2Vertex3.Points = (GLfloat *) points; 1039 break; 1040 case GL_MAP2_VERTEX_4: 1041 ctx->EvalMap.Map2Vertex4.Uorder = uorder; 1042 ctx->EvalMap.Map2Vertex4.u1 = u1; 1043 ctx->EvalMap.Map2Vertex4.u2 = u2; 1044 ctx->EvalMap.Map2Vertex4.du = 1.0 / (u2 - u1); 1045 ctx->EvalMap.Map2Vertex4.Vorder = vorder; 1046 ctx->EvalMap.Map2Vertex4.v1 = v1; 1047 ctx->EvalMap.Map2Vertex4.v2 = v2; 1048 ctx->EvalMap.Map2Vertex4.dv = 1.0 / (v2 - v1); 1049 if (ctx->EvalMap.Map2Vertex4.Points 1050 && !ctx->EvalMap.Map2Vertex4.Retain) { 1051 free( ctx->EvalMap.Map2Vertex4.Points ); 1052 } 1053 ctx->EvalMap.Map2Vertex4.Points = (GLfloat *) points; 1054 ctx->EvalMap.Map2Vertex4.Retain = retain; 1055 break; 1056 case GL_MAP2_INDEX: 1057 ctx->EvalMap.Map2Index.Uorder = uorder; 1058 ctx->EvalMap.Map2Index.u1 = u1; 1059 ctx->EvalMap.Map2Index.u2 = u2; 1060 ctx->EvalMap.Map2Index.du = 1.0 / (u2 - u1); 1061 ctx->EvalMap.Map2Index.Vorder = vorder; 1062 ctx->EvalMap.Map2Index.v1 = v1; 1063 ctx->EvalMap.Map2Index.v2 = v2; 1064 ctx->EvalMap.Map2Index.dv = 1.0 / (v2 - v1); 1065 if (ctx->EvalMap.Map2Index.Points 1066 && !ctx->EvalMap.Map2Index.Retain) { 1067 free( ctx->EvalMap.Map2Index.Points ); 1068 } 1069 ctx->EvalMap.Map2Index.Retain = retain; 1070 ctx->EvalMap.Map2Index.Points = (GLfloat *) points; 1071 break; 1072 case GL_MAP2_COLOR_4: 1073 ctx->EvalMap.Map2Color4.Uorder = uorder; 1074 ctx->EvalMap.Map2Color4.u1 = u1; 1075 ctx->EvalMap.Map2Color4.u2 = u2; 1076 ctx->EvalMap.Map2Color4.du = 1.0 / (u2 - u1); 1077 ctx->EvalMap.Map2Color4.Vorder = vorder; 1078 ctx->EvalMap.Map2Color4.v1 = v1; 1079 ctx->EvalMap.Map2Color4.v2 = v2; 1080 ctx->EvalMap.Map2Color4.dv = 1.0 / (v2 - v1); 1081 if (ctx->EvalMap.Map2Color4.Points 1082 && !ctx->EvalMap.Map2Color4.Retain) { 1083 free( ctx->EvalMap.Map2Color4.Points ); 1084 } 1085 ctx->EvalMap.Map2Color4.Retain = retain; 1086 ctx->EvalMap.Map2Color4.Points = (GLfloat *) points; 1087 break; 1088 case GL_MAP2_NORMAL: 1089 ctx->EvalMap.Map2Normal.Uorder = uorder; 1090 ctx->EvalMap.Map2Normal.u1 = u1; 1091 ctx->EvalMap.Map2Normal.u2 = u2; 1092 ctx->EvalMap.Map2Normal.du = 1.0 / (u2 - u1); 1093 ctx->EvalMap.Map2Normal.Vorder = vorder; 1094 ctx->EvalMap.Map2Normal.v1 = v1; 1095 ctx->EvalMap.Map2Normal.v2 = v2; 1096 ctx->EvalMap.Map2Normal.dv = 1.0 / (v2 - v1); 1097 if (ctx->EvalMap.Map2Normal.Points 1098 && !ctx->EvalMap.Map2Normal.Retain) { 1099 free( ctx->EvalMap.Map2Normal.Points ); 1100 } 1101 ctx->EvalMap.Map2Normal.Retain = retain; 1102 ctx->EvalMap.Map2Normal.Points = (GLfloat *) points; 1103 break; 1104 case GL_MAP2_TEXTURE_COORD_1: 1105 ctx->EvalMap.Map2Texture1.Uorder = uorder; 1106 ctx->EvalMap.Map2Texture1.u1 = u1; 1107 ctx->EvalMap.Map2Texture1.u2 = u2; 1108 ctx->EvalMap.Map2Texture1.du = 1.0 / (u2 - u1); 1109 ctx->EvalMap.Map2Texture1.Vorder = vorder; 1110 ctx->EvalMap.Map2Texture1.v1 = v1; 1111 ctx->EvalMap.Map2Texture1.v2 = v2; 1112 ctx->EvalMap.Map2Texture1.dv = 1.0 / (v2 - v1); 1113 if (ctx->EvalMap.Map2Texture1.Points 1114 && !ctx->EvalMap.Map2Texture1.Retain) { 1115 free( ctx->EvalMap.Map2Texture1.Points ); 1116 } 1117 ctx->EvalMap.Map2Texture1.Retain = retain; 1118 ctx->EvalMap.Map2Texture1.Points = (GLfloat *) points; 1119 break; 1120 case GL_MAP2_TEXTURE_COORD_2: 1121 ctx->EvalMap.Map2Texture2.Uorder = uorder; 1122 ctx->EvalMap.Map2Texture2.u1 = u1; 1123 ctx->EvalMap.Map2Texture2.u2 = u2; 1124 ctx->EvalMap.Map2Texture2.du = 1.0 / (u2 - u1); 1125 ctx->EvalMap.Map2Texture2.Vorder = vorder; 1126 ctx->EvalMap.Map2Texture2.v1 = v1; 1127 ctx->EvalMap.Map2Texture2.v2 = v2; 1128 ctx->EvalMap.Map2Texture2.dv = 1.0 / (v2 - v1); 1129 if (ctx->EvalMap.Map2Texture2.Points 1130 && !ctx->EvalMap.Map2Texture2.Retain) { 1131 free( ctx->EvalMap.Map2Texture2.Points ); 1132 } 1133 ctx->EvalMap.Map2Texture2.Retain = retain; 1134 ctx->EvalMap.Map2Texture2.Points = (GLfloat *) points; 1135 break; 1136 case GL_MAP2_TEXTURE_COORD_3: 1137 ctx->EvalMap.Map2Texture3.Uorder = uorder; 1138 ctx->EvalMap.Map2Texture3.u1 = u1; 1139 ctx->EvalMap.Map2Texture3.u2 = u2; 1140 ctx->EvalMap.Map2Texture3.du = 1.0 / (u2 - u1); 1141 ctx->EvalMap.Map2Texture3.Vorder = vorder; 1142 ctx->EvalMap.Map2Texture3.v1 = v1; 1143 ctx->EvalMap.Map2Texture3.v2 = v2; 1144 ctx->EvalMap.Map2Texture3.dv = 1.0 / (v2 - v1); 1145 if (ctx->EvalMap.Map2Texture3.Points 1146 && !ctx->EvalMap.Map2Texture3.Retain) { 1147 free( ctx->EvalMap.Map2Texture3.Points ); 1148 } 1149 ctx->EvalMap.Map2Texture3.Retain = retain; 1150 ctx->EvalMap.Map2Texture3.Points = (GLfloat *) points; 1151 break; 1152 case GL_MAP2_TEXTURE_COORD_4: 1153 ctx->EvalMap.Map2Texture4.Uorder = uorder; 1154 ctx->EvalMap.Map2Texture4.u1 = u1; 1155 ctx->EvalMap.Map2Texture4.u2 = u2; 1156 ctx->EvalMap.Map2Texture4.du = 1.0 / (u2 - u1); 1157 ctx->EvalMap.Map2Texture4.Vorder = vorder; 1158 ctx->EvalMap.Map2Texture4.v1 = v1; 1159 ctx->EvalMap.Map2Texture4.v2 = v2; 1160 ctx->EvalMap.Map2Texture4.dv = 1.0 / (v2 - v1); 1161 if (ctx->EvalMap.Map2Texture4.Points 1162 && !ctx->EvalMap.Map2Texture4.Retain) { 1163 free( ctx->EvalMap.Map2Texture4.Points ); 1164 } 1165 ctx->EvalMap.Map2Texture4.Retain = retain; 1166 ctx->EvalMap.Map2Texture4.Points = (GLfloat *) points; 1167 break; 1168 default: 1169 gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); 1170 } 1171} 1172 1173 1174 1175 1176 1177void gl_GetMapdv( GLcontext* ctx, GLenum target, GLenum query, GLdouble *v ) 1178{ 1179 GLint i, n; 1180 GLfloat *data; 1181 1182 switch (query) { 1183 case GL_COEFF: 1184 switch (target) { 1185 case GL_MAP1_COLOR_4: 1186 data = ctx->EvalMap.Map1Color4.Points; 1187 n = ctx->EvalMap.Map1Color4.Order * 4; 1188 break; 1189 case GL_MAP1_INDEX: 1190 data = ctx->EvalMap.Map1Index.Points; 1191 n = ctx->EvalMap.Map1Index.Order; 1192 break; 1193 case GL_MAP1_NORMAL: 1194 data = ctx->EvalMap.Map1Normal.Points; 1195 n = ctx->EvalMap.Map1Normal.Order * 3; 1196 break; 1197 case GL_MAP1_TEXTURE_COORD_1: 1198 data = ctx->EvalMap.Map1Texture1.Points; 1199 n = ctx->EvalMap.Map1Texture1.Order * 1; 1200 break; 1201 case GL_MAP1_TEXTURE_COORD_2: 1202 data = ctx->EvalMap.Map1Texture2.Points; 1203 n = ctx->EvalMap.Map1Texture2.Order * 2; 1204 break; 1205 case GL_MAP1_TEXTURE_COORD_3: 1206 data = ctx->EvalMap.Map1Texture3.Points; 1207 n = ctx->EvalMap.Map1Texture3.Order * 3; 1208 break; 1209 case GL_MAP1_TEXTURE_COORD_4: 1210 data = ctx->EvalMap.Map1Texture4.Points; 1211 n = ctx->EvalMap.Map1Texture4.Order * 4; 1212 break; 1213 case GL_MAP1_VERTEX_3: 1214 data = ctx->EvalMap.Map1Vertex3.Points; 1215 n = ctx->EvalMap.Map1Vertex3.Order * 3; 1216 break; 1217 case GL_MAP1_VERTEX_4: 1218 data = ctx->EvalMap.Map1Vertex4.Points; 1219 n = ctx->EvalMap.Map1Vertex4.Order * 4; 1220 break; 1221 case GL_MAP2_COLOR_4: 1222 data = ctx->EvalMap.Map2Color4.Points; 1223 n = ctx->EvalMap.Map2Color4.Uorder 1224 * ctx->EvalMap.Map2Color4.Vorder * 4; 1225 break; 1226 case GL_MAP2_INDEX: 1227 data = ctx->EvalMap.Map2Index.Points; 1228 n = ctx->EvalMap.Map2Index.Uorder 1229 * ctx->EvalMap.Map2Index.Vorder; 1230 break; 1231 case GL_MAP2_NORMAL: 1232 data = ctx->EvalMap.Map2Normal.Points; 1233 n = ctx->EvalMap.Map2Normal.Uorder 1234 * ctx->EvalMap.Map2Normal.Vorder * 3; 1235 break; 1236 case GL_MAP2_TEXTURE_COORD_1: 1237 data = ctx->EvalMap.Map2Texture1.Points; 1238 n = ctx->EvalMap.Map2Texture1.Uorder 1239 * ctx->EvalMap.Map2Texture1.Vorder * 1; 1240 break; 1241 case GL_MAP2_TEXTURE_COORD_2: 1242 data = ctx->EvalMap.Map2Texture2.Points; 1243 n = ctx->EvalMap.Map2Texture2.Uorder 1244 * ctx->EvalMap.Map2Texture2.Vorder * 2; 1245 break; 1246 case GL_MAP2_TEXTURE_COORD_3: 1247 data = ctx->EvalMap.Map2Texture3.Points; 1248 n = ctx->EvalMap.Map2Texture3.Uorder 1249 * ctx->EvalMap.Map2Texture3.Vorder * 3; 1250 break; 1251 case GL_MAP2_TEXTURE_COORD_4: 1252 data = ctx->EvalMap.Map2Texture4.Points; 1253 n = ctx->EvalMap.Map2Texture4.Uorder 1254 * ctx->EvalMap.Map2Texture4.Vorder * 4; 1255 break; 1256 case GL_MAP2_VERTEX_3: 1257 data = ctx->EvalMap.Map2Vertex3.Points; 1258 n = ctx->EvalMap.Map2Vertex3.Uorder 1259 * ctx->EvalMap.Map2Vertex3.Vorder * 3; 1260 break; 1261 case GL_MAP2_VERTEX_4: 1262 data = ctx->EvalMap.Map2Vertex4.Points; 1263 n = ctx->EvalMap.Map2Vertex4.Uorder 1264 * ctx->EvalMap.Map2Vertex4.Vorder * 4; 1265 break; 1266 default: 1267 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); 1268 return; 1269 } 1270 if (data) { 1271 for (i=0;i<n;i++) { 1272 v[i] = data[i]; 1273 } 1274 } 1275 break; 1276 case GL_ORDER: 1277 switch (target) { 1278 case GL_MAP1_COLOR_4: 1279 *v = ctx->EvalMap.Map1Color4.Order; 1280 break; 1281 case GL_MAP1_INDEX: 1282 *v = ctx->EvalMap.Map1Index.Order; 1283 break; 1284 case GL_MAP1_NORMAL: 1285 *v = ctx->EvalMap.Map1Normal.Order; 1286 break; 1287 case GL_MAP1_TEXTURE_COORD_1: 1288 *v = ctx->EvalMap.Map1Texture1.Order; 1289 break; 1290 case GL_MAP1_TEXTURE_COORD_2: 1291 *v = ctx->EvalMap.Map1Texture2.Order; 1292 break; 1293 case GL_MAP1_TEXTURE_COORD_3: 1294 *v = ctx->EvalMap.Map1Texture3.Order; 1295 break; 1296 case GL_MAP1_TEXTURE_COORD_4: 1297 *v = ctx->EvalMap.Map1Texture4.Order; 1298 break; 1299 case GL_MAP1_VERTEX_3: 1300 *v = ctx->EvalMap.Map1Vertex3.Order; 1301 break; 1302 case GL_MAP1_VERTEX_4: 1303 *v = ctx->EvalMap.Map1Vertex4.Order; 1304 break; 1305 case GL_MAP2_COLOR_4: 1306 v[0] = ctx->EvalMap.Map2Color4.Uorder; 1307 v[1] = ctx->EvalMap.Map2Color4.Vorder; 1308 break; 1309 case GL_MAP2_INDEX: 1310 v[0] = ctx->EvalMap.Map2Index.Uorder; 1311 v[1] = ctx->EvalMap.Map2Index.Vorder; 1312 break; 1313 case GL_MAP2_NORMAL: 1314 v[0] = ctx->EvalMap.Map2Normal.Uorder; 1315 v[1] = ctx->EvalMap.Map2Normal.Vorder; 1316 break; 1317 case GL_MAP2_TEXTURE_COORD_1: 1318 v[0] = ctx->EvalMap.Map2Texture1.Uorder; 1319 v[1] = ctx->EvalMap.Map2Texture1.Vorder; 1320 break; 1321 case GL_MAP2_TEXTURE_COORD_2: 1322 v[0] = ctx->EvalMap.Map2Texture2.Uorder; 1323 v[1] = ctx->EvalMap.Map2Texture2.Vorder; 1324 break; 1325 case GL_MAP2_TEXTURE_COORD_3: 1326 v[0] = ctx->EvalMap.Map2Texture3.Uorder; 1327 v[1] = ctx->EvalMap.Map2Texture3.Vorder; 1328 break; 1329 case GL_MAP2_TEXTURE_COORD_4: 1330 v[0] = ctx->EvalMap.Map2Texture4.Uorder; 1331 v[1] = ctx->EvalMap.Map2Texture4.Vorder; 1332 break; 1333 case GL_MAP2_VERTEX_3: 1334 v[0] = ctx->EvalMap.Map2Vertex3.Uorder; 1335 v[1] = ctx->EvalMap.Map2Vertex3.Vorder; 1336 break; 1337 case GL_MAP2_VERTEX_4: 1338 v[0] = ctx->EvalMap.Map2Vertex4.Uorder; 1339 v[1] = ctx->EvalMap.Map2Vertex4.Vorder; 1340 break; 1341 default: 1342 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); 1343 return; 1344 } 1345 break; 1346 case GL_DOMAIN: 1347 switch (target) { 1348 case GL_MAP1_COLOR_4: 1349 v[0] = ctx->EvalMap.Map1Color4.u1; 1350 v[1] = ctx->EvalMap.Map1Color4.u2; 1351 break; 1352 case GL_MAP1_INDEX: 1353 v[0] = ctx->EvalMap.Map1Index.u1; 1354 v[1] = ctx->EvalMap.Map1Index.u2; 1355 break; 1356 case GL_MAP1_NORMAL: 1357 v[0] = ctx->EvalMap.Map1Normal.u1; 1358 v[1] = ctx->EvalMap.Map1Normal.u2; 1359 break; 1360 case GL_MAP1_TEXTURE_COORD_1: 1361 v[0] = ctx->EvalMap.Map1Texture1.u1; 1362 v[1] = ctx->EvalMap.Map1Texture1.u2; 1363 break; 1364 case GL_MAP1_TEXTURE_COORD_2: 1365 v[0] = ctx->EvalMap.Map1Texture2.u1; 1366 v[1] = ctx->EvalMap.Map1Texture2.u2; 1367 break; 1368 case GL_MAP1_TEXTURE_COORD_3: 1369 v[0] = ctx->EvalMap.Map1Texture3.u1; 1370 v[1] = ctx->EvalMap.Map1Texture3.u2; 1371 break; 1372 case GL_MAP1_TEXTURE_COORD_4: 1373 v[0] = ctx->EvalMap.Map1Texture4.u1; 1374 v[1] = ctx->EvalMap.Map1Texture4.u2; 1375 break; 1376 case GL_MAP1_VERTEX_3: 1377 v[0] = ctx->EvalMap.Map1Vertex3.u1; 1378 v[1] = ctx->EvalMap.Map1Vertex3.u2; 1379 break; 1380 case GL_MAP1_VERTEX_4: 1381 v[0] = ctx->EvalMap.Map1Vertex4.u1; 1382 v[1] = ctx->EvalMap.Map1Vertex4.u2; 1383 break; 1384 case GL_MAP2_COLOR_4: 1385 v[0] = ctx->EvalMap.Map2Color4.u1; 1386 v[1] = ctx->EvalMap.Map2Color4.u2; 1387 v[2] = ctx->EvalMap.Map2Color4.v1; 1388 v[3] = ctx->EvalMap.Map2Color4.v2; 1389 break; 1390 case GL_MAP2_INDEX: 1391 v[0] = ctx->EvalMap.Map2Index.u1; 1392 v[1] = ctx->EvalMap.Map2Index.u2; 1393 v[2] = ctx->EvalMap.Map2Index.v1; 1394 v[3] = ctx->EvalMap.Map2Index.v2; 1395 break; 1396 case GL_MAP2_NORMAL: 1397 v[0] = ctx->EvalMap.Map2Normal.u1; 1398 v[1] = ctx->EvalMap.Map2Normal.u2; 1399 v[2] = ctx->EvalMap.Map2Normal.v1; 1400 v[3] = ctx->EvalMap.Map2Normal.v2; 1401 break; 1402 case GL_MAP2_TEXTURE_COORD_1: 1403 v[0] = ctx->EvalMap.Map2Texture1.u1; 1404 v[1] = ctx->EvalMap.Map2Texture1.u2; 1405 v[2] = ctx->EvalMap.Map2Texture1.v1; 1406 v[3] = ctx->EvalMap.Map2Texture1.v2; 1407 break; 1408 case GL_MAP2_TEXTURE_COORD_2: 1409 v[0] = ctx->EvalMap.Map2Texture2.u1; 1410 v[1] = ctx->EvalMap.Map2Texture2.u2; 1411 v[2] = ctx->EvalMap.Map2Texture2.v1; 1412 v[3] = ctx->EvalMap.Map2Texture2.v2; 1413 break; 1414 case GL_MAP2_TEXTURE_COORD_3: 1415 v[0] = ctx->EvalMap.Map2Texture3.u1; 1416 v[1] = ctx->EvalMap.Map2Texture3.u2; 1417 v[2] = ctx->EvalMap.Map2Texture3.v1; 1418 v[3] = ctx->EvalMap.Map2Texture3.v2; 1419 break; 1420 case GL_MAP2_TEXTURE_COORD_4: 1421 v[0] = ctx->EvalMap.Map2Texture4.u1; 1422 v[1] = ctx->EvalMap.Map2Texture4.u2; 1423 v[2] = ctx->EvalMap.Map2Texture4.v1; 1424 v[3] = ctx->EvalMap.Map2Texture4.v2; 1425 break; 1426 case GL_MAP2_VERTEX_3: 1427 v[0] = ctx->EvalMap.Map2Vertex3.u1; 1428 v[1] = ctx->EvalMap.Map2Vertex3.u2; 1429 v[2] = ctx->EvalMap.Map2Vertex3.v1; 1430 v[3] = ctx->EvalMap.Map2Vertex3.v2; 1431 break; 1432 case GL_MAP2_VERTEX_4: 1433 v[0] = ctx->EvalMap.Map2Vertex4.u1; 1434 v[1] = ctx->EvalMap.Map2Vertex4.u2; 1435 v[2] = ctx->EvalMap.Map2Vertex4.v1; 1436 v[3] = ctx->EvalMap.Map2Vertex4.v2; 1437 break; 1438 default: 1439 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); 1440 } 1441 break; 1442 default: 1443 gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" ); 1444 } 1445} 1446 1447 1448void gl_GetMapfv( GLcontext* ctx, GLenum target, GLenum query, GLfloat *v ) 1449{ 1450 GLint i, n; 1451 GLfloat *data; 1452 1453 switch (query) { 1454 case GL_COEFF: 1455 switch (target) { 1456 case GL_MAP1_COLOR_4: 1457 data = ctx->EvalMap.Map1Color4.Points; 1458 n = ctx->EvalMap.Map1Color4.Order * 4; 1459 break; 1460 case GL_MAP1_INDEX: 1461 data = ctx->EvalMap.Map1Index.Points; 1462 n = ctx->EvalMap.Map1Index.Order; 1463 break; 1464 case GL_MAP1_NORMAL: 1465 data = ctx->EvalMap.Map1Normal.Points; 1466 n = ctx->EvalMap.Map1Normal.Order * 3; 1467 break; 1468 case GL_MAP1_TEXTURE_COORD_1: 1469 data = ctx->EvalMap.Map1Texture1.Points; 1470 n = ctx->EvalMap.Map1Texture1.Order * 1; 1471 break; 1472 case GL_MAP1_TEXTURE_COORD_2: 1473 data = ctx->EvalMap.Map1Texture2.Points; 1474 n = ctx->EvalMap.Map1Texture2.Order * 2; 1475 break; 1476 case GL_MAP1_TEXTURE_COORD_3: 1477 data = ctx->EvalMap.Map1Texture3.Points; 1478 n = ctx->EvalMap.Map1Texture3.Order * 3; 1479 break; 1480 case GL_MAP1_TEXTURE_COORD_4: 1481 data = ctx->EvalMap.Map1Texture4.Points; 1482 n = ctx->EvalMap.Map1Texture4.Order * 4; 1483 break; 1484 case GL_MAP1_VERTEX_3: 1485 data = ctx->EvalMap.Map1Vertex3.Points; 1486 n = ctx->EvalMap.Map1Vertex3.Order * 3; 1487 break; 1488 case GL_MAP1_VERTEX_4: 1489 data = ctx->EvalMap.Map1Vertex4.Points; 1490 n = ctx->EvalMap.Map1Vertex4.Order * 4; 1491 break; 1492 case GL_MAP2_COLOR_4: 1493 data = ctx->EvalMap.Map2Color4.Points; 1494 n = ctx->EvalMap.Map2Color4.Uorder 1495 * ctx->EvalMap.Map2Color4.Vorder * 4; 1496 break; 1497 case GL_MAP2_INDEX: 1498 data = ctx->EvalMap.Map2Index.Points; 1499 n = ctx->EvalMap.Map2Index.Uorder 1500 * ctx->EvalMap.Map2Index.Vorder; 1501 break; 1502 case GL_MAP2_NORMAL: 1503 data = ctx->EvalMap.Map2Normal.Points; 1504 n = ctx->EvalMap.Map2Normal.Uorder 1505 * ctx->EvalMap.Map2Normal.Vorder * 3; 1506 break; 1507 case GL_MAP2_TEXTURE_COORD_1: 1508 data = ctx->EvalMap.Map2Texture1.Points; 1509 n = ctx->EvalMap.Map2Texture1.Uorder 1510 * ctx->EvalMap.Map2Texture1.Vorder * 1; 1511 break; 1512 case GL_MAP2_TEXTURE_COORD_2: 1513 data = ctx->EvalMap.Map2Texture2.Points; 1514 n = ctx->EvalMap.Map2Texture2.Uorder 1515 * ctx->EvalMap.Map2Texture2.Vorder * 2; 1516 break; 1517 case GL_MAP2_TEXTURE_COORD_3: 1518 data = ctx->EvalMap.Map2Texture3.Points; 1519 n = ctx->EvalMap.Map2Texture3.Uorder 1520 * ctx->EvalMap.Map2Texture3.Vorder * 3; 1521 break; 1522 case GL_MAP2_TEXTURE_COORD_4: 1523 data = ctx->EvalMap.Map2Texture4.Points; 1524 n = ctx->EvalMap.Map2Texture4.Uorder 1525 * ctx->EvalMap.Map2Texture4.Vorder * 4; 1526 break; 1527 case GL_MAP2_VERTEX_3: 1528 data = ctx->EvalMap.Map2Vertex3.Points; 1529 n = ctx->EvalMap.Map2Vertex3.Uorder 1530 * ctx->EvalMap.Map2Vertex3.Vorder * 3; 1531 break; 1532 case GL_MAP2_VERTEX_4: 1533 data = ctx->EvalMap.Map2Vertex4.Points; 1534 n = ctx->EvalMap.Map2Vertex4.Uorder 1535 * ctx->EvalMap.Map2Vertex4.Vorder * 4; 1536 break; 1537 default: 1538 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); 1539 return; 1540 } 1541 if (data) { 1542 for (i=0;i<n;i++) { 1543 v[i] = data[i]; 1544 } 1545 } 1546 break; 1547 case GL_ORDER: 1548 switch (target) { 1549 case GL_MAP1_COLOR_4: 1550 *v = ctx->EvalMap.Map1Color4.Order; 1551 break; 1552 case GL_MAP1_INDEX: 1553 *v = ctx->EvalMap.Map1Index.Order; 1554 break; 1555 case GL_MAP1_NORMAL: 1556 *v = ctx->EvalMap.Map1Normal.Order; 1557 break; 1558 case GL_MAP1_TEXTURE_COORD_1: 1559 *v = ctx->EvalMap.Map1Texture1.Order; 1560 break; 1561 case GL_MAP1_TEXTURE_COORD_2: 1562 *v = ctx->EvalMap.Map1Texture2.Order; 1563 break; 1564 case GL_MAP1_TEXTURE_COORD_3: 1565 *v = ctx->EvalMap.Map1Texture3.Order; 1566 break; 1567 case GL_MAP1_TEXTURE_COORD_4: 1568 *v = ctx->EvalMap.Map1Texture4.Order; 1569 break; 1570 case GL_MAP1_VERTEX_3: 1571 *v = ctx->EvalMap.Map1Vertex3.Order; 1572 break; 1573 case GL_MAP1_VERTEX_4: 1574 *v = ctx->EvalMap.Map1Vertex4.Order; 1575 break; 1576 case GL_MAP2_COLOR_4: 1577 v[0] = ctx->EvalMap.Map2Color4.Uorder; 1578 v[1] = ctx->EvalMap.Map2Color4.Vorder; 1579 break; 1580 case GL_MAP2_INDEX: 1581 v[0] = ctx->EvalMap.Map2Index.Uorder; 1582 v[1] = ctx->EvalMap.Map2Index.Vorder; 1583 break; 1584 case GL_MAP2_NORMAL: 1585 v[0] = ctx->EvalMap.Map2Normal.Uorder; 1586 v[1] = ctx->EvalMap.Map2Normal.Vorder; 1587 break; 1588 case GL_MAP2_TEXTURE_COORD_1: 1589 v[0] = ctx->EvalMap.Map2Texture1.Uorder; 1590 v[1] = ctx->EvalMap.Map2Texture1.Vorder; 1591 break; 1592 case GL_MAP2_TEXTURE_COORD_2: 1593 v[0] = ctx->EvalMap.Map2Texture2.Uorder; 1594 v[1] = ctx->EvalMap.Map2Texture2.Vorder; 1595 break; 1596 case GL_MAP2_TEXTURE_COORD_3: 1597 v[0] = ctx->EvalMap.Map2Texture3.Uorder; 1598 v[1] = ctx->EvalMap.Map2Texture3.Vorder; 1599 break; 1600 case GL_MAP2_TEXTURE_COORD_4: 1601 v[0] = ctx->EvalMap.Map2Texture4.Uorder; 1602 v[1] = ctx->EvalMap.Map2Texture4.Vorder; 1603 break; 1604 case GL_MAP2_VERTEX_3: 1605 v[0] = ctx->EvalMap.Map2Vertex3.Uorder; 1606 v[1] = ctx->EvalMap.Map2Vertex3.Vorder; 1607 break; 1608 case GL_MAP2_VERTEX_4: 1609 v[0] = ctx->EvalMap.Map2Vertex4.Uorder; 1610 v[1] = ctx->EvalMap.Map2Vertex4.Vorder; 1611 break; 1612 default: 1613 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); 1614 return; 1615 } 1616 break; 1617 case GL_DOMAIN: 1618 switch (target) { 1619 case GL_MAP1_COLOR_4: 1620 v[0] = ctx->EvalMap.Map1Color4.u1; 1621 v[1] = ctx->EvalMap.Map1Color4.u2; 1622 break; 1623 case GL_MAP1_INDEX: 1624 v[0] = ctx->EvalMap.Map1Index.u1; 1625 v[1] = ctx->EvalMap.Map1Index.u2; 1626 break; 1627 case GL_MAP1_NORMAL: 1628 v[0] = ctx->EvalMap.Map1Normal.u1; 1629 v[1] = ctx->EvalMap.Map1Normal.u2; 1630 break; 1631 case GL_MAP1_TEXTURE_COORD_1: 1632 v[0] = ctx->EvalMap.Map1Texture1.u1; 1633 v[1] = ctx->EvalMap.Map1Texture1.u2; 1634 break; 1635 case GL_MAP1_TEXTURE_COORD_2: 1636 v[0] = ctx->EvalMap.Map1Texture2.u1; 1637 v[1] = ctx->EvalMap.Map1Texture2.u2; 1638 break; 1639 case GL_MAP1_TEXTURE_COORD_3: 1640 v[0] = ctx->EvalMap.Map1Texture3.u1; 1641 v[1] = ctx->EvalMap.Map1Texture3.u2; 1642 break; 1643 case GL_MAP1_TEXTURE_COORD_4: 1644 v[0] = ctx->EvalMap.Map1Texture4.u1; 1645 v[1] = ctx->EvalMap.Map1Texture4.u2; 1646 break; 1647 case GL_MAP1_VERTEX_3: 1648 v[0] = ctx->EvalMap.Map1Vertex3.u1; 1649 v[1] = ctx->EvalMap.Map1Vertex3.u2; 1650 break; 1651 case GL_MAP1_VERTEX_4: 1652 v[0] = ctx->EvalMap.Map1Vertex4.u1; 1653 v[1] = ctx->EvalMap.Map1Vertex4.u2; 1654 break; 1655 case GL_MAP2_COLOR_4: 1656 v[0] = ctx->EvalMap.Map2Color4.u1; 1657 v[1] = ctx->EvalMap.Map2Color4.u2; 1658 v[2] = ctx->EvalMap.Map2Color4.v1; 1659 v[3] = ctx->EvalMap.Map2Color4.v2; 1660 break; 1661 case GL_MAP2_INDEX: 1662 v[0] = ctx->EvalMap.Map2Index.u1; 1663 v[1] = ctx->EvalMap.Map2Index.u2; 1664 v[2] = ctx->EvalMap.Map2Index.v1; 1665 v[3] = ctx->EvalMap.Map2Index.v2; 1666 break; 1667 case GL_MAP2_NORMAL: 1668 v[0] = ctx->EvalMap.Map2Normal.u1; 1669 v[1] = ctx->EvalMap.Map2Normal.u2; 1670 v[2] = ctx->EvalMap.Map2Normal.v1; 1671 v[3] = ctx->EvalMap.Map2Normal.v2; 1672 break; 1673 case GL_MAP2_TEXTURE_COORD_1: 1674 v[0] = ctx->EvalMap.Map2Texture1.u1; 1675 v[1] = ctx->EvalMap.Map2Texture1.u2; 1676 v[2] = ctx->EvalMap.Map2Texture1.v1; 1677 v[3] = ctx->EvalMap.Map2Texture1.v2; 1678 break; 1679 case GL_MAP2_TEXTURE_COORD_2: 1680 v[0] = ctx->EvalMap.Map2Texture2.u1; 1681 v[1] = ctx->EvalMap.Map2Texture2.u2; 1682 v[2] = ctx->EvalMap.Map2Texture2.v1; 1683 v[3] = ctx->EvalMap.Map2Texture2.v2; 1684 break; 1685 case GL_MAP2_TEXTURE_COORD_3: 1686 v[0] = ctx->EvalMap.Map2Texture3.u1; 1687 v[1] = ctx->EvalMap.Map2Texture3.u2; 1688 v[2] = ctx->EvalMap.Map2Texture3.v1; 1689 v[3] = ctx->EvalMap.Map2Texture3.v2; 1690 break; 1691 case GL_MAP2_TEXTURE_COORD_4: 1692 v[0] = ctx->EvalMap.Map2Texture4.u1; 1693 v[1] = ctx->EvalMap.Map2Texture4.u2; 1694 v[2] = ctx->EvalMap.Map2Texture4.v1; 1695 v[3] = ctx->EvalMap.Map2Texture4.v2; 1696 break; 1697 case GL_MAP2_VERTEX_3: 1698 v[0] = ctx->EvalMap.Map2Vertex3.u1; 1699 v[1] = ctx->EvalMap.Map2Vertex3.u2; 1700 v[2] = ctx->EvalMap.Map2Vertex3.v1; 1701 v[3] = ctx->EvalMap.Map2Vertex3.v2; 1702 break; 1703 case GL_MAP2_VERTEX_4: 1704 v[0] = ctx->EvalMap.Map2Vertex4.u1; 1705 v[1] = ctx->EvalMap.Map2Vertex4.u2; 1706 v[2] = ctx->EvalMap.Map2Vertex4.v1; 1707 v[3] = ctx->EvalMap.Map2Vertex4.v2; 1708 break; 1709 default: 1710 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); 1711 } 1712 break; 1713 default: 1714 gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" ); 1715 } 1716} 1717 1718 1719void gl_GetMapiv( GLcontext* ctx, GLenum target, GLenum query, GLint *v ) 1720{ 1721 GLuint i, n; 1722 GLfloat *data; 1723 1724 switch (query) { 1725 case GL_COEFF: 1726 switch (target) { 1727 case GL_MAP1_COLOR_4: 1728 data = ctx->EvalMap.Map1Color4.Points; 1729 n = ctx->EvalMap.Map1Color4.Order * 4; 1730 break; 1731 case GL_MAP1_INDEX: 1732 data = ctx->EvalMap.Map1Index.Points; 1733 n = ctx->EvalMap.Map1Index.Order; 1734 break; 1735 case GL_MAP1_NORMAL: 1736 data = ctx->EvalMap.Map1Normal.Points; 1737 n = ctx->EvalMap.Map1Normal.Order * 3; 1738 break; 1739 case GL_MAP1_TEXTURE_COORD_1: 1740 data = ctx->EvalMap.Map1Texture1.Points; 1741 n = ctx->EvalMap.Map1Texture1.Order * 1; 1742 break; 1743 case GL_MAP1_TEXTURE_COORD_2: 1744 data = ctx->EvalMap.Map1Texture2.Points; 1745 n = ctx->EvalMap.Map1Texture2.Order * 2; 1746 break; 1747 case GL_MAP1_TEXTURE_COORD_3: 1748 data = ctx->EvalMap.Map1Texture3.Points; 1749 n = ctx->EvalMap.Map1Texture3.Order * 3; 1750 break; 1751 case GL_MAP1_TEXTURE_COORD_4: 1752 data = ctx->EvalMap.Map1Texture4.Points; 1753 n = ctx->EvalMap.Map1Texture4.Order * 4; 1754 break; 1755 case GL_MAP1_VERTEX_3: 1756 data = ctx->EvalMap.Map1Vertex3.Points; 1757 n = ctx->EvalMap.Map1Vertex3.Order * 3; 1758 break; 1759 case GL_MAP1_VERTEX_4: 1760 data = ctx->EvalMap.Map1Vertex4.Points; 1761 n = ctx->EvalMap.Map1Vertex4.Order * 4; 1762 break; 1763 case GL_MAP2_COLOR_4: 1764 data = ctx->EvalMap.Map2Color4.Points; 1765 n = ctx->EvalMap.Map2Color4.Uorder 1766 * ctx->EvalMap.Map2Color4.Vorder * 4; 1767 break; 1768 case GL_MAP2_INDEX: 1769 data = ctx->EvalMap.Map2Index.Points; 1770 n = ctx->EvalMap.Map2Index.Uorder 1771 * ctx->EvalMap.Map2Index.Vorder; 1772 break; 1773 case GL_MAP2_NORMAL: 1774 data = ctx->EvalMap.Map2Normal.Points; 1775 n = ctx->EvalMap.Map2Normal.Uorder 1776 * ctx->EvalMap.Map2Normal.Vorder * 3; 1777 break; 1778 case GL_MAP2_TEXTURE_COORD_1: 1779 data = ctx->EvalMap.Map2Texture1.Points; 1780 n = ctx->EvalMap.Map2Texture1.Uorder 1781 * ctx->EvalMap.Map2Texture1.Vorder * 1; 1782 break; 1783 case GL_MAP2_TEXTURE_COORD_2: 1784 data = ctx->EvalMap.Map2Texture2.Points; 1785 n = ctx->EvalMap.Map2Texture2.Uorder 1786 * ctx->EvalMap.Map2Texture2.Vorder * 2; 1787 break; 1788 case GL_MAP2_TEXTURE_COORD_3: 1789 data = ctx->EvalMap.Map2Texture3.Points; 1790 n = ctx->EvalMap.Map2Texture3.Uorder 1791 * ctx->EvalMap.Map2Texture3.Vorder * 3; 1792 break; 1793 case GL_MAP2_TEXTURE_COORD_4: 1794 data = ctx->EvalMap.Map2Texture4.Points; 1795 n = ctx->EvalMap.Map2Texture4.Uorder 1796 * ctx->EvalMap.Map2Texture4.Vorder * 4; 1797 break; 1798 case GL_MAP2_VERTEX_3: 1799 data = ctx->EvalMap.Map2Vertex3.Points; 1800 n = ctx->EvalMap.Map2Vertex3.Uorder 1801 * ctx->EvalMap.Map2Vertex3.Vorder * 3; 1802 break; 1803 case GL_MAP2_VERTEX_4: 1804 data = ctx->EvalMap.Map2Vertex4.Points; 1805 n = ctx->EvalMap.Map2Vertex4.Uorder 1806 * ctx->EvalMap.Map2Vertex4.Vorder * 4; 1807 break; 1808 default: 1809 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); 1810 return; 1811 } 1812 if (data) { 1813 for (i=0;i<n;i++) { 1814 v[i] = ROUNDF(data[i]); 1815 } 1816 } 1817 break; 1818 case GL_ORDER: 1819 switch (target) { 1820 case GL_MAP1_COLOR_4: 1821 *v = ctx->EvalMap.Map1Color4.Order; 1822 break; 1823 case GL_MAP1_INDEX: 1824 *v = ctx->EvalMap.Map1Index.Order; 1825 break; 1826 case GL_MAP1_NORMAL: 1827 *v = ctx->EvalMap.Map1Normal.Order; 1828 break; 1829 case GL_MAP1_TEXTURE_COORD_1: 1830 *v = ctx->EvalMap.Map1Texture1.Order; 1831 break; 1832 case GL_MAP1_TEXTURE_COORD_2: 1833 *v = ctx->EvalMap.Map1Texture2.Order; 1834 break; 1835 case GL_MAP1_TEXTURE_COORD_3: 1836 *v = ctx->EvalMap.Map1Texture3.Order; 1837 break; 1838 case GL_MAP1_TEXTURE_COORD_4: 1839 *v = ctx->EvalMap.Map1Texture4.Order; 1840 break; 1841 case GL_MAP1_VERTEX_3: 1842 *v = ctx->EvalMap.Map1Vertex3.Order; 1843 break; 1844 case GL_MAP1_VERTEX_4: 1845 *v = ctx->EvalMap.Map1Vertex4.Order; 1846 break; 1847 case GL_MAP2_COLOR_4: 1848 v[0] = ctx->EvalMap.Map2Color4.Uorder; 1849 v[1] = ctx->EvalMap.Map2Color4.Vorder; 1850 break; 1851 case GL_MAP2_INDEX: 1852 v[0] = ctx->EvalMap.Map2Index.Uorder; 1853 v[1] = ctx->EvalMap.Map2Index.Vorder; 1854 break; 1855 case GL_MAP2_NORMAL: 1856 v[0] = ctx->EvalMap.Map2Normal.Uorder; 1857 v[1] = ctx->EvalMap.Map2Normal.Vorder; 1858 break; 1859 case GL_MAP2_TEXTURE_COORD_1: 1860 v[0] = ctx->EvalMap.Map2Texture1.Uorder; 1861 v[1] = ctx->EvalMap.Map2Texture1.Vorder; 1862 break; 1863 case GL_MAP2_TEXTURE_COORD_2: 1864 v[0] = ctx->EvalMap.Map2Texture2.Uorder; 1865 v[1] = ctx->EvalMap.Map2Texture2.Vorder; 1866 break; 1867 case GL_MAP2_TEXTURE_COORD_3: 1868 v[0] = ctx->EvalMap.Map2Texture3.Uorder; 1869 v[1] = ctx->EvalMap.Map2Texture3.Vorder; 1870 break; 1871 case GL_MAP2_TEXTURE_COORD_4: 1872 v[0] = ctx->EvalMap.Map2Texture4.Uorder; 1873 v[1] = ctx->EvalMap.Map2Texture4.Vorder; 1874 break; 1875 case GL_MAP2_VERTEX_3: 1876 v[0] = ctx->EvalMap.Map2Vertex3.Uorder; 1877 v[1] = ctx->EvalMap.Map2Vertex3.Vorder; 1878 break; 1879 case GL_MAP2_VERTEX_4: 1880 v[0] = ctx->EvalMap.Map2Vertex4.Uorder; 1881 v[1] = ctx->EvalMap.Map2Vertex4.Vorder; 1882 break; 1883 default: 1884 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); 1885 return; 1886 } 1887 break; 1888 case GL_DOMAIN: 1889 switch (target) { 1890 case GL_MAP1_COLOR_4: 1891 v[0] = ROUNDF(ctx->EvalMap.Map1Color4.u1); 1892 v[1] = ROUNDF(ctx->EvalMap.Map1Color4.u2); 1893 break; 1894 case GL_MAP1_INDEX: 1895 v[0] = ROUNDF(ctx->EvalMap.Map1Index.u1); 1896 v[1] = ROUNDF(ctx->EvalMap.Map1Index.u2); 1897 break; 1898 case GL_MAP1_NORMAL: 1899 v[0] = ROUNDF(ctx->EvalMap.Map1Normal.u1); 1900 v[1] = ROUNDF(ctx->EvalMap.Map1Normal.u2); 1901 break; 1902 case GL_MAP1_TEXTURE_COORD_1: 1903 v[0] = ROUNDF(ctx->EvalMap.Map1Texture1.u1); 1904 v[1] = ROUNDF(ctx->EvalMap.Map1Texture1.u2); 1905 break; 1906 case GL_MAP1_TEXTURE_COORD_2: 1907 v[0] = ROUNDF(ctx->EvalMap.Map1Texture2.u1); 1908 v[1] = ROUNDF(ctx->EvalMap.Map1Texture2.u2); 1909 break; 1910 case GL_MAP1_TEXTURE_COORD_3: 1911 v[0] = ROUNDF(ctx->EvalMap.Map1Texture3.u1); 1912 v[1] = ROUNDF(ctx->EvalMap.Map1Texture3.u2); 1913 break; 1914 case GL_MAP1_TEXTURE_COORD_4: 1915 v[0] = ROUNDF(ctx->EvalMap.Map1Texture4.u1); 1916 v[1] = ROUNDF(ctx->EvalMap.Map1Texture4.u2); 1917 break; 1918 case GL_MAP1_VERTEX_3: 1919 v[0] = ROUNDF(ctx->EvalMap.Map1Vertex3.u1); 1920 v[1] = ROUNDF(ctx->EvalMap.Map1Vertex3.u2); 1921 break; 1922 case GL_MAP1_VERTEX_4: 1923 v[0] = ROUNDF(ctx->EvalMap.Map1Vertex4.u1); 1924 v[1] = ROUNDF(ctx->EvalMap.Map1Vertex4.u2); 1925 break; 1926 case GL_MAP2_COLOR_4: 1927 v[0] = ROUNDF(ctx->EvalMap.Map2Color4.u1); 1928 v[1] = ROUNDF(ctx->EvalMap.Map2Color4.u2); 1929 v[2] = ROUNDF(ctx->EvalMap.Map2Color4.v1); 1930 v[3] = ROUNDF(ctx->EvalMap.Map2Color4.v2); 1931 break; 1932 case GL_MAP2_INDEX: 1933 v[0] = ROUNDF(ctx->EvalMap.Map2Index.u1); 1934 v[1] = ROUNDF(ctx->EvalMap.Map2Index.u2); 1935 v[2] = ROUNDF(ctx->EvalMap.Map2Index.v1); 1936 v[3] = ROUNDF(ctx->EvalMap.Map2Index.v2); 1937 break; 1938 case GL_MAP2_NORMAL: 1939 v[0] = ROUNDF(ctx->EvalMap.Map2Normal.u1); 1940 v[1] = ROUNDF(ctx->EvalMap.Map2Normal.u2); 1941 v[2] = ROUNDF(ctx->EvalMap.Map2Normal.v1); 1942 v[3] = ROUNDF(ctx->EvalMap.Map2Normal.v2); 1943 break; 1944 case GL_MAP2_TEXTURE_COORD_1: 1945 v[0] = ROUNDF(ctx->EvalMap.Map2Texture1.u1); 1946 v[1] = ROUNDF(ctx->EvalMap.Map2Texture1.u2); 1947 v[2] = ROUNDF(ctx->EvalMap.Map2Texture1.v1); 1948 v[3] = ROUNDF(ctx->EvalMap.Map2Texture1.v2); 1949 break; 1950 case GL_MAP2_TEXTURE_COORD_2: 1951 v[0] = ROUNDF(ctx->EvalMap.Map2Texture2.u1); 1952 v[1] = ROUNDF(ctx->EvalMap.Map2Texture2.u2); 1953 v[2] = ROUNDF(ctx->EvalMap.Map2Texture2.v1); 1954 v[3] = ROUNDF(ctx->EvalMap.Map2Texture2.v2); 1955 break; 1956 case GL_MAP2_TEXTURE_COORD_3: 1957 v[0] = ROUNDF(ctx->EvalMap.Map2Texture3.u1); 1958 v[1] = ROUNDF(ctx->EvalMap.Map2Texture3.u2); 1959 v[2] = ROUNDF(ctx->EvalMap.Map2Texture3.v1); 1960 v[3] = ROUNDF(ctx->EvalMap.Map2Texture3.v2); 1961 break; 1962 case GL_MAP2_TEXTURE_COORD_4: 1963 v[0] = ROUNDF(ctx->EvalMap.Map2Texture4.u1); 1964 v[1] = ROUNDF(ctx->EvalMap.Map2Texture4.u2); 1965 v[2] = ROUNDF(ctx->EvalMap.Map2Texture4.v1); 1966 v[3] = ROUNDF(ctx->EvalMap.Map2Texture4.v2); 1967 break; 1968 case GL_MAP2_VERTEX_3: 1969 v[0] = ROUNDF(ctx->EvalMap.Map2Vertex3.u1); 1970 v[1] = ROUNDF(ctx->EvalMap.Map2Vertex3.u2); 1971 v[2] = ROUNDF(ctx->EvalMap.Map2Vertex3.v1); 1972 v[3] = ROUNDF(ctx->EvalMap.Map2Vertex3.v2); 1973 break; 1974 case GL_MAP2_VERTEX_4: 1975 v[0] = ROUNDF(ctx->EvalMap.Map2Vertex4.u1); 1976 v[1] = ROUNDF(ctx->EvalMap.Map2Vertex4.u2); 1977 v[2] = ROUNDF(ctx->EvalMap.Map2Vertex4.v1); 1978 v[3] = ROUNDF(ctx->EvalMap.Map2Vertex4.v2); 1979 break; 1980 default: 1981 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); 1982 } 1983 break; 1984 default: 1985 gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" ); 1986 } 1987} 1988 1989 1990 1991void eval_points1( GLfloat outcoord[][4], 1992 GLfloat coord[][4], 1993 const GLuint *flags, 1994 GLfloat du, GLfloat u1 ) 1995{ 1996 GLuint i; 1997 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 1998 if (flags[i] & VERT_EVAL_P1) 1999 outcoord[i][0] = coord[i][0] * du + u1; 2000 else if (flags[i] & VERT_EVAL_ANY) { 2001 outcoord[i][0] = coord[i][0]; 2002 outcoord[i][1] = coord[i][1]; 2003 } 2004} 2005 2006void eval_points2( GLfloat outcoord[][4], 2007 GLfloat coord[][4], 2008 const GLuint *flags, 2009 GLfloat du, GLfloat u1, 2010 GLfloat dv, GLfloat v1 ) 2011{ 2012 GLuint i; 2013 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2014 if (flags[i] & VERT_EVAL_P2) { 2015 outcoord[i][0] = coord[i][0] * du + u1; 2016 outcoord[i][1] = coord[i][1] * dv + v1; 2017 } else if (flags[i] & VERT_EVAL_ANY) { 2018 outcoord[i][0] = coord[i][0]; 2019 outcoord[i][1] = coord[i][1]; 2020 } 2021} 2022 2023 2024static const GLubyte dirty_flags[5] = { 2025 0, /* not possible */ 2026 VEC_DIRTY_0, 2027 VEC_DIRTY_1, 2028 VEC_DIRTY_2, 2029 VEC_DIRTY_3 2030}; 2031 2032 2033GLvector4f *eval1_4f( GLvector4f *dest, 2034 GLfloat coord[][4], 2035 const GLuint *flags, 2036 GLuint dimension, 2037 struct gl_1d_map *map ) 2038{ 2039 const GLfloat u1 = map->u1; 2040 const GLfloat du = map->du; 2041 GLfloat (*to)[4] = dest->data; 2042 GLuint i; 2043 2044 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2045 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { 2046 GLfloat u = (coord[i][0] - u1) * du; 2047 ASSIGN_4V(to[i], 0,0,0,1); 2048 horner_bezier_curve(map->Points, to[i], u, dimension, map->Order); 2049 } 2050 2051 dest->count = i; 2052 dest->size = MAX2(dest->size, dimension); 2053 dest->flags |= dirty_flags[dimension]; 2054 return dest; 2055} 2056 2057 2058GLvector1ui *eval1_1ui( GLvector1ui *dest, 2059 GLfloat coord[][4], 2060 const GLuint *flags, 2061 struct gl_1d_map *map ) 2062{ 2063 const GLfloat u1 = map->u1; 2064 const GLfloat du = map->du; 2065 GLuint *to = dest->data; 2066 GLuint i; 2067 2068 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2069 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { 2070 GLfloat u = (coord[i][0] - u1) * du; 2071 GLfloat tmp; 2072 horner_bezier_curve(map->Points, &tmp, u, 1, map->Order); 2073 to[i] = (GLuint) (GLint) tmp; 2074 } 2075 2076 dest->count = i; 2077 return dest; 2078} 2079 2080GLvector3f *eval1_norm( GLvector3f *dest, 2081 GLfloat coord[][4], 2082 GLuint *flags, /* not const */ 2083 struct gl_1d_map *map ) 2084{ 2085 const GLfloat u1 = map->u1; 2086 const GLfloat du = map->du; 2087 GLfloat (*to)[3] = dest->data; 2088 GLuint i; 2089 2090 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2091 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { 2092 GLfloat u = (coord[i][0] - u1) * du; 2093 horner_bezier_curve(map->Points, to[i], u, 3, map->Order); 2094 flags[i+1] |= VERT_NORM; /* reset */ 2095 } 2096 2097 dest->count = i; 2098 return dest; 2099} 2100 2101GLvector4ub *eval1_color( GLvector4ub *dest, 2102 GLfloat coord[][4], 2103 GLuint *flags, /* not const */ 2104 struct gl_1d_map *map ) 2105{ 2106 const GLfloat u1 = map->u1; 2107 const GLfloat du = map->du; 2108 GLubyte (*to)[4] = dest->data; 2109 GLuint i; 2110 2111 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2112 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { 2113 GLfloat u = (coord[i][0] - u1) * du; 2114 GLfloat fcolor[4]; 2115 horner_bezier_curve(map->Points, fcolor, u, 4, map->Order); 2116 FLOAT_RGBA_TO_UBYTE_RGBA(to[i], fcolor); 2117 flags[i+1] |= VERT_RGBA; /* reset */ 2118 } 2119 2120 dest->count = i; 2121 return dest; 2122} 2123 2124 2125 2126 2127GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, 2128 GLvector3f *norm_ptr, 2129 GLfloat coord[][4], 2130 GLuint *flags, 2131 GLuint dimension, 2132 struct gl_2d_map *map ) 2133{ 2134 const GLfloat u1 = map->u1; 2135 const GLfloat du = map->du; 2136 const GLfloat v1 = map->v1; 2137 const GLfloat dv = map->dv; 2138 GLfloat (*obj)[4] = obj_ptr->data; 2139 GLfloat (*normal)[3] = norm_ptr->data; 2140 GLuint i; 2141 2142 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2143 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { 2144 GLfloat u = (coord[i][0] - u1) * du; 2145 GLfloat v = (coord[i][1] - v1) * dv; 2146 GLfloat du[4], dv[4]; 2147 2148 ASSIGN_4V(obj[i], 0,0,0,1); 2149 de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension, 2150 map->Uorder, map->Vorder); 2151 2152 CROSS3(normal[i], du, dv); 2153 NORMALIZE_3FV(normal[i]); 2154 flags[i+1] |= VERT_NORM; 2155 } 2156 2157 obj_ptr->count = i; 2158 obj_ptr->size = MAX2(obj_ptr->size, dimension); 2159 obj_ptr->flags |= dirty_flags[dimension]; 2160 return obj_ptr; 2161} 2162 2163 2164GLvector4f *eval2_4f( GLvector4f *dest, 2165 GLfloat coord[][4], 2166 const GLuint *flags, 2167 GLuint dimension, 2168 struct gl_2d_map *map ) 2169{ 2170 const GLfloat u1 = map->u1; 2171 const GLfloat du = map->du; 2172 const GLfloat v1 = map->v1; 2173 const GLfloat dv = map->dv; 2174 GLfloat (*to)[4] = dest->data; 2175 GLuint i; 2176 2177 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2178 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { 2179 GLfloat u = (coord[i][0] - u1) * du; 2180 GLfloat v = (coord[i][1] - v1) * dv; 2181 horner_bezier_surf(map->Points, to[i], u, v, dimension, 2182 map->Uorder, map->Vorder); 2183 } 2184 2185 dest->count = i; 2186 dest->size = MAX2(dest->size, dimension); 2187 dest->flags |= dirty_flags[dimension]; 2188 return dest; 2189} 2190 2191 2192GLvector3f *eval2_norm( GLvector3f *dest, 2193 GLfloat coord[][4], 2194 GLuint *flags, 2195 struct gl_2d_map *map ) 2196{ 2197 const GLfloat u1 = map->u1; 2198 const GLfloat du = map->du; 2199 const GLfloat v1 = map->v1; 2200 const GLfloat dv = map->dv; 2201 GLfloat (*to)[3] = dest->data; 2202 GLuint i; 2203 2204 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2205 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { 2206 GLfloat u = (coord[i][0] - u1) * du; 2207 GLfloat v = (coord[i][1] - v1) * dv; 2208 horner_bezier_surf(map->Points, to[i], u, v, 3, 2209 map->Uorder, map->Vorder); 2210 flags[i+1] |= VERT_NORM; /* reset */ 2211 } 2212 2213 dest->count = i; 2214 return dest; 2215} 2216 2217 2218GLvector1ui *eval2_1ui( GLvector1ui *dest, 2219 GLfloat coord[][4], 2220 const GLuint *flags, 2221 struct gl_2d_map *map ) 2222{ 2223 const GLfloat u1 = map->u1; 2224 const GLfloat du = map->du; 2225 const GLfloat v1 = map->v1; 2226 const GLfloat dv = map->dv; 2227 GLuint *to = dest->data; 2228 GLuint i; 2229 2230 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2231 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { 2232 GLfloat u = (coord[i][0] - u1) * du; 2233 GLfloat v = (coord[i][1] - v1) * dv; 2234 GLfloat tmp; 2235 horner_bezier_surf(map->Points, &tmp, u, v, 1, 2236 map->Uorder, map->Vorder); 2237 2238 to[i] = (GLuint) (GLint) tmp; 2239 } 2240 2241 dest->count = i; 2242 return dest; 2243} 2244 2245 2246 2247GLvector4ub *eval2_color( GLvector4ub *dest, 2248 GLfloat coord[][4], 2249 GLuint *flags, 2250 struct gl_2d_map *map ) 2251{ 2252 const GLfloat u1 = map->u1; 2253 const GLfloat du = map->du; 2254 const GLfloat v1 = map->v1; 2255 const GLfloat dv = map->dv; 2256 GLubyte (*to)[4] = dest->data; 2257 GLuint i; 2258 2259 for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2260 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { 2261 GLfloat u = (coord[i][0] - u1) * du; 2262 GLfloat v = (coord[i][1] - v1) * dv; 2263 GLfloat fcolor[4]; 2264 horner_bezier_surf(map->Points, fcolor, u, v, 4, 2265 map->Uorder, map->Vorder); 2266 FLOAT_RGBA_TO_UBYTE_RGBA(to[i], fcolor); 2267 flags[i+1] |= VERT_RGBA; /* reset */ 2268 } 2269 2270 dest->count = i; 2271 return dest; 2272} 2273 2274 2275GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, 2276 const GLuint *flags) 2277{ 2278 GLfloat (*to)[4] = out->data; 2279 GLfloat (*from)[4] = in->data; 2280 GLuint i; 2281 2282 for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2283 if (!(flags[i] & VERT_EVAL_ANY)) 2284 COPY_4FV( to[i], from[i] ); 2285 2286 return out; 2287} 2288 2289GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, 2290 const GLuint *flags) 2291{ 2292 GLfloat (*to)[3] = out->data; 2293 GLfloat (*from)[3] = in->data; 2294 GLuint i; 2295 2296 for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2297 if (!(flags[i] & VERT_EVAL_ANY)) 2298 COPY_3V( to[i], from[i] ); 2299 2300 return out; 2301} 2302 2303GLvector4ub *copy_4ub( GLvector4ub *out, CONST GLvector4ub *in, 2304 const GLuint *flags ) 2305{ 2306 GLubyte (*to)[4] = out->data; 2307 GLubyte (*from)[4] = in->data; 2308 GLuint i; 2309 2310 for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2311 if (!(flags[i] & VERT_EVAL_ANY)) 2312 COPY_4UBV( to[i], from[i] ); 2313 2314 return out; 2315} 2316 2317GLvector1ui *copy_1ui( GLvector1ui *out, CONST GLvector1ui *in, 2318 const GLuint *flags ) 2319{ 2320 GLuint *to = out->data; 2321 CONST GLuint *from = in->data; 2322 GLuint i; 2323 2324 for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 2325 if (!(flags[i] & VERT_EVAL_ANY)) 2326 to[i] = from[i]; 2327 2328 return out; 2329} 2330 2331 2332/* KW: Rewrote this to perform eval on a whole buffer at once. 2333 * Only evaluates active data items, and avoids scribbling 2334 * the source buffer if we are running from a display list. 2335 * 2336 * If the user (in this case looser) sends eval coordinates 2337 * or runs a display list containing eval coords with no 2338 * vertex maps enabled, we have to either copy all non-eval 2339 * data to a new buffer, or find a way of working around 2340 * the eval data. I choose the second option. 2341 * 2342 * KW: This code not reached by cva - use IM to access storage. 2343 */ 2344void gl_eval_vb( struct vertex_buffer *VB ) 2345{ 2346 struct immediate *IM = VB->IM; 2347 GLcontext *ctx = VB->ctx; 2348 GLuint req = ctx->CVA.elt.inputs; 2349 GLfloat (*coord)[4] = VB->ObjPtr->data; 2350 GLuint *flags = VB->Flag; 2351 GLuint new_flags = 0; 2352 2353 2354 GLuint any_eval1 = VB->OrFlag & (VERT_EVAL_C1|VERT_EVAL_P1); 2355 GLuint any_eval2 = VB->OrFlag & (VERT_EVAL_C2|VERT_EVAL_P2); 2356 GLuint all_eval = VB->AndFlag & VERT_EVAL_ANY; 2357 2358 /* Handle the degenerate cases. 2359 */ 2360 if (any_eval1 && !ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) { 2361 VB->PurgeFlags |= (VERT_EVAL_C1|VERT_EVAL_P1); 2362 VB->EarlyCull = 0; 2363 any_eval1 = GL_FALSE; 2364 } 2365 2366 if (any_eval2 && !ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) { 2367 VB->PurgeFlags |= (VERT_EVAL_C2|VERT_EVAL_P2); 2368 VB->EarlyCull = 0; 2369 any_eval2 = GL_FALSE; 2370 } 2371 2372 /* KW: This really is a degenerate case - doing this disables 2373 * culling, and causes dummy values for the missing vertices to be 2374 * transformed and clip tested. It also forces the individual 2375 * cliptesting of each primitive in vb_render. I wish there was a 2376 * nice alternative, but I can't say I want to put effort into 2377 * optimizing such a bad usage of the library - I'd much rather 2378 * work on useful changes. 2379 */ 2380 if (VB->PurgeFlags) { 2381 if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB_START; 2382 gl_purge_vertices( VB ); 2383 if (!any_eval1 && !any_eval2) return; 2384 } else 2385 VB->IndirectCount = VB->Count; 2386 2387 /* Translate points into coords. 2388 */ 2389 if (any_eval1 && (VB->OrFlag & VERT_EVAL_P1)) 2390 { 2391 eval_points1( IM->Obj, coord, flags, 2392 ctx->Eval.MapGrid1du, 2393 ctx->Eval.MapGrid1u1); 2394 2395 coord = IM->Obj; 2396 } 2397 2398 if (any_eval2 && (VB->OrFlag & VERT_EVAL_P2)) 2399 { 2400 eval_points2( IM->Obj, coord, flags, 2401 ctx->Eval.MapGrid2du, 2402 ctx->Eval.MapGrid2u1, 2403 ctx->Eval.MapGrid2dv, 2404 ctx->Eval.MapGrid2v1 ); 2405 2406 coord = IM->Obj; 2407 } 2408 2409 /* Perform the evaluations on active data elements. 2410 */ 2411 if (req & VERT_INDEX) 2412 { 2413 GLvector1ui *in_index = VB->IndexPtr; 2414 GLvector1ui *out_index = &IM->v.Index; 2415 2416 if (ctx->Eval.Map1Index && any_eval1) 2417 VB->IndexPtr = eval1_1ui( out_index, coord, flags, 2418 &ctx->EvalMap.Map1Index ); 2419 2420 if (ctx->Eval.Map2Index && any_eval2) 2421 VB->IndexPtr = eval2_1ui( out_index, coord, flags, 2422 &ctx->EvalMap.Map2Index ); 2423 2424 if (VB->IndexPtr != in_index) { 2425 new_flags |= VERT_INDEX; 2426 if (!all_eval) 2427 VB->IndexPtr = copy_1ui( out_index, in_index, flags ); 2428 } 2429 } 2430 2431 if (req & VERT_RGBA) 2432 { 2433 GLvector4ub *in_color = VB->ColorPtr; 2434 GLvector4ub *out_color = &IM->v.Color; 2435 2436 if (ctx->Eval.Map1Color4 && any_eval1) 2437 VB->ColorPtr = eval1_color( out_color, coord, flags, 2438 &ctx->EvalMap.Map1Color4 ); 2439 2440 if (ctx->Eval.Map2Color4 && any_eval2) 2441 VB->ColorPtr = eval2_color( out_color, coord, flags, 2442 &ctx->EvalMap.Map2Color4 ); 2443 2444 if (VB->ColorPtr != in_color) { 2445 new_flags |= VERT_RGBA; 2446 if (!all_eval) 2447 VB->ColorPtr = copy_4ub( out_color, in_color, flags ); 2448 } 2449 2450 VB->Color[0] = VB->Color[1] = VB->ColorPtr; 2451 } 2452 2453 2454 if (req & VERT_NORM) 2455 { 2456 GLvector3f *in_normal = VB->NormalPtr; 2457 GLvector3f *out_normal = &IM->v.Normal; 2458 2459 if (ctx->Eval.Map1Normal && any_eval1) 2460 VB->NormalPtr = eval1_norm( out_normal, coord, flags, 2461 &ctx->EvalMap.Map1Normal ); 2462 2463 if (ctx->Eval.Map2Normal && any_eval2) 2464 VB->NormalPtr = eval2_norm( out_normal, coord, flags, 2465 &ctx->EvalMap.Map2Normal ); 2466 2467 if (VB->NormalPtr != in_normal) { 2468 new_flags |= VERT_NORM; 2469 if (!all_eval) 2470 VB->NormalPtr = copy_3f( out_normal, in_normal, flags ); 2471 } 2472 } 2473 2474 2475 if (req & VERT_TEX_ANY(0)) 2476 { 2477 GLvector4f *tc = VB->TexCoordPtr[0]; 2478 GLvector4f *in = tc; 2479 GLvector4f *out = &IM->v.TexCoord[0]; 2480 2481 if (any_eval1) { 2482 if (ctx->Eval.Map1TextureCoord4) 2483 tc = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Texture4); 2484 else if (ctx->Eval.Map1TextureCoord3) 2485 tc = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Texture3); 2486 else if (ctx->Eval.Map1TextureCoord2) 2487 tc = eval1_4f( out, coord, flags, 2, &ctx->EvalMap.Map1Texture2); 2488 else if (ctx->Eval.Map1TextureCoord1) 2489 tc = eval1_4f( out, coord, flags, 1, &ctx->EvalMap.Map1Texture1); 2490 } 2491 2492 if (any_eval2) { 2493 if (ctx->Eval.Map2TextureCoord4) 2494 tc = eval2_4f( out, coord, flags, 4, &ctx->EvalMap.Map2Texture4); 2495 else if (ctx->Eval.Map2TextureCoord3) 2496 tc = eval2_4f( out, coord, flags, 3, &ctx->EvalMap.Map2Texture3); 2497 else if (ctx->Eval.Map2TextureCoord2) 2498 tc = eval2_4f( out, coord, flags, 2, &ctx->EvalMap.Map2Texture2); 2499 else if (ctx->Eval.Map2TextureCoord1) 2500 tc = eval2_4f( out, coord, flags, 1, &ctx->EvalMap.Map2Texture1); 2501 } 2502 2503 if (tc != in) { 2504 new_flags |= VERT_TEX_ANY(0); /* fix for sizes.. */ 2505 if (!all_eval) 2506 tc = copy_4f( out, in, flags ); 2507 } 2508 2509 VB->TexCoordPtr[0] = tc; 2510 } 2511 2512 2513 { 2514 GLvector4f *in = VB->ObjPtr; 2515 GLvector4f *out = &IM->v.Obj; 2516 GLvector4f *obj = in; 2517 2518 if (any_eval1) { 2519 if (ctx->Eval.Map1Vertex4) 2520 obj = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Vertex4); 2521 else 2522 obj = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Vertex3); 2523 } 2524 2525 if (any_eval2) { 2526 if (ctx->Eval.Map2Vertex4) 2527 { 2528 if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 2529 obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 4, 2530 &ctx->EvalMap.Map2Vertex4 ); 2531 else 2532 obj = eval2_4f( out, coord, flags, 4, 2533 &ctx->EvalMap.Map2Vertex4); 2534 } 2535 else if (ctx->Eval.Map2Vertex3) 2536 { 2537 if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 2538 obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 3, 2539 &ctx->EvalMap.Map2Vertex3 ); 2540 else 2541 obj = eval2_4f( out, coord, flags, 3, 2542 &ctx->EvalMap.Map2Vertex3 ); 2543 } 2544 } 2545 2546 if (obj != in && !all_eval) 2547 obj = copy_4f( out, in, flags ); 2548 2549 VB->ObjPtr = obj; 2550 } 2551 2552 if (new_flags) { 2553 GLuint *oldflags = VB->Flag; 2554 GLuint *flags = VB->Flag = VB->EvaluatedFlags; 2555 GLuint i; 2556 GLuint count = VB->Count; 2557 2558 if (!flags) { 2559 VB->EvaluatedFlags = (GLuint *)malloc(VB->Size * sizeof(GLuint)); 2560 flags = VB->Flag = VB->EvaluatedFlags; 2561 } 2562 2563 if (all_eval) { 2564 for (i = 0 ; i < count ; i++) 2565 flags[i] = oldflags[i] | new_flags; 2566 VB->AndFlag |= new_flags; 2567 } else { 2568 GLuint andflag = ~0; 2569 for (i = 0 ; i < count ; i++) { 2570 if (oldflags[i] & VERT_EVAL_ANY) 2571 flags[i] = oldflags[i] | new_flags; 2572 andflag &= flags[i]; 2573 } 2574 VB->AndFlag = andflag; 2575 } 2576 } 2577} 2578 2579 2580void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 ) 2581{ 2582 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid1f"); 2583 2584 if (un<1) { 2585 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" ); 2586 return; 2587 } 2588 ctx->Eval.MapGrid1un = un; 2589 ctx->Eval.MapGrid1u1 = u1; 2590 ctx->Eval.MapGrid1u2 = u2; 2591 ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un; 2592} 2593 2594 2595void gl_MapGrid2f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2, 2596 GLint vn, GLfloat v1, GLfloat v2 ) 2597{ 2598 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid2f"); 2599 if (un<1) { 2600 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" ); 2601 return; 2602 } 2603 if (vn<1) { 2604 gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" ); 2605 return; 2606 } 2607 ctx->Eval.MapGrid2un = un; 2608 ctx->Eval.MapGrid2u1 = u1; 2609 ctx->Eval.MapGrid2u2 = u2; 2610 ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un; 2611 ctx->Eval.MapGrid2vn = vn; 2612 ctx->Eval.MapGrid2v1 = v1; 2613 ctx->Eval.MapGrid2v2 = v2; 2614 ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn; 2615} 2616 2617 2618 2619void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 ) 2620{ 2621 GLint i; 2622 GLfloat u, du; 2623 GLenum prim; 2624 2625 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh1"); 2626 2627 switch (mode) { 2628 case GL_POINT: 2629 prim = GL_POINTS; 2630 break; 2631 case GL_LINE: 2632 prim = GL_LINE_STRIP; 2633 break; 2634 default: 2635 gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); 2636 return; 2637 } 2638 2639 /* No effect if vertex maps disabled. 2640 */ 2641 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 2642 return; 2643 2644 du = ctx->Eval.MapGrid1du; 2645 u = ctx->Eval.MapGrid1u1 + i1 * du; 2646 2647 /* KW: Could short-circuit this to avoid the immediate mechanism. 2648 */ 2649 RESET_IMMEDIATE(ctx); 2650 2651 gl_Begin( ctx, prim ); 2652 for (i=i1;i<=i2;i++,u+=du) { 2653 gl_EvalCoord1f( ctx, u ); 2654 } 2655 gl_End(ctx); 2656} 2657 2658 2659 2660void gl_EvalMesh2( GLcontext* ctx, 2661 GLenum mode, 2662 GLint i1, GLint i2, 2663 GLint j1, GLint j2 ) 2664{ 2665 GLint i, j; 2666 GLfloat u, du, v, dv, v1, u1; 2667 2668 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh2"); 2669 2670 /* No effect if vertex maps disabled. 2671 */ 2672 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 2673 return; 2674 2675 du = ctx->Eval.MapGrid2du; 2676 dv = ctx->Eval.MapGrid2dv; 2677 v1 = ctx->Eval.MapGrid2v1 + j1 * dv; 2678 u1 = ctx->Eval.MapGrid2u1 + i1 * du; 2679 2680 RESET_IMMEDIATE(ctx); 2681 2682 switch (mode) { 2683 case GL_POINT: 2684 gl_Begin( ctx, GL_POINTS ); 2685 for (v=v1,j=j1;j<=j2;j++,v+=dv) { 2686 for (u=u1,i=i1;i<=i2;i++,u+=du) { 2687 gl_EvalCoord2f( ctx, u, v ); 2688 } 2689 } 2690 gl_End(ctx); 2691 break; 2692 case GL_LINE: 2693 for (v=v1,j=j1;j<=j2;j++,v+=dv) { 2694 gl_Begin( ctx, GL_LINE_STRIP ); 2695 for (u=u1,i=i1;i<=i2;i++,u+=du) { 2696 gl_EvalCoord2f( ctx, u, v ); 2697 } 2698 gl_End(ctx); 2699 } 2700 for (u=u1,i=i1;i<=i2;i++,u+=du) { 2701 gl_Begin( ctx, GL_LINE_STRIP ); 2702 for (v=v1,j=j1;j<=j2;j++,v+=dv) { 2703 gl_EvalCoord2f( ctx, u, v ); 2704 } 2705 gl_End(ctx); 2706 } 2707 break; 2708 case GL_FILL: 2709 for (v=v1,j=j1;j<j2;j++,v+=dv) { 2710 /* NOTE: a quad strip can't be used because the four */ 2711 /* can't be guaranteed to be coplanar! */ 2712 gl_Begin( ctx, GL_TRIANGLE_STRIP ); 2713 for (u=u1,i=i1;i<=i2;i++,u+=du) { 2714 gl_EvalCoord2f( ctx, u, v ); 2715 gl_EvalCoord2f( ctx, u, v+dv ); 2716 } 2717 gl_End(ctx); 2718 } 2719 break; 2720 default: 2721 gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); 2722 return; 2723 } 2724} 2725 2726