ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

glsurfeval.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.