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