00001 #ifndef CELLBE 00002 // 00003 // support general tesselation of polygons 00004 // 00005 00006 #ifdef MBSD_COCOA 00007 # include <OpenGL/glu.h> 00008 #else 00009 # include <GL/glu.h> 00010 #endif 00011 00012 #ifndef CALLBACK 00013 #define CALLBACK 00014 #endif 00015 00016 // 00017 // define max texture coordindate dimensionality 00018 // 00019 #define RE_TEXTURE_DIM 2 00020 00021 // 00022 // class to hold tesselated vertex info 00023 // 00024 struct RE_TessVertex { 00025 float v[3]; // the vertex 00026 float n[3]; // its normal 00027 float c[4]; // its color; 00028 float t[4]; // its texture coords 00029 float a[4]; // its attrib data 00030 00031 // there's no point in making these bit fields, 00032 // since structure alignment, will pad it to 00033 // the next mod 4 address anyway 00034 char nSet; // is normal valid 00035 char cCount; // is color set, and w/ 3 or 4 values 00036 char tCount; // are texture coords set, how many values 00037 char aCount; // are attrib data set, how many values 00038 int aLoc; // attrib data location 00039 00040 // clear all the flags to the default state 00041 void clear() { 00042 nSet = GL_FALSE; 00043 cCount = 0; // not set 00044 tCount = 0; 00045 aCount = 0; 00046 aLoc = -1; 00047 } 00048 }; 00049 00050 // 00051 // RE_TessCommand contains an operator and data 00052 // 00053 struct RE_TessCommand { 00054 enum TessOperator { begin, vertex, end }; 00055 00056 TessOperator op; 00057 int data; 00058 }; 00059 00060 00061 // 00062 // The RE_Tesselator class manages an array of RE_TessVertex's 00063 // Color, Normal and Texture data are put into the current 00064 // vertex, if we are rendering a concave polygon. 00065 // 00066 // RE_TessVertexBuffer is a Singleton Design Pattern 00067 // 00068 class RE_Tesselator { 00069 public: 00070 static RE_Tesselator *instance(); 00071 static void deReference(); 00072 00073 void init() { 00074 _currentVert = 0; 00075 _currentCmd = 0; 00076 clearVert(); 00077 } 00078 00079 void buffer(); 00080 void immediate(); 00081 00082 void normal( const float n[] ) { 00083 currentVert()->nSet = GL_TRUE; 00084 currentVert()->n[0] = n[0]; 00085 currentVert()->n[1] = n[1]; 00086 currentVert()->n[2] = n[2]; 00087 } 00088 void texture1( const float t[] ) { 00089 currentVert()->tCount = 1; 00090 currentVert()->t[0] = t[0]; 00091 } 00092 void texture2( const float t[] ) { 00093 currentVert()->tCount = 2; 00094 currentVert()->t[0] = t[0]; 00095 currentVert()->t[1] = t[1]; 00096 } 00097 void texture3( const float t[] ) { 00098 #if RE_TEXTURE_DIM >= 3 00099 currentVert()->tCount = 3; 00100 currentVert()->t[0] = t[0]; 00101 currentVert()->t[1] = t[1]; 00102 currentVert()->t[2] = t[2]; 00103 #else // use 2D 00104 texture2( t ); 00105 #endif // RE_TEXTURE_DIM >= 3 00106 } 00107 void texture4( const float t[] ) { 00108 #if RE_TEXTURE_DIM >= 4 00109 currentVert()->tCount = 4; 00110 currentVert()->t[0] = t[0]; 00111 currentVert()->t[1] = t[1]; 00112 currentVert()->t[2] = t[2]; 00113 currentVert()->t[3] = t[3]; 00114 #else // use 3D (texture3 may actually use texture2) 00115 texture3( t ); 00116 #endif // RE_TEXTURE_DIM >= 4 00117 } 00118 void attrib1( unsigned int loc, const float a[] ) { 00119 currentVert()->aLoc = loc; 00120 currentVert()->aCount = 1; 00121 currentVert()->a[0] = a[0]; 00122 } 00123 void attrib2( unsigned int loc, const float a[] ) { 00124 currentVert()->aLoc = loc; 00125 currentVert()->aCount = 2; 00126 currentVert()->a[0] = a[0]; 00127 currentVert()->a[1] = a[1]; 00128 } 00129 void attrib3( unsigned int loc, const float a[] ) { 00130 currentVert()->aLoc = loc; 00131 currentVert()->aCount = 3; 00132 currentVert()->a[0] = a[0]; 00133 currentVert()->a[1] = a[1]; 00134 currentVert()->a[2] = a[2]; 00135 } 00136 void attrib4( unsigned int loc, const float a[] ) { 00137 currentVert()->aLoc = loc; 00138 currentVert()->aCount = 4; 00139 currentVert()->a[0] = a[0]; 00140 currentVert()->a[1] = a[1]; 00141 currentVert()->a[2] = a[2]; 00142 currentVert()->a[3] = a[3]; 00143 } 00144 void color3( const float c[] ) { 00145 currentVert()->cCount = 3; 00146 currentVert()->c[0] = c[0]; 00147 currentVert()->c[1] = c[1]; 00148 currentVert()->c[2] = c[2]; 00149 } 00150 void color4( const float c[] ) { 00151 currentVert()->cCount = 4; 00152 currentVert()->c[0] = c[0]; 00153 currentVert()->c[1] = c[1]; 00154 currentVert()->c[2] = c[2]; 00155 currentVert()->c[3] = c[3]; 00156 } 00157 void vertex( const float v[] ); 00158 00159 void tesselate(); 00160 void interp(); 00161 00162 ~RE_Tesselator(); 00163 protected: 00164 RE_Tesselator(); 00165 00166 RE_TessVertex *currentVert() { return &_vbuf[_currentVert]; } 00167 00168 int degenerateShape(); 00169 00170 // tesselator callback functions 00171 static void CALLBACK beginCB( GLenum ); 00172 static void CALLBACK vertexCB( void *data ); 00173 static void CALLBACK endCB(); 00174 00175 void doVert( int index ); 00176 00177 private: 00178 static RE_Tesselator *_instance; 00179 00180 GLUtriangulatorObj *_gluTess; 00181 int _immediate; 00182 00183 // 00184 // expandable buffer of vertex's 00185 // 00186 RE_TessVertex *_vbuf; 00187 int _currentVert; 00188 int _vbufSize; 00189 00190 void clearVert() { currentVert()->clear(); } 00191 void nextVert(); 00192 00193 // 00194 // expandable buffer of commands 00195 // 00196 RE_TessCommand *_cmdBuf; 00197 int _currentCmd; 00198 int _cmdBufSize; 00199 00200 void nextCmd(); 00201 }; 00202 00203 #endif // CELLBE
1.5.9