Esempio n. 1
0
/* Generate an extruded, capped part from a 2-D polyline. */
static void 
ExtrudePart(int n, GLfloat v[][2], float depth)
{
  static GLUtriangulatorObj *tobj = NULL;
  int i;
  float z0 = 0.5 * depth;
  float z1 = -0.5 * depth;
  GLdouble vertex[3];

  if (tobj == NULL) {
    tobj = gluNewTess();  /* create and initialize a GLU polygon * *
                             tesselation object */
    gluTessCallback(tobj, GLU_BEGIN, glBegin);
    gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
    gluTessCallback(tobj, GLU_END, glEnd);
  }
  /* +Z face */
  glPushMatrix();
  glTranslatef(0.0, 0.0, z0);
  glNormal3f(0.0, 0.0, 1.0);
  gluBeginPolygon(tobj);
  for (i = 0; i < n; i++) {
    vertex[0] = v[i][0];
    vertex[1] = v[i][1];
    vertex[2] = 0.0;
    gluTessVertex(tobj, vertex, v[i]);
  }
  gluEndPolygon(tobj);
  glPopMatrix();

  /* -Z face */
  glFrontFace(GL_CW);
  glPushMatrix();
  glTranslatef(0.0, 0.0, z1);
  glNormal3f(0.0, 0.0, -1.0);
  gluBeginPolygon(tobj);
  for (i = 0; i < n; i++) {
    vertex[0] = v[i][0];
    vertex[1] = v[i][1];
    vertex[2] = z1;
    gluTessVertex(tobj, vertex, v[i]);
  }
  gluEndPolygon(tobj);
  glPopMatrix();

  glFrontFace(GL_CCW);
  /* edge polygons */
  glBegin(GL_TRIANGLE_STRIP);
  for (i = 0; i <= n; i++) {
    float x = v[i % n][0];
    float y = v[i % n][1];
    float dx = v[(i + 1) % n][0] - x;
    float dy = v[(i + 1) % n][1] - y;
    glVertex3f(x, y, z0);
    glVertex3f(x, y, z1);
    glNormal3f(dy, -dx, 0.0);
  }
  glEnd();

}
Esempio n. 2
0
void
extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
                        GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
{
    static GLUtriangulatorObj *tobj = NULL;
    GLdouble vertex[3], dx, dy, len;
    int i;
    int count = dataSize / (int) (2 * sizeof(GLfloat));

    if (tobj == NULL) {
        tobj = gluNewTess();  /* create and initialize a GLU
                             polygon tesselation object */
        gluTessCallback(tobj, GLU_BEGIN, glBegin);
        gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
        gluTessCallback(tobj, GLU_END, glEnd);
    }
    glNewList(side, GL_COMPILE);
    glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing
                               tessellation */
    gluBeginPolygon(tobj);
    for (i = 0; i < count; i++) {
        vertex[0] = data[i][0];
        vertex[1] = data[i][1];
        vertex[2] = 0;
        gluTessVertex(tobj, vertex, data[i]);
    }
    gluEndPolygon(tobj);
    glEndList();
    glNewList(edge, GL_COMPILE);
    glShadeModel(GL_FLAT);  /* flat shade keeps angular hands
                             from being "smoothed" */
    glBegin(GL_QUAD_STRIP);
    for (i = 0; i <= count; i++) {
        /* mod function handles closing the edge */
        glVertex3f(data[i % count][0], data[i % count][1], 0.0);
        glVertex3f(data[i % count][0], data[i % count][1], thickness);
        /* Calculate a unit normal by dividing by Euclidean
           distance. We * could be lazy and use
           glEnable(GL_NORMALIZE) so we could pass in * arbitrary
           normals for a very slight performance hit. */
        dx = data[(i + 1) % count][1] - data[i % count][1];
        dy = data[i % count][0] - data[(i + 1) % count][0];
        len = sqrt(dx * dx + dy * dy);
        glNormal3f(dx / len, dy / len, 0.0);
    }
    glEnd();
    glEndList();
    glNewList(whole, GL_COMPILE);
    glFrontFace(GL_CW);
    glCallList(edge);
    glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */
    glCallList(side);
    glPushMatrix();
    glTranslatef(0.0, 0.0, thickness);
    glFrontFace(GL_CCW);
    glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */
    glCallList(side);
    glPopMatrix();
    glEndList();
}
Esempio n. 3
0
void draw_angle_style_front_cap (int ncp,	/* number of contour points */
                           gleDouble bi[3],		/* biscetor */
                           gleDouble point_array[][3])	/* polyline */
{
    int	j;
#ifdef OPENGL_10
   GLUtriangulatorObj *tobj;
#endif /* OPENGL_10 */

   if (bi[2] < 0.0) {
      VEC_SCALE (bi, -1.0, bi); 
   }

#ifdef GL_32
   /* old-style gl handles concave polygons no problem, so the code is
    * simple.  New-style gl is a lot more tricky. */
   /* draw the end cap */
   BGNPOLYGON ();

   N3F (bi);
   for (j=0; j<ncp; j++) {
      V3F (point_array[j], j, FRONT_CAP);
   }
   ENDPOLYGON ();
#endif /* GL_32 */

#ifdef OPENGL_10
   N3F(bi);

   tobj = gluNewTess ();
   gluTessCallback (tobj, GLU_BEGIN, glBegin);
   gluTessCallback (tobj, GLU_VERTEX, glVertex3dv);
   gluTessCallback (tobj, GLU_END, glEnd);
   gluBeginPolygon (tobj);

   for (j=0; j<ncp; j++) {
      gluTessVertex (tobj, point_array[j], point_array[j]);
   }
   gluEndPolygon (tobj);
   gluDeleteTess (tobj);
#endif /* OPENGL_10 */
}
Esempio n. 4
0
static void
draw_cut_style_cap_callback (int iloop,
                                  double cap[][3],
                                  float face_color[3],
                                  gleDouble cut_vector[3],
                                  gleDouble bisect_vector[3],
                                  double norms[][3],
                                  int frontwards)
{
#ifdef DELICATE_TESSELATOR
   int i;
   int is_colinear;
   double *previous_vertex = 0x0;
   double *first_vertex = 0x0;
#endif /* DELICATE_TESSELATOR */

#ifdef OPENGL_10
   GLUtriangulatorObj *tobj;
   tobj = gluNewTess ();
   gluTessCallback (tobj, GLU_BEGIN, glBegin);
   gluTessCallback (tobj, GLU_VERTEX, glVertex3dv);
   gluTessCallback (tobj, GLU_END, glEnd);
#endif /* OPENGL_10 */

   if (face_color != NULL) C3F (face_color);

   if (frontwards) {

      /* if lighting is on, specify the endcap normal */
      if (cut_vector != NULL) {
         /* if normal pointing in wrong direction, flip it. */
         if (cut_vector[2] < 0.0) {
            VEC_SCALE (cut_vector, -1.0, cut_vector);
         }
         N3F_D (cut_vector);
      }
#ifdef GL_32
      BGNPOLYGON();
      for (i=0; i<iloop; i++) {
         V3F_D (cap[i], i, FRONT_CAP);
      }
      ENDPOLYGON();
#endif /* GL_32 */
#ifdef OPENGL_10

/* If you have a tesselator that is happy with anything,
 * including degenerate points, colinear segments, etc.
 * then define this. Otherwise, pick one of the others.
 *
 * I beleive that the stock SGI tesselator is "lenient",
 * despite explicit disclaimers in the documentation.
 * (circa 1995).
 *
 * The Mesa tesselator is not at all forgiving of
 * degenerate points.
 * (circa 1997-1998)
 */

#ifdef LENIENT_TESSELATOR
      gluBeginPolygon (tobj);
      for (i=0; i<iloop; i++) {
         gluTessVertex (tobj, cap[i], cap[i]);
      }
      gluEndPolygon (tobj);
#endif /* LENIENT_TESSELATOR */

#ifdef DELICATE_TESSELATOR
      gluBeginPolygon (tobj);

      first_vertex = 0x0;
      previous_vertex = cap[iloop-1];
      for (i=0; i<iloop-1; i++) {
         COLINEAR (is_colinear, previous_vertex, cap[i], cap[i+1]);
         if (!is_colinear) {
            gluTessVertex (tobj, cap[i], cap[i]);
            previous_vertex = cap[i];
            if (!first_vertex) first_vertex = previous_vertex;
         }
      }

      if (!first_vertex) first_vertex = cap[0];
      COLINEAR (is_colinear, previous_vertex, cap[iloop-1], first_vertex);
      if (!is_colinear) gluTessVertex (tobj, cap[iloop-1], cap[iloop-1]);

      gluEndPolygon (tobj);
#endif /* DELICATE_TESSELATOR */

#endif /* OPENGL_10 */
   } else {

      /* if lighting is on, specify the endcap normal */
      if (cut_vector != NULL) {
         /* if normal pointing in wrong direction, flip it. */
         if (cut_vector[2] > 0.0) {
            VEC_SCALE (cut_vector, -1.0, cut_vector);
         }
         N3F_D (cut_vector);
      }
      /* the sense of the loop is reversed for backfacing culling */
#ifdef GL_32
      BGNPOLYGON();
      for (i=iloop-1; i>-1; i--) {
         V3F_D (cap[i], i, BACK_CAP);
      }
      ENDPOLYGON();
#endif /* GL_32 */
#ifdef OPENGL_10

#ifdef LENIENT_TESSELATOR
      gluBeginPolygon (tobj);
      for (i=iloop-1; i>-1; i--) {
         gluTessVertex (tobj, cap[i], cap[i]);
      }
      gluEndPolygon (tobj);
#endif /* LENIENT_TESSELATOR */

#ifdef DELICATE_TESSELATOR
      gluBeginPolygon (tobj);

      first_vertex = 0x0;
      previous_vertex = cap[0];
      for (i=iloop-1; i>0; i--) {
         COLINEAR (is_colinear, previous_vertex, cap[i], cap[i-1]);
         if (!is_colinear) {
            gluTessVertex (tobj, cap[i], cap[i]);
            previous_vertex = cap[i];
            if (!first_vertex) first_vertex = previous_vertex;
         }
      }

      if (!first_vertex) first_vertex = cap[iloop-1];
      COLINEAR (is_colinear, previous_vertex, cap[0], first_vertex);
      if (!is_colinear) gluTessVertex (tobj, cap[0], cap[0]);

      gluEndPolygon (tobj);
#endif /* DELICATE_TESSELATOR */

#endif /* OPENGL_10 */
   }

#ifdef OPENGL_10
   gluDeleteTess (tobj);
#endif /* OPENGL_10 */

}
/* Mark Kilgard's tessellation code from the "dino" demos. */
void extrudeSolidFromPolygon(GLfloat data[][3], unsigned int dataSize,
		GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
{
	GLdouble vertex[3], dx, dy, len;
	int i, k;
	int flag = 0;
	int count = dataSize / (3 * sizeof(GLfloat));
    static GLUtriangulatorObj *tobj = NULL;

    if (tobj == NULL) {
    	tobj = gluNewTess();
    	
    	gluTessCallback(tobj, GLU_BEGIN, glBegin);
    	gluTessCallback(tobj, GLU_VERTEX, glVertex3fv);
    	gluTessCallback(tobj, GLU_END, glEnd);
    }
    glNewList(side, GL_COMPILE);
    	glShadeModel(GL_SMOOTH);
    	gluBeginPolygon(tobj);
    		for(i = 0; i < count; i++) {
    			/* This detects a new contour from a large number placed in
    			the unused z coordinate of the vertex where the new contour 
    			starts. See the coordinates for letterO, above. The coordinate 
    			must be reset below for additional calls. */

    			if (data[i][2] > 1000.0) {
    				data[i][2] = 0.0;
    				flag = 1; k = i;
    				gluNextContour(tobj, GLU_INTERIOR); 
    			}
    			
    			vertex[0] = data[i][0];
    			vertex[1] = data[i][1];
    			vertex[2] = 0.0;
    			gluTessVertex(tobj, vertex, data[i]);
    		}
    	gluEndPolygon(tobj);
    glEndList();
	
				/* Reset coordinate for new calls. */
				if (flag == 1) {
				data[k][2] = 10000.0;
				flag = 0;
				}
	glNewList(edge, GL_COMPILE);
		glBegin(GL_QUAD_STRIP);
		for(i = 0; i <= count; i++) {
			glVertex3f(data[i % count][0], data[i % count][1], 0.0);
			glVertex3f(data[i % count][0], data[i % count][1], thickness);
			/* Normals */
			dx = data[(i+ 1) % count][1] - data[i % count][1];
			dy = data[i % count][0] - data[(i + 1) % count][0];
			len = sqrt(dx * dx + dy * dy);
			glNormal3f(dx / len, dy / len, 0.0);
		}
		glEnd();
	glEndList();
	
	glNewList(whole, GL_COMPILE);
		glFrontFace(GL_CW);

		glMaterialfv(GL_FRONT, GL_DIFFUSE, edgeColor);
		glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
		glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);				

		glCallList(edge);
		glNormal3f(0.0, 0.0, -1.0); 
		glCallList(side);
		glPushMatrix();
			glTranslatef(0.0, 0.0, thickness);
			glFrontFace(GL_CCW);
			glNormal3f(0.0, 0.0, 1.0);

		glMaterialfv(GL_FRONT, GL_DIFFUSE, sideColor);
		glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
		glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);		
		
			glCallList(side);
		glPopMatrix();
	glEndList();
}
Esempio n. 6
0
/* ARGSUSED4 */
static void draw_cut_style_cap_callback (int iloop,
                                  double cap[][3], 
                                  float face_color[3],
                                  gleDouble cut_vector[3],
                                  gleDouble bisect_vector[3],
                                  double norms[][3], 
                                  int frontwards)
{
   int i;
#ifdef OPENGL_10
   GLUtriangulatorObj *tobj;
   tobj = gluNewTess ();
   gluTessCallback (tobj, GLU_BEGIN, (void (CALLBACK*)()) glBegin);
   gluTessCallback (tobj, GLU_VERTEX, (void (CALLBACK*)()) glVertex3dv);
   gluTessCallback (tobj, GLU_END, (void (CALLBACK*)()) glEnd);
#endif /* OPENGL_10 */

   if (face_color != NULL) C3F (face_color);

   if (frontwards) {

      /* if lighting is on, specify the endcap normal */
      if (cut_vector != NULL) {
         /* if normal pointing in wrong direction, flip it. */
         if (cut_vector[2] < 0.0) { 
            VEC_SCALE (cut_vector, -1.0, cut_vector); 
         }
         N3F_D (cut_vector);
      }
#ifdef GL_32
      BGNPOLYGON();
      for (i=0; i<iloop; i++) {
         V3F_D (cap[i], i, FRONT_CAP);
      }
      ENDPOLYGON();
#endif /* GL_32 */
#ifdef OPENGL_10
      gluBeginPolygon (tobj);
      for (i=0; i<iloop; i++) {
         gluTessVertex (tobj, cap[i], cap[i]);
      }
      gluEndPolygon (tobj);
#endif /* OPENGL_10 */
   } else {

      /* if lighting is on, specify the endcap normal */
      if (cut_vector != NULL) {
         /* if normal pointing in wrong direction, flip it. */
         if (cut_vector[2] > 0.0) {
            VEC_SCALE (cut_vector, -1.0, cut_vector); 
         }
         N3F_D (cut_vector);
      }
      /* the sense of the loop is reversed for backfacing culling */
#ifdef GL_32
      BGNPOLYGON();
      for (i=iloop-1; i>-1; i--) {
         V3F_D (cap[i], i, BACK_CAP);
      }
      ENDPOLYGON();
#endif /* GL_32 */
#ifdef OPENGL_10
      gluBeginPolygon (tobj);
      for (i=iloop-1; i>-1; i--) {
         gluTessVertex (tobj, cap[i], cap[i]);
      }
      gluEndPolygon (tobj);
#endif /* OPENGL_10 */
   }

#ifdef OPENGL_10
   gluDeleteTess (tobj);
#endif /* OPENGL_10 */

}
Esempio n. 7
0
void gluauxBeginPolygon (GLUtriangulatorObj* tessobj)
{
 current(tessobj);
 gluBeginPolygon(tessobj); 
}
Esempio n. 8
0
int
Tesselate (Tcl_Interp *interp, int argc, char* argv [])
{
   int result = TCL_OK;
   int icoord = 0;
   int edgeflags = 1;
   int iarg;
   GLUtriangulatorObj* obj;
   int dlist = -1;
   GLdouble coord [3];
   GLfloat* vtx;
   GLfloat* vtxptr;

   globalinterp = interp;
   globalresult = TCL_OK;

   for (iarg = 2; iarg < argc; iarg++) {	
      int len = (int)strlen (argv [iarg]);
      if (strncmp (argv [iarg], "-displaylist", len) == 0) {
	 iarg++;
	 if (iarg == argc) {
            Tcl_AppendResult (interp, "not enough arguments", (char*)NULL);
            return TCL_ERROR;
         }
         if (strcmp (argv [iarg], "none") == 0) {
            dlist = 0;
         } 
         else if (Tcl_GetInt (interp, argv [iarg], &dlist) != TCL_OK) {
	    Tcl_AppendResult (interp,
	           "\nError parsing display list number", (char*) NULL);
	    return TCL_ERROR;
	 }
      } 
      else if (strncmp (argv [iarg], "-noedgeflags", len) == 0) {
	 edgeflags = 0;
      }
      else break;
   }

   if (argc - iarg < 9) {
      Tcl_AppendResult (interp,
	      "Not enough vertices", (char*) NULL);
      return TCL_ERROR;
   }

   obj = gluNewTess();
   vtx = (GLfloat*) malloc (sizeof (GLfloat) * (argc - iarg));
   vtxptr = vtx;

   assert (vtx != NULL);

   gluTessCallback(obj, GLU_BEGIN, glBegin);
   gluTessCallback(obj, GLU_VERTEX, glVertex3fv); 
   gluTessCallback(obj, GLU_END, glEnd);
   gluTessCallback(obj, GLU_ERROR, (TessCallback) TessError);
   if (edgeflags) gluTessCallback (obj, GLU_EDGE_FLAG, (TessCallback) glEdgeFlag);
   if (dlist == -1) dlist = glGenLists (1);   
   if (dlist != 0) glNewList (dlist, GL_COMPILE);
   gluBeginPolygon (obj);

   for (; iarg < argc; iarg++) {	
      int len = (int)strlen (argv [iarg]);
      if (strncmp (argv [iarg], "-contour", len) == 0) {
	 gluNextContour (obj, GLU_UNKNOWN);
      }
      else {
	 if (Tcl_GetDouble (interp, argv [iarg], &coord[icoord]) != TCL_OK) {
	    Tcl_AppendResult (interp,
	      "\nError parsing tesselation vertex coord", (char*) NULL);
	    result = TCL_ERROR;
	    break;
	 }
	 else {
	    icoord = (icoord+1)%3;
	    if (icoord == 0) {
	       *(vtxptr) = (GLfloat)coord [0];
	       *(vtxptr+1) = (GLfloat)coord [1];
	       *(vtxptr+2) = (GLfloat)coord [2];
	       gluTessVertex (obj, coord, vtxptr);
	       vtxptr += 3;
	    }
	 }
      }
   }
   
   gluEndPolygon (obj);
   gluDeleteTess (obj);
   free (vtx);
   if (dlist != 0) glEndList(); 

   if (result != TCL_OK || globalresult != TCL_OK) {
      if (dlist != 0) glDeleteLists (dlist, 1);
      return TCL_ERROR;
   }
   
   if (dlist != 0) {
     char tmp[128];
     sprintf (tmp, "%d", dlist);
     Tcl_SetResult(interp, tmp, TCL_VOLATILE);
   }
   return TCL_OK;
}
Esempio n. 9
0
void TglTessellator::doTessellate(GLTess &glTess, const TColorFunction *cf, const bool antiAliasing, TRegionOutline &outline)
{
	QMutexLocker sl(&CombineDataGuard);

	Combine_data.clear();
	assert(glTess.m_tess);

	gluTessCallback(glTess.m_tess, GLU_TESS_BEGIN, (GluCallback)glBegin);
	gluTessCallback(glTess.m_tess, GLU_TESS_END, (GluCallback)glEnd);

	gluTessCallback(glTess.m_tess, GLU_TESS_COMBINE, (GluCallback)myCombine);

#ifdef GLU_VERSION_1_2
	gluTessBeginPolygon(glTess.m_tess, NULL);
	gluTessProperty(glTess.m_tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
#else
#ifdef GLU_VERSION_1_1
	gluBeginPolygon(glTess.m_tess);
#else
	assert(false);
#endif
#endif

	for (TRegionOutline::Boundary::iterator poly_it = outline.m_exterior.begin(); poly_it != outline.m_exterior.end(); ++poly_it) {

#ifdef GLU_VERSION_1_2
		gluTessBeginContour(glTess.m_tess);
#else
#ifdef GLU_VERSION_1_1
		gluNextContour(glTess.m_tess, GLU_EXTERIOR);
#else
		assert(false);
#endif
#endif

		for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it)
			gluTessVertex(glTess.m_tess, &(it->x), &(it->x));

#ifdef GLU_VERSION_1_2
		gluTessEndContour(glTess.m_tess);
#endif
	}

	int subRegionNumber = outline.m_interior.size();
	if (subRegionNumber > 0) {

		for (TRegionOutline::Boundary::iterator poly_it = outline.m_interior.begin(); poly_it != outline.m_interior.end(); ++poly_it) {

#ifdef GLU_VERSION_1_2
			gluTessBeginContour(glTess.m_tess);
#else
#ifdef GLU_VERSION_1_1
			gluNextContour(glTess.m_tess, GLU_INTERIOR);
#else
			assert(false);
#endif
#endif

			for (TRegionOutline::PointVector::reverse_iterator rit = poly_it->rbegin(); rit != poly_it->rend(); ++rit)
				gluTessVertex(glTess.m_tess, &(rit->x), &(rit->x));

#ifdef GLU_VERSION_1_2
			gluTessEndContour(glTess.m_tess);
#endif
		}
	}

#ifdef GLU_VERSION_1_2
	gluTessEndPolygon(glTess.m_tess);
#else
#ifdef GLU_VERSION_1_1
	gluEndPolygon(glTess.m_tess);
#else
	assert(false);
#endif
#endif

	std::list<GLdouble *>::iterator beginIt, endIt;
	endIt = Combine_data.end();
	beginIt = Combine_data.begin();
	for (; beginIt != endIt; ++beginIt)
		delete[](*beginIt);
}
void IceFloe::drawGeom() {	
	int i, j;
	float h;

	h = height * TransIcelandicExpress::c_RoadLevel;	

	// draw the sides	
	sgVec3 edge, n, up;
	sgSetVec3( up, 0.0, 1.0, 0.0 );
	glBegin( GL_QUADS );
	for (j = npnts-1, i = 0; i < npnts; j=i++) {
		sgSetVec3( edge, pnts[j][0] - pnts[i][0], 0.0,
						 pnts[j][2] - pnts[i][2] );

		sgNormalizeVec3( edge );
		sgVectorProductVec3( n, edge, up );
	
		glNormal3f( n[0], n[1], n[2] );

		glVertex3f( pnts[i][0], h, pnts[i][2] );
		glVertex3f( pnts[j][0], h, pnts[j][2] );
		glVertex3f( pnts[j][0], 0.0, pnts[j][2] );
		glVertex3f( pnts[i][0], 0.0, pnts[i][2] );						
	}
	glEnd();

	// tesselate the top
	if (!tess.size()) {
		if (!gluTess) {

			gluTess = gluNewTess();
			gluTessCallback( gluTess, GLU_BEGIN,  (void(__stdcall *)(void))tessBegin );
			gluTessCallback( gluTess, GLU_END,    (void(__stdcall *)(void))tessEnd );
			gluTessCallback( gluTess, GLU_VERTEX, (void(__stdcall *)(void))tessVertex );
			gluTessCallback( gluTess, GLU_ERROR,  (void(__stdcall *)(void))tessError );
		}

		printf("Tesselating polygon....\n");
		floeToTess = this;

		gluBeginPolygon( gluTess );
		GLdouble *v;
		for (i = 0; i < npnts; i++) {
			pnts[i][1] = h;

			v = new GLdouble[4];
			v[0] = pnts[i][0]; 
			v[1] = pnts[i][1]; 
			v[2] = pnts[i][2];			

			printf("gluTessVertex %3.4f %3.4f %3.4f\n",
				v[0], v[1], v[2] );
			gluTessVertex( gluTess, v, pnts[i] );
		}
		printf("About to call end....\n");
		gluEndPolygon( gluTess );
		printf("Done.\n");

		floeToTess = NULL;
	} 

	// draw the top
	glNormal3f( 0.0, 1.0, 0.0 );
	glBegin( GL_TRIANGLES );	
	for (std::vector<TessTri*>::iterator ti = tess.begin();
		 ti != tess.end(); ti++ ) {

		glVertex3f( (*ti)->a[0], (*ti)->a[1], (*ti)->a[2] );
		glVertex3f( (*ti)->b[0], (*ti)->b[1], (*ti)->b[2] );
		glVertex3f( (*ti)->c[0], (*ti)->c[1], (*ti)->c[2] );

	}
	glEnd();

}