Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenglsurfeval.cc
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 */ 00034 00035 /* 00036 * glsurfeval.c++ 00037 * 00038 */ 00039 00040 /* Polynomial Evaluator Interface */ 00041 #include "gluos.h" 00042 #include <stdio.h> 00043 #include "glimports.h" 00044 #include "glrenderer.h" 00045 #include "glsurfeval.h" 00046 #include "nurbsconsts.h" 00047 #include "bezierPatchMesh.h" 00048 00049 00050 //extern int surfcount; 00051 //int surfcount=0; 00052 00053 /*#define USE_INTERNAL_EVAL*/ //use internal evaluator 00054 00055 /*whether do evaluation or not*/ 00056 /*#define NO_EVALUATION*/ 00057 00058 //#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too 00059 00060 /*for statistics*/ 00061 //#define STATISTICS 00062 #ifdef STATISTICS 00063 static int STAT_num_of_triangles=0; 00064 static int STAT_num_of_eval_vertices=0; 00065 static int STAT_num_of_quad_strips=0; 00066 #endif 00067 00068 /*for output triangles*/ 00069 /*#define OUTPUT_TRIANGLES*/ 00070 00071 00072 /*#define FOR_CHRIS*/ 00073 #ifdef FOR_CHRIS 00074 extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val, 00075 int n_lower, REAL v_lower, REAL* lower_val);} 00076 00077 extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val, 00078 int n_right, REAL u_right, REAL* right_val); 00079 } 00080 #endif 00081 00082 00083 /**************begin for LOD_eval_list***********/ 00084 void OpenGLSurfaceEvaluator::LOD_eval_list(int level) 00085 { 00086 if(level == 0) 00087 LOD_eval_level = 1; 00088 else if(level == 1) 00089 LOD_eval_level = 2; 00090 else if(level == 2) 00091 LOD_eval_level = 4; 00092 else 00093 LOD_eval_level = 8; 00094 00095 inBPMListEvalEM(global_bpm); 00096 } 00097 00098 00099 OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator() 00100 { 00101 int i; 00102 00103 for (i=0; i<VERTEX_CACHE_SIZE; i++) { 00104 vertexCache[i] = new StoredVertex; 00105 } 00106 tmeshing = 0; 00107 which = 0; 00108 vcount = 0; 00109 00110 global_uorder = 0; 00111 global_vorder = 0; 00112 global_uprime = -1.0; 00113 global_vprime = -1.0; 00114 global_vprime_BV = -1.0; 00115 global_uprime_BU = -1.0; 00116 global_uorder_BU = 0; 00117 global_vorder_BU = 0; 00118 global_uorder_BV = 0; 00119 global_vorder_BV = 0; 00120 global_baseData = NULL; 00121 00122 global_bpm = NULL; 00123 output_triangles = 0; //don't output triangles by default 00124 00125 //no default callback functions 00126 beginCallBackN = NULL; 00127 endCallBackN = NULL; 00128 vertexCallBackN = NULL; 00129 normalCallBackN = NULL; 00130 colorCallBackN = NULL; 00131 texcoordCallBackN = NULL; 00132 beginCallBackData = NULL; 00133 endCallBackData = NULL; 00134 vertexCallBackData = NULL; 00135 normalCallBackData = NULL; 00136 colorCallBackData = NULL; 00137 texcoordCallBackData = NULL; 00138 00139 userData = NULL; 00140 00141 auto_normal_flag = 0; 00142 callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0 00143 vertex_flag = 0; 00144 normal_flag = 0; 00145 color_flag = 0; 00146 texcoord_flag = 0; 00147 00148 em_vertex.uprime = -1.0; 00149 em_vertex.vprime = -1.0; 00150 em_normal.uprime = -1.0; 00151 em_normal.vprime = -1.0; 00152 em_color.uprime = -1.0; 00153 em_color.vprime = -1.0; 00154 em_texcoord.uprime = -1.0; 00155 em_texcoord.vprime = -1.0; 00156 00157 #ifdef USE_LOD 00158 LOD_eval_level = 1; 00159 #endif 00160 } 00161 00162 OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator() 00163 { 00164 for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) { 00165 delete vertexCache[ii]; 00166 vertexCache[ii]= 0; 00167 } 00168 } 00169 00170 /*--------------------------------------------------------------------------- 00171 * disable - turn off a map 00172 *--------------------------------------------------------------------------- 00173 */ 00174 void 00175 OpenGLSurfaceEvaluator::disable(long type) 00176 { 00177 glDisable((GLenum) type); 00178 } 00179 00180 /*--------------------------------------------------------------------------- 00181 * enable - turn on a map 00182 *--------------------------------------------------------------------------- 00183 */ 00184 void 00185 OpenGLSurfaceEvaluator::enable(long type) 00186 { 00187 glEnable((GLenum) type); 00188 } 00189 00190 /*------------------------------------------------------------------------- 00191 * mapgrid2f - define a lattice of points with origin and offset 00192 *------------------------------------------------------------------------- 00193 */ 00194 void 00195 OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1) 00196 { 00197 #ifdef USE_INTERNAL_EVAL 00198 inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv, 00199 (REAL) v0, (REAL) v1); 00200 #else 00201 00202 if(output_triangles) 00203 { 00204 global_grid_u0 = u0; 00205 global_grid_u1 = u1; 00206 global_grid_nu = nu; 00207 global_grid_v0 = v0; 00208 global_grid_v1 = v1; 00209 global_grid_nv = nv; 00210 } 00211 else 00212 glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv, 00213 (GLdouble) v0, (GLdouble) v1); 00214 00215 #endif 00216 } 00217 00218 void 00219 OpenGLSurfaceEvaluator::polymode(long style) 00220 { 00221 if(! output_triangles) 00222 { 00223 switch(style) { 00224 default: 00225 case N_MESHFILL: 00226 00227 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL); 00228 break; 00229 case N_MESHLINE: 00230 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE); 00231 break; 00232 case N_MESHPOINT: 00233 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT); 00234 break; 00235 } 00236 } 00237 } 00238 00239 void 00240 OpenGLSurfaceEvaluator::bgnline(void) 00241 { 00242 if(output_triangles) 00243 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP); 00244 else 00245 glBegin((GLenum) GL_LINE_STRIP); 00246 } 00247 00248 void 00249 OpenGLSurfaceEvaluator::endline(void) 00250 { 00251 if(output_triangles) 00252 bezierPatchMeshEndStrip(global_bpm); 00253 else 00254 glEnd(); 00255 } 00256 00257 void 00258 OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to) 00259 { 00260 } 00261 00262 void 00263 OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi) 00264 { 00265 } 00266 00267 void 00268 OpenGLSurfaceEvaluator::bgnclosedline(void) 00269 { 00270 if(output_triangles) 00271 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP); 00272 else 00273 glBegin((GLenum) GL_LINE_LOOP); 00274 } 00275 00276 void 00277 OpenGLSurfaceEvaluator::endclosedline(void) 00278 { 00279 if(output_triangles) 00280 bezierPatchMeshEndStrip(global_bpm); 00281 else 00282 glEnd(); 00283 } 00284 00285 00286 00287 00288 00289 void 00290 OpenGLSurfaceEvaluator::bgntmesh(void) 00291 { 00292 00293 tmeshing = 1; 00294 which = 0; 00295 vcount = 0; 00296 00297 if(output_triangles) 00298 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES); 00299 else 00300 glBegin((GLenum) GL_TRIANGLES); 00301 00302 } 00303 00304 void 00305 OpenGLSurfaceEvaluator::swaptmesh(void) 00306 { 00307 which = 1 - which; 00308 00309 } 00310 00311 void 00312 OpenGLSurfaceEvaluator::endtmesh(void) 00313 { 00314 tmeshing = 0; 00315 00316 00317 if(output_triangles) 00318 bezierPatchMeshEndStrip(global_bpm); 00319 else 00320 glEnd(); 00321 } 00322 00323 void 00324 OpenGLSurfaceEvaluator::bgntfan(void) 00325 { 00326 00327 if(output_triangles) 00328 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN); 00329 else 00330 glBegin((GLenum) GL_TRIANGLE_FAN); 00331 00332 } 00333 void 00334 OpenGLSurfaceEvaluator::endtfan(void) 00335 { 00336 if(output_triangles) 00337 bezierPatchMeshEndStrip(global_bpm); 00338 else 00339 glEnd(); 00340 } 00341 00342 void 00343 OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) 00344 { 00345 #ifdef USE_INTERNAL_EVAL 00346 inEvalUStrip(n_upper, v_upper, upper_val, 00347 n_lower, v_lower, lower_val); 00348 #else 00349 00350 #ifdef FOR_CHRIS 00351 evalUStripExt(n_upper, v_upper, upper_val, 00352 n_lower, v_lower, lower_val); 00353 return; 00354 00355 #endif 00356 int i,j,k,l; 00357 REAL leftMostV[2]; 00358 00359 /* 00360 *the algorithm works by scanning from left to right. 00361 *leftMostV: the left most of the remaining verteces (on both upper and lower). 00362 * it could an element of upperVerts or lowerVerts. 00363 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line 00364 *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line 00365 */ 00366 00367 /*initialize i,j,and leftMostV 00368 */ 00369 if(upper_val[0] <= lower_val[0]) 00370 { 00371 i=1; 00372 j=0; 00373 00374 leftMostV[0] = upper_val[0]; 00375 leftMostV[1] = v_upper; 00376 } 00377 else 00378 { 00379 i=0; 00380 j=1; 00381 00382 leftMostV[0] = lower_val[0]; 00383 leftMostV[1] = v_lower; 00384 00385 } 00386 00387 /*the main loop. 00388 *the invariance is that: 00389 *at the beginning of each loop, the meaning of i,j,and leftMostV are 00390 *maintained 00391 */ 00392 while(1) 00393 { 00394 if(i >= n_upper) /*case1: no more in upper*/ 00395 { 00396 if(j<n_lower-1) /*at least two vertices in lower*/ 00397 { 00398 bgntfan(); 00399 coord2f(leftMostV[0], leftMostV[1]); 00400 // glNormal3fv(leftMostNormal); 00401 // glVertex3fv(leftMostXYZ); 00402 00403 while(j<n_lower){ 00404 coord2f(lower_val[j], v_lower); 00405 // glNormal3fv(lowerNormal[j]); 00406 // glVertex3fv(lowerXYZ[j]); 00407 j++; 00408 00409 } 00410 endtfan(); 00411 } 00412 break; /*exit the main loop*/ 00413 } 00414 else if(j>= n_lower) /*case2: no more in lower*/ 00415 { 00416 if(i<n_upper-1) /*at least two vertices in upper*/ 00417 { 00418 bgntfan(); 00419 coord2f(leftMostV[0], leftMostV[1]); 00420 // glNormal3fv(leftMostNormal); 00421 // glVertex3fv(leftMostXYZ); 00422 00423 for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ 00424 { 00425 coord2f(upper_val[k], v_upper); 00426 // glNormal3fv(upperNormal[k]); 00427 // glVertex3fv(upperXYZ[k]); 00428 } 00429 00430 endtfan(); 00431 } 00432 break; /*exit the main loop*/ 00433 } 00434 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ 00435 { 00436 if(upper_val[i] <= lower_val[j]) 00437 { 00438 bgntfan(); 00439 coord2f(lower_val[j], v_lower); 00440 // glNormal3fv(lowerNormal[j]); 00441 // glVertex3fv(lowerXYZ[j]); 00442 00443 /*find the last k>=i such that 00444 *upperverts[k][0] <= lowerverts[j][0] 00445 */ 00446 k=i; 00447 00448 while(k<n_upper) 00449 { 00450 if(upper_val[k] > lower_val[j]) 00451 break; 00452 k++; 00453 00454 } 00455 k--; 00456 00457 00458 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ 00459 { 00460 coord2f(upper_val[l], v_upper); 00461 // glNormal3fv(upperNormal[l]); 00462 // glVertex3fv(upperXYZ[l]); 00463 00464 } 00465 coord2f(leftMostV[0], leftMostV[1]); 00466 // glNormal3fv(leftMostNormal); 00467 // glVertex3fv(leftMostXYZ); 00468 00469 endtfan(); 00470 00471 /*update i and leftMostV for next loop 00472 */ 00473 i = k+1; 00474 00475 leftMostV[0] = upper_val[k]; 00476 leftMostV[1] = v_upper; 00477 // leftMostNormal = upperNormal[k]; 00478 // leftMostXYZ = upperXYZ[k]; 00479 } 00480 else /*upperVerts[i][0] > lowerVerts[j][0]*/ 00481 { 00482 bgntfan(); 00483 coord2f(upper_val[i], v_upper); 00484 // glNormal3fv(upperNormal[i]); 00485 // glVertex3fv(upperXYZ[i]); 00486 00487 coord2f(leftMostV[0], leftMostV[1]); 00488 // glNormal3fv(leftMostNormal); 00489 // glVertex3fv(leftMostXYZ); 00490 00491 00492 /*find the last k>=j such that 00493 *lowerverts[k][0] < upperverts[i][0] 00494 */ 00495 k=j; 00496 while(k< n_lower) 00497 { 00498 if(lower_val[k] >= upper_val[i]) 00499 break; 00500 coord2f(lower_val[k], v_lower); 00501 // glNormal3fv(lowerNormal[k]); 00502 // glVertex3fv(lowerXYZ[k]); 00503 00504 k++; 00505 } 00506 endtfan(); 00507 00508 /*update j and leftMostV for next loop 00509 */ 00510 j=k; 00511 leftMostV[0] = lower_val[j-1]; 00512 leftMostV[1] = v_lower; 00513 00514 // leftMostNormal = lowerNormal[j-1]; 00515 // leftMostXYZ = lowerXYZ[j-1]; 00516 } 00517 } 00518 } 00519 //clean up 00520 // free(upperXYZ); 00521 // free(lowerXYZ); 00522 // free(upperNormal); 00523 // free(lowerNormal); 00524 #endif 00525 00526 } 00527 00528 00529 void 00530 OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) 00531 { 00532 #ifdef USE_INTERNAL_EVAL 00533 inEvalVStrip(n_left, u_left, left_val, 00534 n_right, u_right, right_val); 00535 #else 00536 00537 #ifdef FOR_CHRIS 00538 evalVStripExt(n_left, u_left, left_val, 00539 n_right, u_right, right_val); 00540 return; 00541 00542 #endif 00543 00544 int i,j,k,l; 00545 REAL botMostV[2]; 00546 /* 00547 *the algorithm works by scanning from bot to top. 00548 *botMostV: the bot most of the remaining verteces (on both left and right). 00549 * it could an element of leftVerts or rightVerts. 00550 *i: leftVerts[i] is the first vertex to the top of botMostV on left line 00551 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline 00552 */ 00553 00554 /*initialize i,j,and botMostV 00555 */ 00556 if(left_val[0] <= right_val[0]) 00557 { 00558 i=1; 00559 j=0; 00560 00561 botMostV[0] = u_left; 00562 botMostV[1] = left_val[0]; 00563 } 00564 else 00565 { 00566 i=0; 00567 j=1; 00568 00569 botMostV[0] = u_right; 00570 botMostV[1] = right_val[0]; 00571 } 00572 00573 /*the main loop. 00574 *the invariance is that: 00575 *at the beginning of each loop, the meaning of i,j,and botMostV are 00576 *maintained 00577 */ 00578 while(1) 00579 { 00580 if(i >= n_left) /*case1: no more in left*/ 00581 { 00582 if(j<n_right-1) /*at least two vertices in right*/ 00583 { 00584 bgntfan(); 00585 coord2f(botMostV[0], botMostV[1]); 00586 while(j<n_right){ 00587 coord2f(u_right, right_val[j]); 00588 // glNormal3fv(rightNormal[j]); 00589 // glVertex3fv(rightXYZ[j]); 00590 j++; 00591 00592 } 00593 endtfan(); 00594 } 00595 break; /*exit the main loop*/ 00596 } 00597 else if(j>= n_right) /*case2: no more in right*/ 00598 { 00599 if(i<n_left-1) /*at least two vertices in left*/ 00600 { 00601 bgntfan(); 00602 coord2f(botMostV[0], botMostV[1]); 00603 // glNormal3fv(botMostNormal); 00604 // glVertex3fv(botMostXYZ); 00605 00606 for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ 00607 { 00608 coord2f(u_left, left_val[k]); 00609 // glNormal3fv(leftNormal[k]); 00610 // glVertex3fv(leftXYZ[k]); 00611 } 00612 00613 endtfan(); 00614 } 00615 break; /*exit the main loop*/ 00616 } 00617 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ 00618 { 00619 if(left_val[i] <= right_val[j]) 00620 { 00621 bgntfan(); 00622 coord2f(u_right, right_val[j]); 00623 // glNormal3fv(rightNormal[j]); 00624 // glVertex3fv(rightXYZ[j]); 00625 00626 /*find the last k>=i such that 00627 *leftverts[k][0] <= rightverts[j][0] 00628 */ 00629 k=i; 00630 00631 while(k<n_left) 00632 { 00633 if(left_val[k] > right_val[j]) 00634 break; 00635 k++; 00636 00637 } 00638 k--; 00639 00640 00641 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ 00642 { 00643 coord2f(u_left, left_val[l]); 00644 // glNormal3fv(leftNormal[l]); 00645 // glVertex3fv(leftXYZ[l]); 00646 00647 } 00648 coord2f(botMostV[0], botMostV[1]); 00649 // glNormal3fv(botMostNormal); 00650 // glVertex3fv(botMostXYZ); 00651 00652 endtfan(); 00653 00654 /*update i and botMostV for next loop 00655 */ 00656 i = k+1; 00657 00658 botMostV[0] = u_left; 00659 botMostV[1] = left_val[k]; 00660 // botMostNormal = leftNormal[k]; 00661 // botMostXYZ = leftXYZ[k]; 00662 } 00663 else /*left_val[i] > right_val[j])*/ 00664 { 00665 bgntfan(); 00666 coord2f(u_left, left_val[i]); 00667 // glNormal3fv(leftNormal[i]); 00668 // glVertex3fv(leftXYZ[i]); 00669 00670 coord2f(botMostV[0], botMostV[1]); 00671 // glNormal3fv(botMostNormal); 00672 // glVertex3fv(botMostXYZ); 00673 00674 00675 /*find the last k>=j such that 00676 *rightverts[k][0] < leftverts[i][0] 00677 */ 00678 k=j; 00679 while(k< n_right) 00680 { 00681 if(right_val[k] >= left_val[i]) 00682 break; 00683 coord2f(u_right, right_val[k]); 00684 // glNormal3fv(rightNormal[k]); 00685 // glVertex3fv(rightXYZ[k]); 00686 00687 k++; 00688 } 00689 endtfan(); 00690 00691 /*update j and botMostV for next loop 00692 */ 00693 j=k; 00694 botMostV[0] = u_right; 00695 botMostV[1] = right_val[j-1]; 00696 00697 // botMostNormal = rightNormal[j-1]; 00698 // botMostXYZ = rightXYZ[j-1]; 00699 } 00700 } 00701 } 00702 //clean up 00703 // free(leftXYZ); 00704 // free(leftNormal); 00705 // free(rightXYZ); 00706 // free(rightNormal); 00707 #endif 00708 } 00709 00710 00711 void 00712 OpenGLSurfaceEvaluator::bgnqstrip(void) 00713 { 00714 if(output_triangles) 00715 bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP); 00716 else 00717 glBegin((GLenum) GL_QUAD_STRIP); 00718 00719 #ifdef STATISTICS 00720 STAT_num_of_quad_strips++; 00721 #endif 00722 } 00723 00724 void 00725 OpenGLSurfaceEvaluator::endqstrip(void) 00726 { 00727 if(output_triangles) 00728 bezierPatchMeshEndStrip(global_bpm); 00729 else 00730 glEnd(); 00731 00732 } 00733 00734 /*------------------------------------------------------------------------- 00735 * bgnmap2f - preamble to surface definition and evaluations 00736 *------------------------------------------------------------------------- 00737 */ 00738 void 00739 OpenGLSurfaceEvaluator::bgnmap2f(long) 00740 { 00741 if(output_triangles) 00742 { 00743 /*deallocate the space which may has been 00744 *allocated by global_bpm previously 00745 */ 00746 if(global_bpm != NULL) { 00747 bezierPatchMeshListDelete(global_bpm); 00748 global_bpm = NULL; 00749 } 00750 00751 00752 /* 00753 auto_normal_flag = 1; //always output normal in callback mode. 00754 //we could have used the following code, 00755 //but Inspector doesn't have gl context 00756 //before it calls tessellator. 00757 //this way is temporary. 00758 */ 00759 //NEWCALLBACK 00760 //if one of the two normal callback functions are set, 00761 //then set 00762 if(normalCallBackN != NULL || 00763 normalCallBackData != NULL) 00764 auto_normal_flag = 1; 00765 else 00766 auto_normal_flag = 0; 00767 00768 //initialize so that no maps initially 00769 vertex_flag = 0; 00770 normal_flag = 0; 00771 color_flag = 0; 00772 texcoord_flag = 0; 00773 00774 /* 00775 if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE) 00776 auto_normal_flag = 1; 00777 else if (callback_auto_normal == 1) 00778 auto_normal_flag = 1; 00779 else 00780 auto_normal_flag = 0; 00781 */ 00782 00783 //NEWCALLBACK: no need to worry about gl states when gling clalback 00784 } 00785 else 00786 { 00787 glPushAttrib((GLbitfield) GL_EVAL_BIT); 00788 00789 /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE 00790 */ 00791 glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode); 00792 } 00793 00794 } 00795 00796 /*------------------------------------------------------------------------- 00797 * endmap2f - postamble to a map 00798 *------------------------------------------------------------------------- 00799 */ 00800 void 00801 OpenGLSurfaceEvaluator::endmap2f(void) 00802 { 00803 00804 if(output_triangles) 00805 { 00806 //bezierPatchMeshListDelDeg(global_bpm); 00807 00808 // bezierPatchMeshListEval(global_bpm); 00809 00810 //surfcount++; 00811 //printf("surfcount=%i\n", surfcount); 00812 //if(surfcount == 8) exit(0); 00813 00814 inBPMListEvalEM(global_bpm); 00815 00816 00817 00818 /* 00819 global_bpm = bezierPatchMeshListReverse(global_bpm); 00820 { 00821 float *vertex_array; 00822 float *normal_array; 00823 int *length_array; 00824 int *type_array; 00825 int num_strips; 00826 bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips); 00827 drawStrips(vertex_array, normal_array, length_array, type_array, num_strips); 00828 free(vertex_array); 00829 free(normal_array); 00830 free(length_array); 00831 free(type_array); 00832 } 00833 */ 00834 00835 //bezierPatchMeshListPrint(global_bpm); 00836 //bezierPatchMeshListDraw(global_bpm); 00837 00838 // printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm)); 00839 00840 #ifdef USE_LOD 00841 #else 00842 bezierPatchMeshListDelete(global_bpm); 00843 global_bpm = NULL; 00844 #endif 00845 00846 } 00847 else 00848 { 00849 #ifndef USE_LOD 00850 glPopAttrib(); 00851 #endif 00852 00853 #ifdef STATISTICS 00854 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); 00855 #endif 00856 00857 /*to restore the gl_polygon_mode 00858 */ 00859 #ifndef USE_LOD 00860 glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]); 00861 glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]); 00862 #endif 00863 } 00864 00865 } 00866 00867 /*------------------------------------------------------------------------- 00868 * map2f - pass a desription of a surface map 00869 *------------------------------------------------------------------------- 00870 */ 00871 void 00872 OpenGLSurfaceEvaluator::map2f( 00873 long _type, 00874 REAL _ulower, /* u lower domain coord */ 00875 REAL _uupper, /* u upper domain coord */ 00876 long _ustride, /* interpoint distance */ 00877 long _uorder, /* parametric order */ 00878 REAL _vlower, /* v lower domain coord */ 00879 REAL _vupper, /* v upper domain coord */ 00880 long _vstride, /* interpoint distance */ 00881 long _vorder, /* parametric order */ 00882 REAL *pts) /* control points */ 00883 { 00884 #ifdef USE_INTERNAL_EVAL 00885 inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper, 00886 (int) _ustride, (int) _uorder, (REAL) _vlower, 00887 (REAL) _vupper, (int) _vstride, (int) _vorder, 00888 (REAL *) pts); 00889 #else 00890 00891 00892 00893 if(output_triangles) 00894 { 00895 if(global_bpm == NULL) 00896 global_bpm = bezierPatchMeshMake2(10,10); 00897 if( 00898 (global_bpm->bpatch == NULL && 00899 (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4)) 00900 || 00901 (global_bpm->bpatch_normal == NULL && 00902 (_type == GL_MAP2_NORMAL)) 00903 || 00904 (global_bpm->bpatch_color == NULL && 00905 (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4)) 00906 || 00907 (global_bpm->bpatch_texcoord == NULL && 00908 (_type == GL_MAP2_TEXTURE_COORD_1 || 00909 _type == GL_MAP2_TEXTURE_COORD_2 || 00910 _type == GL_MAP2_TEXTURE_COORD_3 || 00911 _type == GL_MAP2_TEXTURE_COORD_4 ) 00912 )) 00913 { 00914 bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); 00915 } 00916 else /*new surface patch (with multiple maps) starts*/ 00917 { 00918 bezierPatchMesh *temp = bezierPatchMeshMake2(10,10); 00919 bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); 00920 global_bpm = bezierPatchMeshListInsert(global_bpm, temp); 00921 00922 /* 00923 global_bpm = bezierPatchMeshListInsert(global_bpm, 00924 bezierPatchMeshMake( 00925 (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10)); 00926 */ 00927 } 00928 } 00929 else /*not output triangles*/ 00930 { 00931 glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper, 00932 (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower, 00933 (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder, 00934 (const GLfloat *) pts); 00935 } 00936 00937 #endif 00938 } 00939 00940 00941 /*------------------------------------------------------------------------- 00942 * mapmesh2f - evaluate a mesh of points on lattice 00943 *------------------------------------------------------------------------- 00944 */ 00945 void 00946 OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax) 00947 { 00948 #ifdef NO_EVALUATION 00949 return; 00950 #endif 00951 00952 #ifdef USE_INTERNAL_EVAL 00953 inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax); 00954 #else 00955 00956 00957 00958 if(output_triangles) 00959 { 00960 #ifdef USE_LOD 00961 bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON); 00962 bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0); 00963 bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1); 00964 bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv); 00965 bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin); 00966 bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax); 00967 bezierPatchMeshEndStrip(global_bpm); 00968 00969 #else 00970 00971 REAL du, dv; 00972 long i,j; 00973 if(global_grid_nu == 0 || global_grid_nv == 0) 00974 return; /*no points need to be output*/ 00975 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; 00976 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; 00977 00978 if(global_grid_nu >= global_grid_nv){ 00979 00980 for(i=umin; i<umax; i++){ 00981 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); 00982 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du); 00983 00984 bgnqstrip(); 00985 for(j=vmax; j>=vmin; j--){ 00986 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); 00987 00988 coord2f(u1, v1); 00989 coord2f(u2, v1); 00990 } 00991 endqstrip(); 00992 } 00993 } 00994 else{ 00995 00996 for(i=vmin; i<vmax; i++){ 00997 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv); 00998 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv); 00999 01000 bgnqstrip(); 01001 for(j=umax; j>=umin; j--){ 01002 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); 01003 coord2f(u1, v2); 01004 coord2f(u1, v1); 01005 } 01006 endqstrip(); 01007 } 01008 } 01009 #endif 01010 } 01011 else 01012 { 01013 switch(style) { 01014 default: 01015 case N_MESHFILL: 01016 glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax, 01017 (GLint) vmin, (GLint) vmax); 01018 break; 01019 case N_MESHLINE: 01020 glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax, 01021 (GLint) vmin, (GLint) vmax); 01022 break; 01023 case N_MESHPOINT: 01024 glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax, 01025 (GLint) vmin, (GLint) vmax); 01026 break; 01027 } 01028 } 01029 01030 #endif 01031 01032 #ifdef STATISTICS 01033 STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin); 01034 #endif 01035 } 01036 01037 /*------------------------------------------------------------------------- 01038 * evalcoord2f - evaluate a point on a surface 01039 *------------------------------------------------------------------------- 01040 */ 01041 void 01042 OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v) 01043 { 01044 01045 01046 #ifdef NO_EVALUATION 01047 return; 01048 #endif 01049 01050 01051 newtmeshvert(u, v); 01052 } 01053 01054 /*------------------------------------------------------------------------- 01055 * evalpoint2i - evaluate a grid point 01056 *------------------------------------------------------------------------- 01057 */ 01058 void 01059 OpenGLSurfaceEvaluator::evalpoint2i(long u, long v) 01060 { 01061 #ifdef NO_EVALUATION 01062 return; 01063 #endif 01064 01065 newtmeshvert(u, v); 01066 } 01067 01068 void 01069 OpenGLSurfaceEvaluator::point2i( long u, long v ) 01070 { 01071 #ifdef NO_EVALUATION 01072 return; 01073 #else 01074 01075 #ifdef USE_INTERNAL_EVAL 01076 inEvalPoint2( (int)u, (int)v); 01077 #else 01078 01079 01080 if(output_triangles) 01081 { 01082 01083 REAL du, dv; 01084 REAL fu,fv; 01085 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; 01086 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; 01087 fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du); 01088 fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv); 01089 coord2f(fu,fv); 01090 } 01091 else 01092 glEvalPoint2((GLint) u, (GLint) v); 01093 01094 01095 #endif 01096 01097 #ifdef STATISTICS 01098 STAT_num_of_eval_vertices++; 01099 #endif 01100 01101 #endif 01102 01103 } 01104 01105 void 01106 OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v ) 01107 { 01108 #ifdef NO_EVALUATION 01109 return; 01110 #else 01111 01112 #ifdef USE_INTERNAL_EVAL 01113 inEvalCoord2f( u, v); 01114 #else 01115 01116 01117 if(output_triangles) 01118 bezierPatchMeshInsertUV(global_bpm, u,v); 01119 else 01120 glEvalCoord2f((GLfloat) u, (GLfloat) v); 01121 01122 01123 #endif 01124 01125 01126 #ifdef STATISTICS 01127 STAT_num_of_eval_vertices++; 01128 #endif 01129 01130 #endif 01131 } 01132 01133 void 01134 OpenGLSurfaceEvaluator::newtmeshvert( long u, long v ) 01135 { 01136 #ifdef NO_EVALUATION 01137 return; 01138 #else 01139 01140 if (tmeshing) { 01141 01142 if (vcount == 2) { 01143 vertexCache[0]->invoke(this); 01144 vertexCache[1]->invoke(this); 01145 point2i( u, v); 01146 01147 } else { 01148 vcount++; 01149 } 01150 01151 vertexCache[which]->saveEvalPoint(u, v); 01152 which = 1 - which; 01153 } else { 01154 point2i( u, v); 01155 } 01156 #endif 01157 } 01158 01159 void 01160 OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v ) 01161 { 01162 #ifdef NO_EVALUATION 01163 return; 01164 #else 01165 if (tmeshing) { 01166 01167 01168 if (vcount == 2) { 01169 vertexCache[0]->invoke(this); 01170 vertexCache[1]->invoke(this); 01171 coord2f(u,v); 01172 01173 } else { 01174 vcount++; 01175 } 01176 01177 vertexCache[which]->saveEvalCoord(u, v); 01178 which = 1 - which; 01179 } else { 01180 01181 coord2f( u, v); 01182 } 01183 #endif 01184 01185 } 01186 01187 void 01188 OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn ) 01189 { 01190 switch(which) 01191 { 01192 case GLU_NURBS_BEGIN: 01193 beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn; 01194 break; 01195 case GLU_NURBS_END: 01196 endCallBackN = (void (GLAPIENTRY *) (void)) fn; 01197 break; 01198 case GLU_NURBS_VERTEX: 01199 vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 01200 break; 01201 case GLU_NURBS_NORMAL: 01202 normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 01203 break; 01204 case GLU_NURBS_COLOR: 01205 colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 01206 break; 01207 case GLU_NURBS_TEXTURE_COORD: 01208 texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; 01209 break; 01210 case GLU_NURBS_BEGIN_DATA: 01211 beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn; 01212 break; 01213 case GLU_NURBS_END_DATA: 01214 endCallBackData = (void (GLAPIENTRY *) (void*)) fn; 01215 break; 01216 case GLU_NURBS_VERTEX_DATA: 01217 vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 01218 break; 01219 case GLU_NURBS_NORMAL_DATA: 01220 normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 01221 break; 01222 case GLU_NURBS_COLOR_DATA: 01223 colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 01224 break; 01225 case GLU_NURBS_TEXTURE_COORD_DATA: 01226 texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; 01227 break; 01228 01229 } 01230 } 01231 01232 01233 void 01234 OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data) 01235 { 01236 if(beginCallBackData) 01237 beginCallBackData(which, data); 01238 else if(beginCallBackN) 01239 beginCallBackN(which); 01240 } 01241 01242 void 01243 OpenGLSurfaceEvaluator::endCallBack(void *data) 01244 { 01245 if(endCallBackData) 01246 endCallBackData(data); 01247 else if(endCallBackN) 01248 endCallBackN(); 01249 } 01250 01251 void 01252 OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data) 01253 { 01254 if(vertexCallBackData) 01255 vertexCallBackData(vert, data); 01256 else if(vertexCallBackN) 01257 vertexCallBackN(vert); 01258 } 01259 01260 01261 void 01262 OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data) 01263 { 01264 if(normalCallBackData) 01265 normalCallBackData(normal, data); 01266 else if(normalCallBackN) 01267 normalCallBackN(normal); 01268 } 01269 01270 void 01271 OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data) 01272 { 01273 if(colorCallBackData) 01274 colorCallBackData(color, data); 01275 else if(colorCallBackN) 01276 colorCallBackN(color); 01277 } 01278 01279 void 01280 OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data) 01281 { 01282 if(texcoordCallBackData) 01283 texcoordCallBackData(texcoord, data); 01284 else if(texcoordCallBackN) 01285 texcoordCallBackN(texcoord); 01286 } 01287 01288 01289 01290 Generated on Sat May 26 2012 04:22:14 for ReactOS by
1.7.6.1
|