1 /* 2 ** License Applicability. Except to the extent portions of this file are 3 ** made subject to an alternative license as permitted in the SGI Free 4 ** Software License B, Version 1.1 (the "License"), the contents of this 5 ** file are subject only to the provisions of the License. You may not use 6 ** this file except in compliance with the License. You may obtain a copy 7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9 ** 10 ** http://oss.sgi.com/projects/FreeB 11 ** 12 ** Note that, as provided in the License, the Software is distributed on an 13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17 ** 18 ** Original Code. The Original Code is: OpenGL Sample Implementation, 19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 21 ** Copyright in any portions created by third parties is as indicated 22 ** elsewhere herein. All Rights Reserved. 23 ** 24 ** Additional Notice Provisions: The application programming interfaces 25 ** established by SGI in conjunction with the Original Code are The 26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 29 ** Window System(R) (Version 1.3), released October 19, 1998. This software 30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 31 ** published by SGI, but has not been independently verified as being 32 ** compliant with the OpenGL(R) version 1.2.1 Specification. 33 */ 34 35 /* 36 * glsurfeval.c++ 37 * 38 */ 39 40 /* Polynomial Evaluator Interface */ 41 #include "gluos.h" 42 //#include <stdio.h> 43 //#include "glimports.h" 44 #include "glrenderer.h" 45 //#include "glsurfeval.h" 46 //#include "nurbsconsts.h" 47 //#include "bezierPatchMesh.h" 48 49 50 //extern int surfcount; 51 //int surfcount=0; 52 53 /*#define USE_INTERNAL_EVAL*/ //use internal evaluator 54 55 /*whether do evaluation or not*/ 56 /*#define NO_EVALUATION*/ 57 58 //#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too 59 60 /*for statistics*/ 61 //#define STATISTICS 62 #ifdef STATISTICS 63 static int STAT_num_of_triangles=0; 64 static int STAT_num_of_eval_vertices=0; 65 static int STAT_num_of_quad_strips=0; 66 #endif 67 68 /*for output triangles*/ 69 /*#define OUTPUT_TRIANGLES*/ 70 71 72 /*#define FOR_CHRIS*/ 73 #ifdef FOR_CHRIS 74 extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val, 75 int n_lower, REAL v_lower, REAL* lower_val);} 76 77 extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val, 78 int n_right, REAL u_right, REAL* right_val); 79 } 80 #endif 81 82 83 /**************begin for LOD_eval_list***********/ 84 void OpenGLSurfaceEvaluator::LOD_eval_list(int level) 85 { 86 if(level == 0) 87 LOD_eval_level = 1; 88 else if(level == 1) 89 LOD_eval_level = 2; 90 else if(level == 2) 91 LOD_eval_level = 4; 92 else 93 LOD_eval_level = 8; 94 95 inBPMListEvalEM(global_bpm); 96 } 97 98 99 OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator() 100 { 101 int i; 102 103 for (i=0; i<VERTEX_CACHE_SIZE; i++) { 104 vertexCache[i] = new StoredVertex; 105 } 106 tmeshing = 0; 107 which = 0; 108 vcount = 0; 109 110 global_uorder = 0; 111 global_vorder = 0; 112 global_uprime = -1.0; 113 global_vprime = -1.0; 114 global_vprime_BV = -1.0; 115 global_uprime_BU = -1.0; 116 global_uorder_BU = 0; 117 global_vorder_BU = 0; 118 global_uorder_BV = 0; 119 global_vorder_BV = 0; 120 global_baseData = NULL; 121 122 global_bpm = NULL; 123 output_triangles = 0; //don't output triangles by default 124 125 //no default callback functions 126 beginCallBackN = NULL; 127 endCallBackN = NULL; 128 vertexCallBackN = NULL; 129 normalCallBackN = NULL; 130 colorCallBackN = NULL; 131 texcoordCallBackN = NULL; 132 beginCallBackData = NULL; 133 endCallBackData = NULL; 134 vertexCallBackData = NULL; 135 normalCallBackData = NULL; 136 colorCallBackData = NULL; 137 texcoordCallBackData = NULL; 138 139 userData = NULL; 140 141 auto_normal_flag = 0; 142 callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0 143 vertex_flag = 0; 144 normal_flag = 0; 145 color_flag = 0; 146 texcoord_flag = 0; 147 148 em_vertex.uprime = -1.0; 149 em_vertex.vprime = -1.0; 150 em_normal.uprime = -1.0; 151 em_normal.vprime = -1.0; 152 em_color.uprime = -1.0; 153 em_color.vprime = -1.0; 154 em_texcoord.uprime = -1.0; 155 em_texcoord.vprime = -1.0; 156 157 #ifdef USE_LOD 158 LOD_eval_level = 1; 159 #endif 160 } 161 162 OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator() 163 { 164 for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) { 165 delete vertexCache[ii]; 166 vertexCache[ii]= 0; 167 } 168 } 169 170 /*--------------------------------------------------------------------------- 171 * disable - turn off a map 172 *--------------------------------------------------------------------------- 173 */ 174 void 175 OpenGLSurfaceEvaluator::disable(long type) 176 { 177 glDisable((GLenum) type); 178 } 179 180 /*--------------------------------------------------------------------------- 181 * enable - turn on a map 182 *--------------------------------------------------------------------------- 183 */ 184 void 185 OpenGLSurfaceEvaluator::enable(long type) 186 { 187 glEnable((GLenum) type); 188 } 189 190 /*------------------------------------------------------------------------- 191 * mapgrid2f - define a lattice of points with origin and offset 192 *------------------------------------------------------------------------- 193 */ 194 void 195 OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1) 196 { 197 #ifdef USE_INTERNAL_EVAL 198 inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv, 199 (REAL) v0, (REAL) v1); 200 #else 201 202 if(output_triangles) 203 { 204 global_grid_u0 = u0; 205 global_grid_u1 = u1; 206 global_grid_nu = nu; 207 global_grid_v0 = v0; 208 global_grid_v1 = v1; 209 global_grid_nv = nv; 210 } 211 else 212 glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv, 213 (GLdouble) v0, (GLdouble) v1); 214 215 #endif 216 } 217 218 void 219 OpenGLSurfaceEvaluator::polymode(long style) 220 { 221 if(! output_triangles) 222 { 223 switch(style) { 224 default: 225 case N_MESHFILL: 226 227 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL); 228 break; 229 case N_MESHLINE: 230 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE); 231 break; 232 case N_MESHPOINT: 233 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT); 234 break; 235 } 236 } 237 } 238 239 void 240 OpenGLSurfaceEvaluator::bgnline(void) 241 { 242 if(output_triangles) 243 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP); 244 else 245 glBegin((GLenum) GL_LINE_STRIP); 246 } 247 248 void 249 OpenGLSurfaceEvaluator::endline(void) 250 { 251 if(output_triangles) 252 bezierPatchMeshEndStrip(global_bpm); 253 else 254 glEnd(); 255 } 256 257 void 258 OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to) 259 { 260 } 261 262 void 263 OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi) 264 { 265 } 266 267 void 268 OpenGLSurfaceEvaluator::bgnclosedline(void) 269 { 270 if(output_triangles) 271 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP); 272 else 273 glBegin((GLenum) GL_LINE_LOOP); 274 } 275 276 void 277 OpenGLSurfaceEvaluator::endclosedline(void) 278 { 279 if(output_triangles) 280 bezierPatchMeshEndStrip(global_bpm); 281 else 282 glEnd(); 283 } 284 285 286 287 288 289 void 290 OpenGLSurfaceEvaluator::bgntmesh(void) 291 { 292 293 tmeshing = 1; 294 which = 0; 295 vcount = 0; 296 297 if(output_triangles) 298 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES); 299 else 300 glBegin((GLenum) GL_TRIANGLES); 301 302 } 303 304 void 305 OpenGLSurfaceEvaluator::swaptmesh(void) 306 { 307 which = 1 - which; 308 309 } 310 311 void 312 OpenGLSurfaceEvaluator::endtmesh(void) 313 { 314 tmeshing = 0; 315 316 317 if(output_triangles) 318 bezierPatchMeshEndStrip(global_bpm); 319 else 320 glEnd(); 321 } 322 323 void 324 OpenGLSurfaceEvaluator::bgntfan(void) 325 { 326 327 if(output_triangles) 328 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN); 329 else 330 glBegin((GLenum) GL_TRIANGLE_FAN); 331 332 } 333 void 334 OpenGLSurfaceEvaluator::endtfan(void) 335 { 336 if(output_triangles) 337 bezierPatchMeshEndStrip(global_bpm); 338 else 339 glEnd(); 340 } 341 342 void 343 OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) 344 { 345 #ifdef USE_INTERNAL_EVAL 346 inEvalUStrip(n_upper, v_upper, upper_val, 347 n_lower, v_lower, lower_val); 348 #else 349 350 #ifdef FOR_CHRIS 351 evalUStripExt(n_upper, v_upper, upper_val, 352 n_lower, v_lower, lower_val); 353 return; 354 355 #endif 356 int i,j,k,l; 357 REAL leftMostV[2]; 358 359 /* 360 *the algorithm works by scanning from left to right. 361 *leftMostV: the left most of the remaining verteces (on both upper and lower). 362 * it could an element of upperVerts or lowerVerts. 363 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line 364 *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line 365 */ 366 367 /*initialize i,j,and leftMostV 368 */ 369 if(upper_val[0] <= lower_val[0]) 370 { 371 i=1; 372 j=0; 373 374 leftMostV[0] = upper_val[0]; 375 leftMostV[1] = v_upper; 376 } 377 else 378 { 379 i=0; 380 j=1; 381 382 leftMostV[0] = lower_val[0]; 383 leftMostV[1] = v_lower; 384 385 } 386 387 /*the main loop. 388 *the invariance is that: 389 *at the beginning of each loop, the meaning of i,j,and leftMostV are 390 *maintained 391 */ 392 while(1) 393 { 394 if(i >= n_upper) /*case1: no more in upper*/ 395 { 396 if(j<n_lower-1) /*at least two vertices in lower*/ 397 { 398 bgntfan(); 399 coord2f(leftMostV[0], leftMostV[1]); 400 // glNormal3fv(leftMostNormal); 401 // glVertex3fv(leftMostXYZ); 402 403 while(j<n_lower){ 404 coord2f(lower_val[j], v_lower); 405 // glNormal3fv(lowerNormal[j]); 406 // glVertex3fv(lowerXYZ[j]); 407 j++; 408 409 } 410 endtfan(); 411 } 412 break; /*exit the main loop*/ 413 } 414 else if(j>= n_lower) /*case2: no more in lower*/ 415 { 416 if(i<n_upper-1) /*at least two vertices in upper*/ 417 { 418 bgntfan(); 419 coord2f(leftMostV[0], leftMostV[1]); 420 // glNormal3fv(leftMostNormal); 421 // glVertex3fv(leftMostXYZ); 422 423 for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ 424 { 425 coord2f(upper_val[k], v_upper); 426 // glNormal3fv(upperNormal[k]); 427 // glVertex3fv(upperXYZ[k]); 428 } 429 430 endtfan(); 431 } 432 break; /*exit the main loop*/ 433 } 434 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ 435 { 436 if(upper_val[i] <= lower_val[j]) 437 { 438 bgntfan(); 439 coord2f(lower_val[j], v_lower); 440 // glNormal3fv(lowerNormal[j]); 441 // glVertex3fv(lowerXYZ[j]); 442 443 /*find the last k>=i such that 444 *upperverts[k][0] <= lowerverts[j][0] 445 */ 446 k=i; 447 448 while(k<n_upper) 449 { 450 if(upper_val[k] > lower_val[j]) 451 break; 452 k++; 453 454 } 455 k--; 456 457 458 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ 459 { 460 coord2f(upper_val[l], v_upper); 461 // glNormal3fv(upperNormal[l]); 462 // glVertex3fv(upperXYZ[l]); 463 464 } 465 coord2f(leftMostV[0], leftMostV[1]); 466 // glNormal3fv(leftMostNormal); 467 // glVertex3fv(leftMostXYZ); 468 469 endtfan(); 470 471 /*update i and leftMostV for next loop 472 */ 473 i = k+1; 474 475 leftMostV[0] = upper_val[k]; 476 leftMostV[1] = v_upper; 477 // leftMostNormal = upperNormal[k]; 478 // leftMostXYZ = upperXYZ[k]; 479 } 480 else /*upperVerts[i][0] > lowerVerts[j][0]*/ 481 { 482 bgntfan(); 483 coord2f(upper_val[i], v_upper); 484 // glNormal3fv(upperNormal[i]); 485 // glVertex3fv(upperXYZ[i]); 486 487 coord2f(leftMostV[0], leftMostV[1]); 488 // glNormal3fv(leftMostNormal); 489 // glVertex3fv(leftMostXYZ); 490 491 492 /*find the last k>=j such that 493 *lowerverts[k][0] < upperverts[i][0] 494 */ 495 k=j; 496 while(k< n_lower) 497 { 498 if(lower_val[k] >= upper_val[i]) 499 break; 500 coord2f(lower_val[k], v_lower); 501 // glNormal3fv(lowerNormal[k]); 502 // glVertex3fv(lowerXYZ[k]); 503 504 k++; 505 } 506 endtfan(); 507 508 /*update j and leftMostV for next loop 509 */ 510 j=k; 511 leftMostV[0] = lower_val[j-1]; 512 leftMostV[1] = v_lower; 513 514 // leftMostNormal = lowerNormal[j-1]; 515 // leftMostXYZ = lowerXYZ[j-1]; 516 } 517 } 518 } 519 //clean up 520 // free(upperXYZ); 521 // free(lowerXYZ); 522 // free(upperNormal); 523 // free(lowerNormal); 524 #endif 525 526 } 527 528 529 void 530 OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) 531 { 532 #ifdef USE_INTERNAL_EVAL 533 inEvalVStrip(n_left, u_left, left_val, 534 n_right, u_right, right_val); 535 #else 536 537 #ifdef FOR_CHRIS 538 evalVStripExt(n_left, u_left, left_val, 539 n_right, u_right, right_val); 540 return; 541 542 #endif 543 544 int i,j,k,l; 545 REAL botMostV[2]; 546 /* 547 *the algorithm works by scanning from bot to top. 548 *botMostV: the bot most of the remaining verteces (on both left and right). 549 * it could an element of leftVerts or rightVerts. 550 *i: leftVerts[i] is the first vertex to the top of botMostV on left line 551 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline 552 */ 553 554 /*initialize i,j,and botMostV 555 */ 556 if(left_val[0] <= right_val[0]) 557 { 558 i=1; 559 j=0; 560 561 botMostV[0] = u_left; 562 botMostV[1] = left_val[0]; 563 } 564 else 565 { 566 i=0; 567 j=1; 568 569 botMostV[0] = u_right; 570 botMostV[1] = right_val[0]; 571 } 572 573 /*the main loop. 574 *the invariance is that: 575 *at the beginning of each loop, the meaning of i,j,and botMostV are 576 *maintained 577 */ 578 while(1) 579 { 580 if(i >= n_left) /*case1: no more in left*/ 581 { 582 if(j<n_right-1) /*at least two vertices in right*/ 583 { 584 bgntfan(); 585 coord2f(botMostV[0], botMostV[1]); 586 while(j<n_right){ 587 coord2f(u_right, right_val[j]); 588 // glNormal3fv(rightNormal[j]); 589 // glVertex3fv(rightXYZ[j]); 590 j++; 591 592 } 593 endtfan(); 594 } 595 break; /*exit the main loop*/ 596 } 597 else if(j>= n_right) /*case2: no more in right*/ 598 { 599 if(i<n_left-1) /*at least two vertices in left*/ 600 { 601 bgntfan(); 602 coord2f(botMostV[0], botMostV[1]); 603 // glNormal3fv(botMostNormal); 604 // glVertex3fv(botMostXYZ); 605 606 for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ 607 { 608 coord2f(u_left, left_val[k]); 609 // glNormal3fv(leftNormal[k]); 610 // glVertex3fv(leftXYZ[k]); 611 } 612 613 endtfan(); 614 } 615 break; /*exit the main loop*/ 616 } 617 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ 618 { 619 if(left_val[i] <= right_val[j]) 620 { 621 bgntfan(); 622 coord2f(u_right, right_val[j]); 623 // glNormal3fv(rightNormal[j]); 624 // glVertex3fv(rightXYZ[j]); 625 626 /*find the last k>=i such that 627 *leftverts[k][0] <= rightverts[j][0] 628 */ 629 k=i; 630 631 while(k<n_left) 632 { 633 if(left_val[k] > right_val[j]) 634 break; 635 k++; 636 637 } 638 k--; 639 640 641 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ 642 { 643 coord2f(u_left, left_val[l]); 644 // glNormal3fv(leftNormal[l]); 645 // glVertex3fv(leftXYZ[l]); 646 647 } 648 coord2f(botMostV[0], botMostV[1]); 649 // glNormal3fv(botMostNormal); 650 // glVertex3fv(botMostXYZ); 651 652 endtfan(); 653 654 /*update i and botMostV for next loop 655 */ 656 i = k+1; 657 658 botMostV[0] = u_left; 659 botMostV[1] = left_val[k]; 660 // botMostNormal = leftNormal[k]; 661 // botMostXYZ = leftXYZ[k]; 662 } 663 else /*left_val[i] > right_val[j])*/ 664 { 665 bgntfan(); 666 coord2f(u_left, left_val[i]); 667 // glNormal3fv(leftNormal[i]); 668 // glVertex3fv(leftXYZ[i]); 669 670 coord2f(botMostV[0], botMostV[1]); 671 // glNormal3fv(botMostNormal); 672 // glVertex3fv(botMostXYZ); 673 674 675 /*find the last k>=j such that 676 *rightverts[k][0] < leftverts[i][0] 677 */ 678 k=j; 679 while(k< n_right) 680 { 681 if(right_val[k] >= left_val[i]) 682 break; 683 coord2f(u_right, right_val[k]); 684 // glNormal3fv(rightNormal[k]); 685 // glVertex3fv(rightXYZ[k]); 686 687 k++; 688 } 689 endtfan(); 690 691 /*update j and botMostV for next loop 692 */ 693 j=k; 694 botMostV[0] = u_right; 695 botMostV[1] = right_val[j-1]; 696 697 // botMostNormal = rightNormal[j-1]; 698 // botMostXYZ = rightXYZ[j-1]; 699 } 700 } 701 } 702 //clean up 703 // free(leftXYZ); 704 // free(leftNormal); 705 // free(rightXYZ); 706 // free(rightNormal); 707 #endif 708 } 709 710 711 void 712 OpenGLSurfaceEvaluator::bgnqstrip(void) 713 { 714 if(output_triangles) 715 bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP); 716 else 717 glBegin((GLenum) GL_QUAD_STRIP); 718 719 #ifdef STATISTICS 720 STAT_num_of_quad_strips++; 721 #endif 722 } 723 724 void 725 OpenGLSurfaceEvaluator::endqstrip(void) 726 { 727 if(output_triangles) 728 bezierPatchMeshEndStrip(global_bpm); 729 else 730 glEnd(); 731 732 } 733 734 /*------------------------------------------------------------------------- 735 * bgnmap2f - preamble to surface definition and evaluations 736 *------------------------------------------------------------------------- 737 */ 738 void 739 OpenGLSurfaceEvaluator::bgnmap2f(long) 740 { 741 if(output_triangles) 742 { 743 /*deallocate the space which may has been 744 *allocated by global_bpm previously 745 */ 746 if(global_bpm != NULL) { 747 bezierPatchMeshListDelete(global_bpm); 748 global_bpm = NULL; 749 } 750 751 752 /* 753 auto_normal_flag = 1; //always output normal in callback mode. 754 //we could have used the following code, 755 //but Inspector doesn't have gl context 756 //before it calls tessellator. 757 //this way is temporary. 758 */ 759 //NEWCALLBACK 760 //if one of the two normal callback functions are set, 761 //then set 762 if(normalCallBackN != NULL || 763 normalCallBackData != NULL) 764 auto_normal_flag = 1; 765 else 766 auto_normal_flag = 0; 767 768 //initialize so that no maps initially 769 vertex_flag = 0; 770 normal_flag = 0; 771 color_flag = 0; 772 texcoord_flag = 0; 773 774 /* 775 if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE) 776 auto_normal_flag = 1; 777 else if (callback_auto_normal == 1) 778 auto_normal_flag = 1; 779 else 780 auto_normal_flag = 0; 781 */ 782 glPushAttrib((GLbitfield) GL_EVAL_BIT); 783 784 } 785 else 786 { 787 glPushAttrib((GLbitfield) GL_EVAL_BIT); 788 789 /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE 790 */ 791 glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode); 792 } 793 794 } 795 796 /*------------------------------------------------------------------------- 797 * endmap2f - postamble to a map 798 *------------------------------------------------------------------------- 799 */ 800 void 801 OpenGLSurfaceEvaluator::endmap2f(void) 802 { 803 804 if(output_triangles) 805 { 806 //bezierPatchMeshListDelDeg(global_bpm); 807 808 // bezierPatchMeshListEval(global_bpm); 809 810 //surfcount++; 811 //printf("surfcount=%i\n", surfcount); 812 //if(surfcount == 8) exit(0); 813 814 inBPMListEvalEM(global_bpm); 815 816 817 818 /* 819 global_bpm = bezierPatchMeshListReverse(global_bpm); 820 { 821 float *vertex_array; 822 float *normal_array; 823 int *length_array; 824 int *type_array; 825 int num_strips; 826 bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips); 827 drawStrips(vertex_array, normal_array, length_array, type_array, num_strips); 828 free(vertex_array); 829 free(normal_array); 830 free(length_array); 831 free(type_array); 832 } 833 */ 834 835 //bezierPatchMeshListPrint(global_bpm); 836 //bezierPatchMeshListDraw(global_bpm); 837 838 // printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm)); 839 840 #ifdef USE_LOD 841 #else 842 bezierPatchMeshListDelete(global_bpm); 843 global_bpm = NULL; 844 #endif 845 glPopAttrib(); 846 } 847 else 848 { 849 #ifndef USE_LOD 850 glPopAttrib(); 851 #endif 852 853 #ifdef STATISTICS 854 fprintf(stderr, "num_vertices=%i,num_triangles=%i,num_quads_strips=%i\n", STAT_num_of_eval_vertices,STAT_num_of_triangles,STAT_num_of_quad_strips); 855 #endif 856 857 /*to restore the gl_polygon_mode 858 */ 859 #ifndef USE_LOD 860 glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]); 861 glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]); 862 #endif 863 } 864 865 } 866 867 /*------------------------------------------------------------------------- 868 * map2f - pass a desription of a surface map 869 *------------------------------------------------------------------------- 870 */ 871 void 872 OpenGLSurfaceEvaluator::map2f( 873 long _type, 874 REAL _ulower, /* u lower domain coord */ 875 REAL _uupper, /* u upper domain coord */ 876 long _ustride, /* interpoint distance */ 877 long _uorder, /* parametric order */ 878 REAL _vlower, /* v lower domain coord */ 879 REAL _vupper, /* v upper domain coord */ 880 long _vstride, /* interpoint distance */ 881 long _vorder, /* parametric order */ 882 REAL *pts) /* control points */ 883 { 884 #ifdef USE_INTERNAL_EVAL 885 inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper, 886 (int) _ustride, (int) _uorder, (REAL) _vlower, 887 (REAL) _vupper, (int) _vstride, (int) _vorder, 888 (REAL *) pts); 889 #else 890 891 892 893 if(output_triangles) 894 { 895 if(global_bpm == NULL) 896 global_bpm = bezierPatchMeshMake2(10,10); 897 if( 898 (global_bpm->bpatch == NULL && 899 (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4)) 900 || 901 (global_bpm->bpatch_normal == NULL && 902 (_type == GL_MAP2_NORMAL)) 903 || 904 (global_bpm->bpatch_color == NULL && 905 (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4)) 906 || 907 (global_bpm->bpatch_texcoord == NULL && 908 (_type == GL_MAP2_TEXTURE_COORD_1 || 909 _type == GL_MAP2_TEXTURE_COORD_2 || 910 _type == GL_MAP2_TEXTURE_COORD_3 || 911 _type == GL_MAP2_TEXTURE_COORD_4 ) 912 )) 913 { 914 bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); 915 } 916 else /*new surface patch (with multiple maps) starts*/ 917 { 918 bezierPatchMesh *temp = bezierPatchMeshMake2(10,10); 919 bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); 920 global_bpm = bezierPatchMeshListInsert(global_bpm, temp); 921 922 /* 923 global_bpm = bezierPatchMeshListInsert(global_bpm, 924 bezierPatchMeshMake( 925 (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10)); 926 */ 927 } 928 } 929 else /*not output triangles*/ 930 { 931 glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper, 932 (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower, 933 (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder, 934 (const GLfloat *) pts); 935 } 936 937 #endif 938 } 939 940 941 /*------------------------------------------------------------------------- 942 * mapmesh2f - evaluate a mesh of points on lattice 943 *------------------------------------------------------------------------- 944 */ 945 void 946 OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax) 947 { 948 #ifdef NO_EVALUATION 949 return; 950 #endif 951 952 #ifdef USE_INTERNAL_EVAL 953 inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax); 954 #else 955 956 957 958 if(output_triangles) 959 { 960 #ifdef USE_LOD 961 bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON); 962 bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0); 963 bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1); 964 bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv); 965 bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin); 966 bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax); 967 bezierPatchMeshEndStrip(global_bpm); 968 969 #else 970 971 REAL du, dv; 972 long i,j; 973 if(global_grid_nu == 0 || global_grid_nv == 0) 974 return; /*no points need to be output*/ 975 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; 976 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; 977 978 if(global_grid_nu >= global_grid_nv){ 979 980 for(i=umin; i<umax; i++){ 981 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); 982 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du); 983 984 bgnqstrip(); 985 for(j=vmax; j>=vmin; j--){ 986 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); 987 988 coord2f(u1, v1); 989 coord2f(u2, v1); 990 } 991 endqstrip(); 992 } 993 } 994 else{ 995 996 for(i=vmin; i<vmax; i++){ 997 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv); 998 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv); 999 1000 bgnqstrip(); 1001 for(j=umax; j>=umin; j--){ 1002 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); 1003 coord2f(u1, v2); 1004 coord2f(u1, v1); 1005 } 1006 endqstrip(); 1007 } 1008 } 1009 #endif 1010 } 1011 else 1012 { 1013 switch(style) { 1014 default: 1015 case N_MESHFILL: 1016 glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax, 1017 (GLint) vmin, (GLint) vmax); 1018 break; 1019 case N_MESHLINE: 1020 glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax, 1021 (GLint) vmin, (GLint) vmax); 1022 break; 1023 case N_MESHPOINT: 1024 glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax, 1025 (GLint) vmin, (GLint) vmax); 1026 break; 1027 } 1028 } 1029 1030 #endif 1031 1032 #ifdef STATISTICS 1033 STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin); 1034 #endif 1035 } 1036 1037 /*------------------------------------------------------------------------- 1038 * evalcoord2f - evaluate a point on a surface 1039 *------------------------------------------------------------------------- 1040 */ 1041 void 1042 OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v) 1043 { 1044 1045 1046 #ifdef NO_EVALUATION 1047 return; 1048 #endif 1049 1050 1051 newtmeshvert(u, v); 1052 } 1053 1054 /*------------------------------------------------------------------------- 1055 * evalpoint2i - evaluate a grid point 1056 *------------------------------------------------------------------------- 1057 */ 1058 void 1059 OpenGLSurfaceEvaluator::evalpoint2i(long u, long v) 1060 { 1061 #ifdef NO_EVALUATION 1062 return; 1063 #endif 1064 1065 newtmeshvert(u, v); 1066 } 1067 1068 void 1069 OpenGLSurfaceEvaluator::point2i( long u, long v ) 1070 { 1071 #ifdef NO_EVALUATION 1072 return; 1073 #else 1074 1075 #ifdef USE_INTERNAL_EVAL 1076 inEvalPoint2( (int)u, (int)v); 1077 #else 1078 1079 1080 if(output_triangles) 1081 { 1082 1083 REAL du, dv; 1084 REAL fu,fv; 1085 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; 1086 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; 1087 fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du); 1088 fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv); 1089 coord2f(fu,fv); 1090 } 1091 else 1092 glEvalPoint2((GLint) u, (GLint) v); 1093 1094 1095 #endif 1096 1097 #ifdef STATISTICS 1098 STAT_num_of_eval_vertices++; 1099 #endif 1100 1101 #endif 1102 1103 } 1104 1105 void 1106 OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v ) 1107 { 1108 #ifdef NO_EVALUATION 1109 return; 1110 #else 1111 1112 #ifdef USE_INTERNAL_EVAL 1113 inEvalCoord2f( u, v); 1114 #else 1115 1116 1117 if(output_triangles) 1118 bezierPatchMeshInsertUV(global_bpm, u,v); 1119 else 1120 glEvalCoord2f((GLfloat) u, (GLfloat) v); 1121 1122 1123 #endif 1124 1125 1126 #ifdef STATISTICS 1127 STAT_num_of_eval_vertices++; 1128 #endif 1129 1130 #endif 1131 } 1132 1133 void 1134 OpenGLSurfaceEvaluator::newtmeshvert( long u, long v ) 1135 { 1136 #ifdef NO_EVALUATION 1137 return; 1138 #else 1139 1140 if (tmeshing) { 1141 1142 if (vcount == 2) { 1143 vertexCache[0]->invoke(this); 1144 vertexCache[1]->invoke(this); 1145 point2i( u, v); 1146 1147 } else { 1148 vcount++; 1149 } 1150 1151 vertexCache[which]->saveEvalPoint(u, v); 1152 which = 1 - which; 1153 } else { 1154 point2i( u, v); 1155 } 1156 #endif 1157 } 1158 1159 void 1160 OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v ) 1161 { 1162 #ifdef NO_EVALUATION 1163 return; 1164 #else 1165 if (tmeshing) { 1166 1167 1168 if (vcount == 2) { 1169 vertexCache[0]->invoke(this); 1170 vertexCache[1]->invoke(this); 1171 coord2f(u,v); 1172 1173 } else { 1174 vcount++; 1175 } 1176 1177 vertexCache[which]->saveEvalCoord(u, v); 1178 which = 1 - which; 1179 } else { 1180 1181 coord2f( u, v); 1182 } 1183 #endif 1184 1185 } 1186 1187 #ifdef _WIN32 1188 void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)() ) 1189 #else 1190 void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn ) 1191 #endif 1192 { 1193 switch(which) 1194 { 1195 case GLU_NURBS_BEGIN: 1196 beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn; 1197 break; 1198 case GLU_NURBS_END: 1199 endCallBackN = (void (GLAPIENTRY *) (void)) fn; 1200 break; 1201 case GLU_NURBS_VERTEX: 1202 vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 1203 break; 1204 case GLU_NURBS_NORMAL: 1205 normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 1206 break; 1207 case GLU_NURBS_COLOR: 1208 colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 1209 break; 1210 case GLU_NURBS_TEXTURE_COORD: 1211 texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 1212 break; 1213 case GLU_NURBS_BEGIN_DATA: 1214 beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn; 1215 break; 1216 case GLU_NURBS_END_DATA: 1217 endCallBackData = (void (GLAPIENTRY *) (void*)) fn; 1218 break; 1219 case GLU_NURBS_VERTEX_DATA: 1220 vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 1221 break; 1222 case GLU_NURBS_NORMAL_DATA: 1223 normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 1224 break; 1225 case GLU_NURBS_COLOR_DATA: 1226 colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 1227 break; 1228 case GLU_NURBS_TEXTURE_COORD_DATA: 1229 texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 1230 break; 1231 1232 } 1233 } 1234 1235 1236 void 1237 OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data) 1238 { 1239 if(beginCallBackData) 1240 beginCallBackData(which, data); 1241 else if(beginCallBackN) 1242 beginCallBackN(which); 1243 } 1244 1245 void 1246 OpenGLSurfaceEvaluator::endCallBack(void *data) 1247 { 1248 if(endCallBackData) 1249 endCallBackData(data); 1250 else if(endCallBackN) 1251 endCallBackN(); 1252 } 1253 1254 void 1255 OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data) 1256 { 1257 if(vertexCallBackData) 1258 vertexCallBackData(vert, data); 1259 else if(vertexCallBackN) 1260 vertexCallBackN(vert); 1261 } 1262 1263 1264 void 1265 OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data) 1266 { 1267 if(normalCallBackData) 1268 normalCallBackData(normal, data); 1269 else if(normalCallBackN) 1270 normalCallBackN(normal); 1271 } 1272 1273 void 1274 OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data) 1275 { 1276 if(colorCallBackData) 1277 colorCallBackData(color, data); 1278 else if(colorCallBackN) 1279 colorCallBackN(color); 1280 } 1281 1282 void 1283 OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data) 1284 { 1285 if(texcoordCallBackData) 1286 texcoordCallBackData(texcoord, data); 1287 else if(texcoordCallBackN) 1288 texcoordCallBackN(texcoord); 1289 } 1290 1291 1292 1293 1294