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