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

tess.c
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 ** Author: Eric Veach, July 1994.
00037 **
00038 */
00039 
00040 #include "gluos.h"
00041 #include <stddef.h>
00042 #include <assert.h>
00043 #include <setjmp.h>
00044 #include "memalloc.h"
00045 #include "tess.h"
00046 #include "mesh.h"
00047 #include "normal.h"
00048 #include "sweep.h"
00049 #include "tessmono.h"
00050 #include "render.h"
00051 
00052 #define GLU_TESS_DEFAULT_TOLERANCE 0.0
00053 #define GLU_TESS_MESH       100112  /* void (*)(GLUmesh *mesh)      */
00054 
00055 #define TRUE 1
00056 #define FALSE 0
00057 
00058 /*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {}
00059 /*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {}
00060 /*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {}
00061 /*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {}
00062 /*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {}
00063 /*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4],
00064                     GLfloat weight[4], void **dataOut ) {}
00065 /*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {}
00066 
00067 
00068 /*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type,
00069                          void *polygonData ) {}
00070 /*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge,
00071                        void *polygonData ) {}
00072 /*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data,
00073                           void *polygonData ) {}
00074 /*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {}
00075 /*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum,
00076                          void *polygonData ) {}
00077 /*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3],
00078                            void *data[4],
00079                            GLfloat weight[4],
00080                            void **outData,
00081                            void *polygonData ) {}
00082 
00083 /* Half-edges are allocated in pairs (see mesh.c) */
00084 typedef struct { GLUhalfEdge e, eSym; } EdgePair;
00085 
00086 #undef  MAX
00087 #define MAX(a,b)    ((a) > (b) ? (a) : (b))
00088 #define MAX_FAST_ALLOC  (MAX(sizeof(EdgePair), \
00089                          MAX(sizeof(GLUvertex),sizeof(GLUface))))
00090 
00091 
00092 GLUtesselator * GLAPIENTRY
00093 gluNewTess( void )
00094 {
00095   GLUtesselator *tess;
00096 
00097   /* Only initialize fields which can be changed by the api.  Other fields
00098    * are initialized where they are used.
00099    */
00100 
00101   if (memInit( MAX_FAST_ALLOC ) == 0) {
00102      return 0;          /* out of memory */
00103   }
00104   tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator ));
00105   if (tess == NULL) {
00106      return 0;          /* out of memory */
00107   }
00108 
00109   tess->state = T_DORMANT;
00110 
00111   tess->normal[0] = 0;
00112   tess->normal[1] = 0;
00113   tess->normal[2] = 0;
00114 
00115   tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
00116   tess->windingRule = GLU_TESS_WINDING_ODD;
00117   tess->flagBoundary = FALSE;
00118   tess->boundaryOnly = FALSE;
00119 
00120   tess->callBegin = &noBegin;
00121   tess->callEdgeFlag = &noEdgeFlag;
00122   tess->callVertex = &noVertex;
00123   tess->callEnd = &noEnd;
00124 
00125   tess->callError = &noError;
00126   tess->callCombine = &noCombine;
00127   tess->callMesh = &noMesh;
00128 
00129   tess->callBeginData= &__gl_noBeginData;
00130   tess->callEdgeFlagData= &__gl_noEdgeFlagData;
00131   tess->callVertexData= &__gl_noVertexData;
00132   tess->callEndData= &__gl_noEndData;
00133   tess->callErrorData= &__gl_noErrorData;
00134   tess->callCombineData= &__gl_noCombineData;
00135 
00136   tess->polygonData= NULL;
00137 
00138   return tess;
00139 }
00140 
00141 static void MakeDormant( GLUtesselator *tess )
00142 {
00143   /* Return the tessellator to its original dormant state. */
00144 
00145   if( tess->mesh != NULL ) {
00146     __gl_meshDeleteMesh( tess->mesh );
00147   }
00148   tess->state = T_DORMANT;
00149   tess->lastEdge = NULL;
00150   tess->mesh = NULL;
00151 }
00152 
00153 #define RequireState( tess, s )   if( tess->state != s ) GotoState(tess,s)
00154 
00155 static void GotoState( GLUtesselator *tess, enum TessState newState )
00156 {
00157   while( tess->state != newState ) {
00158     /* We change the current state one level at a time, to get to
00159      * the desired state.
00160      */
00161     if( tess->state < newState ) {
00162       switch( tess->state ) {
00163       case T_DORMANT:
00164     CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON );
00165     gluTessBeginPolygon( tess, NULL );
00166     break;
00167       case T_IN_POLYGON:
00168     CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR );
00169     gluTessBeginContour( tess );
00170     break;
00171       default:
00172      ;
00173       }
00174     } else {
00175       switch( tess->state ) {
00176       case T_IN_CONTOUR:
00177     CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR );
00178     gluTessEndContour( tess );
00179     break;
00180       case T_IN_POLYGON:
00181     CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON );
00182     /* gluTessEndPolygon( tess ) is too much work! */
00183     MakeDormant( tess );
00184     break;
00185       default:
00186      ;
00187       }
00188     }
00189   }
00190 }
00191 
00192 
00193 void GLAPIENTRY
00194 gluDeleteTess( GLUtesselator *tess )
00195 {
00196   RequireState( tess, T_DORMANT );
00197   memFree( tess );
00198 }
00199 
00200 
00201 void GLAPIENTRY
00202 gluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value )
00203 {
00204   GLenum windingRule;
00205 
00206   switch( which ) {
00207   case GLU_TESS_TOLERANCE:
00208     if( value < 0.0 || value > 1.0 ) break;
00209     tess->relTolerance = value;
00210     return;
00211 
00212   case GLU_TESS_WINDING_RULE:
00213     windingRule = (GLenum) value;
00214     if( windingRule != value ) break;   /* not an integer */
00215 
00216     switch( windingRule ) {
00217     case GLU_TESS_WINDING_ODD:
00218     case GLU_TESS_WINDING_NONZERO:
00219     case GLU_TESS_WINDING_POSITIVE:
00220     case GLU_TESS_WINDING_NEGATIVE:
00221     case GLU_TESS_WINDING_ABS_GEQ_TWO:
00222       tess->windingRule = windingRule;
00223       return;
00224     default:
00225       break;
00226     }
00227 
00228   case GLU_TESS_BOUNDARY_ONLY:
00229     tess->boundaryOnly = (value != 0);
00230     return;
00231 
00232   default:
00233     CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
00234     return;
00235   }
00236   CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE );
00237 }
00238 
00239 /* Returns tessellator property */
00240 void GLAPIENTRY
00241 gluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value )
00242 {
00243    switch (which) {
00244    case GLU_TESS_TOLERANCE:
00245       /* tolerance should be in range [0..1] */
00246       assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0);
00247       *value= tess->relTolerance;
00248       break;
00249    case GLU_TESS_WINDING_RULE:
00250       assert(tess->windingRule == GLU_TESS_WINDING_ODD ||
00251          tess->windingRule == GLU_TESS_WINDING_NONZERO ||
00252          tess->windingRule == GLU_TESS_WINDING_POSITIVE ||
00253          tess->windingRule == GLU_TESS_WINDING_NEGATIVE ||
00254          tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO);
00255       *value= tess->windingRule;
00256       break;
00257    case GLU_TESS_BOUNDARY_ONLY:
00258       assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE);
00259       *value= tess->boundaryOnly;
00260       break;
00261    default:
00262       *value= 0.0;
00263       CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
00264       break;
00265    }
00266 } /* gluGetTessProperty() */
00267 
00268 void GLAPIENTRY
00269 gluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z )
00270 {
00271   tess->normal[0] = x;
00272   tess->normal[1] = y;
00273   tess->normal[2] = z;
00274 }
00275 
00276 void GLAPIENTRY
00277 gluTessCallback( GLUtesselator *tess, GLenum which, _GLUfuncptr fn)
00278 {
00279   switch( which ) {
00280   case GLU_TESS_BEGIN:
00281     tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn;
00282     return;
00283   case GLU_TESS_BEGIN_DATA:
00284     tess->callBeginData = (fn == NULL) ?
00285     &__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
00286     return;
00287   case GLU_TESS_EDGE_FLAG:
00288     tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag :
00289                     (void (GLAPIENTRY *)(GLboolean)) fn;
00290     /* If the client wants boundary edges to be flagged,
00291      * we render everything as separate triangles (no strips or fans).
00292      */
00293     tess->flagBoundary = (fn != NULL);
00294     return;
00295   case GLU_TESS_EDGE_FLAG_DATA:
00296     tess->callEdgeFlagData= (fn == NULL) ?
00297     &__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn;
00298     /* If the client wants boundary edges to be flagged,
00299      * we render everything as separate triangles (no strips or fans).
00300      */
00301     tess->flagBoundary = (fn != NULL);
00302     return;
00303   case GLU_TESS_VERTEX:
00304     tess->callVertex = (fn == NULL) ? &noVertex :
00305                       (void (GLAPIENTRY *)(void *)) fn;
00306     return;
00307   case GLU_TESS_VERTEX_DATA:
00308     tess->callVertexData = (fn == NULL) ?
00309     &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn;
00310     return;
00311   case GLU_TESS_END:
00312     tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn;
00313     return;
00314   case GLU_TESS_END_DATA:
00315     tess->callEndData = (fn == NULL) ? &__gl_noEndData :
00316                        (void (GLAPIENTRY *)(void *)) fn;
00317     return;
00318   case GLU_TESS_ERROR:
00319     tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn;
00320     return;
00321   case GLU_TESS_ERROR_DATA:
00322     tess->callErrorData = (fn == NULL) ?
00323     &__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
00324     return;
00325   case GLU_TESS_COMBINE:
00326     tess->callCombine = (fn == NULL) ? &noCombine :
00327     (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn;
00328     return;
00329   case GLU_TESS_COMBINE_DATA:
00330     tess->callCombineData = (fn == NULL) ? &__gl_noCombineData :
00331                        (void (GLAPIENTRY *)(GLdouble [3],
00332                              void *[4],
00333                              GLfloat [4],
00334                              void **,
00335                              void *)) fn;
00336     return;
00337   case GLU_TESS_MESH:
00338     tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn;
00339     return;
00340   default:
00341     CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
00342     return;
00343   }
00344 }
00345 
00346 static int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
00347 {
00348   GLUhalfEdge *e;
00349 
00350   e = tess->lastEdge;
00351   if( e == NULL ) {
00352     /* Make a self-loop (one vertex, one edge). */
00353 
00354     e = __gl_meshMakeEdge( tess->mesh );
00355     if (e == NULL) return 0;
00356     if ( !__gl_meshSplice( e, e->Sym ) ) return 0;
00357   } else {
00358     /* Create a new vertex and edge which immediately follow e
00359      * in the ordering around the left face.
00360      */
00361     if (__gl_meshSplitEdge( e ) == NULL) return 0;
00362     e = e->Lnext;
00363   }
00364 
00365   /* The new vertex is now e->Org. */
00366   e->Org->data = data;
00367   e->Org->coords[0] = coords[0];
00368   e->Org->coords[1] = coords[1];
00369   e->Org->coords[2] = coords[2];
00370 
00371   /* The winding of an edge says how the winding number changes as we
00372    * cross from the edge''s right face to its left face.  We add the
00373    * vertices in such an order that a CCW contour will add +1 to
00374    * the winding number of the region inside the contour.
00375    */
00376   e->winding = 1;
00377   e->Sym->winding = -1;
00378 
00379   tess->lastEdge = e;
00380 
00381   return 1;
00382 }
00383 
00384 
00385 static void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
00386 {
00387   CachedVertex *v = &tess->cache[tess->cacheCount];
00388 
00389   v->data = data;
00390   v->coords[0] = coords[0];
00391   v->coords[1] = coords[1];
00392   v->coords[2] = coords[2];
00393   ++tess->cacheCount;
00394 }
00395 
00396 
00397 static int EmptyCache( GLUtesselator *tess )
00398 {
00399   CachedVertex *v = tess->cache;
00400   CachedVertex *vLast;
00401 
00402   tess->mesh = __gl_meshNewMesh();
00403   if (tess->mesh == NULL) return 0;
00404 
00405   for( vLast = v + tess->cacheCount; v < vLast; ++v ) {
00406     if ( !AddVertex( tess, v->coords, v->data ) ) return 0;
00407   }
00408   tess->cacheCount = 0;
00409   tess->emptyCache = FALSE;
00410 
00411   return 1;
00412 }
00413 
00414 
00415 void GLAPIENTRY
00416 gluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
00417 {
00418   int i, tooLarge = FALSE;
00419   GLdouble x, clamped[3];
00420 
00421   RequireState( tess, T_IN_CONTOUR );
00422 
00423   if( tess->emptyCache ) {
00424     if ( !EmptyCache( tess ) ) {
00425        CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
00426        return;
00427     }
00428     tess->lastEdge = NULL;
00429   }
00430   for( i = 0; i < 3; ++i ) {
00431     x = coords[i];
00432     if( x < - GLU_TESS_MAX_COORD ) {
00433       x = - GLU_TESS_MAX_COORD;
00434       tooLarge = TRUE;
00435     }
00436     if( x > GLU_TESS_MAX_COORD ) {
00437       x = GLU_TESS_MAX_COORD;
00438       tooLarge = TRUE;
00439     }
00440     clamped[i] = x;
00441   }
00442   if( tooLarge ) {
00443     CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE );
00444   }
00445 
00446   if( tess->mesh == NULL ) {
00447     if( tess->cacheCount < TESS_MAX_CACHE ) {
00448       CacheVertex( tess, clamped, data );
00449       return;
00450     }
00451     if ( !EmptyCache( tess ) ) {
00452        CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
00453        return;
00454     }
00455   }
00456   if ( !AddVertex( tess, clamped, data ) ) {
00457        CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
00458   }
00459 }
00460 
00461 
00462 void GLAPIENTRY
00463 gluTessBeginPolygon( GLUtesselator *tess, void *data )
00464 {
00465   RequireState( tess, T_DORMANT );
00466 
00467   tess->state = T_IN_POLYGON;
00468   tess->cacheCount = 0;
00469   tess->emptyCache = FALSE;
00470   tess->mesh = NULL;
00471 
00472   tess->polygonData= data;
00473 }
00474 
00475 
00476 void GLAPIENTRY
00477 gluTessBeginContour( GLUtesselator *tess )
00478 {
00479   RequireState( tess, T_IN_POLYGON );
00480 
00481   tess->state = T_IN_CONTOUR;
00482   tess->lastEdge = NULL;
00483   if( tess->cacheCount > 0 ) {
00484     /* Just set a flag so we don't get confused by empty contours
00485      * -- these can be generated accidentally with the obsolete
00486      * NextContour() interface.
00487      */
00488     tess->emptyCache = TRUE;
00489   }
00490 }
00491 
00492 
00493 void GLAPIENTRY
00494 gluTessEndContour( GLUtesselator *tess )
00495 {
00496   RequireState( tess, T_IN_CONTOUR );
00497   tess->state = T_IN_POLYGON;
00498 }
00499 
00500 void GLAPIENTRY
00501 gluTessEndPolygon( GLUtesselator *tess )
00502 {
00503   GLUmesh *mesh;
00504 
00505   if (setjmp(tess->env) != 0) {
00506      /* come back here if out of memory */
00507      CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
00508      return;
00509   }
00510 
00511   RequireState( tess, T_IN_POLYGON );
00512   tess->state = T_DORMANT;
00513 
00514   if( tess->mesh == NULL ) {
00515     if( ! tess->flagBoundary && tess->callMesh == &noMesh ) {
00516 
00517       /* Try some special code to make the easy cases go quickly
00518        * (eg. convex polygons).  This code does NOT handle multiple contours,
00519        * intersections, edge flags, and of course it does not generate
00520        * an explicit mesh either.
00521        */
00522       if( __gl_renderCache( tess )) {
00523     tess->polygonData= NULL;
00524     return;
00525       }
00526     }
00527     if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/
00528   }
00529 
00530   /* Determine the polygon normal and project vertices onto the plane
00531    * of the polygon.
00532    */
00533   __gl_projectPolygon( tess );
00534 
00535   /* __gl_computeInterior( tess ) computes the planar arrangement specified
00536    * by the given contours, and further subdivides this arrangement
00537    * into regions.  Each region is marked "inside" if it belongs
00538    * to the polygon, according to the rule given by tess->windingRule.
00539    * Each interior region is guaranteed be monotone.
00540    */
00541   if ( !__gl_computeInterior( tess ) ) {
00542      longjmp(tess->env,1);  /* could've used a label */
00543   }
00544 
00545   mesh = tess->mesh;
00546   if( ! tess->fatalError ) {
00547     int rc = 1;
00548 
00549     /* If the user wants only the boundary contours, we throw away all edges
00550      * except those which separate the interior from the exterior.
00551      * Otherwise we tessellate all the regions marked "inside".
00552      */
00553     if( tess->boundaryOnly ) {
00554       rc = __gl_meshSetWindingNumber( mesh, 1, TRUE );
00555     } else {
00556       rc = __gl_meshTessellateInterior( mesh );
00557     }
00558     if (rc == 0) longjmp(tess->env,1);  /* could've used a label */
00559 
00560     __gl_meshCheckMesh( mesh );
00561 
00562     if( tess->callBegin != &noBegin || tess->callEnd != &noEnd
00563        || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag
00564        || tess->callBeginData != &__gl_noBeginData
00565        || tess->callEndData != &__gl_noEndData
00566        || tess->callVertexData != &__gl_noVertexData
00567        || tess->callEdgeFlagData != &__gl_noEdgeFlagData )
00568     {
00569       if( tess->boundaryOnly ) {
00570     __gl_renderBoundary( tess, mesh );  /* output boundary contours */
00571       } else {
00572     __gl_renderMesh( tess, mesh );     /* output strips and fans */
00573       }
00574     }
00575     if( tess->callMesh != &noMesh ) {
00576 
00577       /* Throw away the exterior faces, so that all faces are interior.
00578        * This way the user doesn't have to check the "inside" flag,
00579        * and we don't need to even reveal its existence.  It also leaves
00580        * the freedom for an implementation to not generate the exterior
00581        * faces in the first place.
00582        */
00583       __gl_meshDiscardExterior( mesh );
00584       (*tess->callMesh)( mesh );        /* user wants the mesh itself */
00585       tess->mesh = NULL;
00586       tess->polygonData= NULL;
00587       return;
00588     }
00589   }
00590   __gl_meshDeleteMesh( mesh );
00591   tess->polygonData= NULL;
00592   tess->mesh = NULL;
00593 }
00594 
00595 
00596 /*XXXblythe unused function*/
00597 #if 0
00598 void GLAPIENTRY
00599 gluDeleteMesh( GLUmesh *mesh )
00600 {
00601   __gl_meshDeleteMesh( mesh );
00602 }
00603 #endif
00604 
00605 
00606 
00607 /*******************************************************/
00608 
00609 /* Obsolete calls -- for backward compatibility */
00610 
00611 void GLAPIENTRY
00612 gluBeginPolygon( GLUtesselator *tess )
00613 {
00614   gluTessBeginPolygon( tess, NULL );
00615   gluTessBeginContour( tess );
00616 }
00617 
00618 
00619 /*ARGSUSED*/
00620 void GLAPIENTRY
00621 gluNextContour( GLUtesselator *tess, GLenum type )
00622 {
00623   gluTessEndContour( tess );
00624   gluTessBeginContour( tess );
00625 }
00626 
00627 
00628 void GLAPIENTRY
00629 gluEndPolygon( GLUtesselator *tess )
00630 {
00631   gluTessEndContour( tess );
00632   gluTessEndPolygon( tess );
00633 }

Generated on Fri May 25 2012 04:21:58 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.