1 /* 2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice including the dates of first publication and 13 * either this permission notice or a reference to 14 * http://oss.sgi.com/projects/FreeB/ 15 * shall be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Except as contained in this notice, the name of Silicon Graphics, Inc. 26 * shall not be used in advertising or otherwise to promote the sale, use or 27 * other dealings in this Software without prior written authorization from 28 * Silicon Graphics, Inc. 29 */ 30 /* 31 ** Author: Eric Veach, July 1994. 32 ** 33 */ 34 35 #ifndef __tess_h_ 36 #define __tess_h_ 37 38 // #include <GL/glu.h> 39 #include <osg/GLU> 40 41 #if defined(_MSC_VER) && defined(OSG_DISABLE_MSVC_WARNINGS) 42 // disable: structure was padded due to __declspec(align()) 43 #pragma warning( disable : 4324 ) 44 45 // disable: warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable 46 #pragma warning( disable : 4611) 47 #endif 48 49 #ifndef GLAPIENTRY 50 #define GLAPIENTRY GL_APIENTRY 51 #endif 52 53 #include <setjmp.h> 54 #include "mesh.h" 55 #include "dict.h" 56 #include "priorityq.h" 57 58 /* The begin/end calls must be properly nested. We keep track of 59 * the current state to enforce the ordering. 60 */ 61 enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR }; 62 63 /* We cache vertex data for single-contour polygons so that we can 64 * try a quick-and-dirty decomposition first. 65 */ 66 #define TESS_MAX_CACHE 100 67 68 typedef struct CachedVertex { 69 GLdouble coords[3]; 70 void *data; 71 } CachedVertex; 72 73 struct osg::GLUtesselator { 74 75 /*** state needed for collecting the input data ***/ 76 77 enum TessState state; /* what begin/end calls have we seen? */ 78 79 GLUhalfEdge *lastEdge; /* lastEdge->Org is the most recent vertex */ 80 GLUmesh *mesh; /* stores the input contours, and eventually 81 the tessellation itself */ 82 83 void (GLAPIENTRY *callError)( GLenum errnum ); 84 85 /*** state needed for projecting onto the sweep plane ***/ 86 87 GLdouble normal[3]; /* user-specified normal (if provided) */ 88 GLdouble sUnit[3]; /* unit vector in s-direction (debugging) */ 89 GLdouble tUnit[3]; /* unit vector in t-direction (debugging) */ 90 91 /*** state needed for the line sweep ***/ 92 93 GLdouble relTolerance; /* tolerance for merging features */ 94 GLenum windingRule; /* rule for determining polygon interior */ 95 GLboolean fatalError; /* fatal error: needed combine callback */ 96 97 Dict *dict; /* edge dictionary for sweep line */ 98 PriorityQ *pq; /* priority queue of vertex events */ 99 GLUvertex *event; /* current sweep event being processed */ 100 101 void (GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4], 102 GLfloat weight[4], void **outData ); 103 104 /*** state needed for rendering callbacks (see render.c) ***/ 105 106 GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */ 107 GLboolean boundaryOnly; /* Extract contours, not triangles */ 108 GLUface *lonelyTriList; 109 /* list of triangles which could not be rendered as strips or fans */ 110 111 void (GLAPIENTRY *callBegin)( GLenum type ); 112 void (GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge ); 113 void (GLAPIENTRY *callVertex)( void *data ); 114 void (GLAPIENTRY *callEnd)( void ); 115 void (GLAPIENTRY *callMesh)( GLUmesh *mesh ); 116 117 118 /*** state needed to cache single-contour polygons for renderCache() */ 119 120 GLboolean emptyCache; /* empty cache on next vertex() call */ 121 int cacheCount; /* number of cached vertices */ 122 CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */ 123 124 /*** rendering callbacks that also pass polygon data ***/ 125 void (GLAPIENTRY *callBeginData)( GLenum type, void *polygonData ); 126 void (GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge, 127 void *polygonData ); 128 void (GLAPIENTRY *callVertexData)( void *data, void *polygonData ); 129 void (GLAPIENTRY *callEndData)( void *polygonData ); 130 void (GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData ); 131 void (GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4], 132 GLfloat weight[4], void **outData, 133 void *polygonData ); 134 135 jmp_buf env; /* place to jump to when memAllocs fail */ 136 137 void *polygonData; /* client data for current polygon */ 138 }; 139 140 void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData ); 141 void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData ); 142 void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData ); 143 void GLAPIENTRY __gl_noEndData( void *polygonData ); 144 void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData ); 145 void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4], 146 GLfloat weight[4], void **outData, 147 void *polygonData ); 148 149 #define CALL_BEGIN_OR_BEGIN_DATA(a) \ 150 if (tess->callBeginData != &__gl_noBeginData) \ 151 (*tess->callBeginData)((a),tess->polygonData); \ 152 else (*tess->callBegin)((a)); 153 154 #define CALL_VERTEX_OR_VERTEX_DATA(a) \ 155 if (tess->callVertexData != &__gl_noVertexData) \ 156 (*tess->callVertexData)((a),tess->polygonData); \ 157 else (*tess->callVertex)((a)); 158 159 #define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \ 160 if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \ 161 (*tess->callEdgeFlagData)((a),tess->polygonData); \ 162 else (*tess->callEdgeFlag)((a)); 163 164 #define CALL_END_OR_END_DATA() \ 165 if (tess->callEndData != &__gl_noEndData) \ 166 (*tess->callEndData)(tess->polygonData); \ 167 else (*tess->callEnd)(); 168 169 #define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \ 170 if (tess->callCombineData != &__gl_noCombineData) \ 171 (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \ 172 else (*tess->callCombine)((a),(b),(c),(d)); 173 174 #define CALL_ERROR_OR_ERROR_DATA(a) \ 175 if (tess->callErrorData != &__gl_noErrorData) \ 176 (*tess->callErrorData)((a),tess->polygonData); \ 177 else (*tess->callError)((a)); 178 179 // make it easy to introduce the namespace osg for the public functions and typedefs 180 using osg::GLUtesselator; 181 using osg::_GLUfuncptr; 182 183 184 #endif 185