Ejemplo n.º 1
0
void drawColourPoly(const carve::geom3d::Vector &normal, std::vector<std::pair<carve::geom3d::Vector, cRGBA> > &v) {
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  GLUtesselator *tess = gluNewTess();

  gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (GLUTessCallback)_normalBegin);
  gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLUTessCallback)_colourVertex);
  gluTessCallback(tess,  GLU_TESS_END_DATA, (GLUTessCallback)_normalEnd);

  gluTessBeginPolygon(tess, (void *)(GLdouble *)normal.v);
  gluTessBeginContour(tess);

  for (size_t i = 0, l = v.size(); i != l; ++i) {
    gluTessVertex(tess, (GLdouble *)v[i].first.v, (GLvoid *)&v[i]);
  }

  gluTessEndContour(tess);
  gluTessEndPolygon(tess);

  gluDeleteTess(tess);
}
Ejemplo n.º 2
0
void glu_tessbeginpolygon( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {

    MOGLDEFMYTESS;

	if (NULL == gluTessBeginPolygon) mogl_glunsupported("gluTessBeginPolygon");

    // Setup all tesselator callbacks for this polygon:
    MOGLSETTESSCALLBACK(GLU_TESS_BEGIN);
    MOGLSETTESSCALLBACK(GLU_TESS_EDGE_FLAG);
    MOGLSETTESSCALLBACK(GLU_TESS_VERTEX);
    MOGLSETTESSCALLBACK(GLU_TESS_END);
    MOGLSETTESSCALLBACK(GLU_TESS_COMBINE);
    MOGLSETTESSCALLBACK(GLU_TESS_ERROR);
        
    // Store user-provided polygon data pointer internally:
    mytess->polygondata = mxGetScalar(prhs[1]);
    
    // Pass pointer to our own struct as polygondata to the real tesselator:
	gluTessBeginPolygon((GLUtesselator*) mytess->glutesselator, (GLvoid*) mytess);

}
Ejemplo n.º 3
0
void GLShapeRenderer::renderPolygon(LKSurface& Surface, const XShape& shape, Brush& brush, const ScreenProjection& _Proj) {
  /*
   OpenGL cannot draw complex polygons so we need to use a Tessallator to draw the polygon using a GL_TRIANGLE_FAN
   */  
#ifdef USE_GLSL
  OpenGL::solid_shader->Use();
#endif
  
  brush.Bind();
    
  std::unique_ptr<const GLBlend> blend; 
  if(!brush.IsOpaque()) {
    blend = std::make_unique<const GLBlend>(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }
  
  curr_LabelPos = clipRect.GetBottomRight();
  
  const shapeObj& shp = shape.shape;

  gluTessBeginPolygon(tess, this );
  for (int j = 0; j < shp.numlines; j++) {
    gluTessBeginContour(tess);
    for (int i = 0; i < shp.line[j].numpoints; i++) {
      const RasterPoint pt = _Proj.LonLat2Screen(shp.line[j].point[i]);
      if (!noLabel &&  (pt.x<=curr_LabelPos.x)) {
        curr_LabelPos = pt;
      }  
      vertex_t& vertex = *(pointers.insert(pointers.end(), vertex_t({{(GLdouble)pt.x, (GLdouble)pt.y, 0.}})));
      gluTessVertex(tess, vertex.data(), vertex.data());
    }
    gluTessEndContour(tess);
  }
  gluTessEndPolygon(tess);
  
  if(shape.HasLabel() && clipRect.IsInside(curr_LabelPos)) {
    shape.renderSpecial(Surface, curr_LabelPos.x, curr_LabelPos.y, clipRect);
  }
  
  pointers.clear();
}
Ejemplo n.º 4
0
void  Opengl2dPainter::drawPolygon(const POINT2F* pPoints, INT count, bool bFill)
{
    /// opengl tesselation

    if (bFill)
        gluTessProperty(_pPimpl->pTesslation, GLU_TESS_BOUNDARY_ONLY, false);
    else
        gluTessProperty(_pPimpl->pTesslation, GLU_TESS_BOUNDARY_ONLY, true);

    VERTEX_EDGE v;
    std::vector<VERTEX_EDGE> vertices;
    vertices.reserve(count+1);

    gluTessBeginPolygon(_pPimpl->pTesslation, NULL);
    gluTessBeginContour(_pPimpl->pTesslation);
    gluNextContour(_pPimpl->pTesslation, GLU_EXTERIOR);

    for (int i=0; i< count; ++i)
    {
        v.x = pPoints[i].x;
        v.y = pPoints[i].y;
        v.z = 0;
        vertices.push_back(v);
        gluTessVertex(_pPimpl->pTesslation, (double*)&vertices[i], (void*) &vertices[i]);
    }

    v.x = pPoints[0].x;
    v.y = pPoints[0].y;
    v.z = 0;
    vertices.push_back(v);

    gluTessVertex(_pPimpl->pTesslation, (double*)&vertices[count],(void*) &vertices[count]);


    gluTessEndContour(_pPimpl->pTesslation);
    gluTessEndPolygon(_pPimpl->pTesslation);

}
Ejemplo n.º 5
0
Archivo: tess.c Proyecto: ghub/NVprSDK
static void GotoState( GLUtesselator *tess, enum TessState newState )
{
  while( tess->state != newState ) {
    /* We change the current state one level at a time, to get to
     * the desired state.
     */
    if( tess->state < newState ) {
      switch( tess->state ) {
      case T_DORMANT:
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON );
	gluTessBeginPolygon( tess, NULL );
	break;
      case T_IN_POLYGON:
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR );
	gluTessBeginContour( tess );
	break;
      default:
        assert(0);
        break;
      }
    } else {
      switch( tess->state ) {
      case T_IN_CONTOUR:
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR );
	gluTessEndContour( tess );
	break;
      case T_IN_POLYGON:
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON );
	/* gluTessEndPolygon( tess ) is too much work! */
	MakeDormant( tess );
	break;
      default:
        assert(0);
        break;
      }
    }
  }
}
Ejemplo n.º 6
0
void tessellate
    (double **verts,
     int *nverts,
     int **tris,
     int *ntris,
     const double **contoursbegin, 
     const double **contoursend)
{
    const double *contourbegin, *contourend;
    struct Vertex_s *current_vertex;
    GLUtesselator *tess;
    struct TessContext_s *ctx;

    tess = gluNewTess();
    ctx = new_tess_context();
    gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
    gluTessCallback(tess, GLU_TESS_VERTEX_DATA,  (GLvoid (*) ()) &vertex);
    gluTessCallback(tess, GLU_TESS_BEGIN_DATA,   (GLvoid (*) ()) &begin);
    gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (GLvoid (*) ()) &combine);

    gluTessBeginPolygon(tess, ctx);
    do {
        contourbegin = *contoursbegin++;
        contourend = *contoursbegin;
        gluTessBeginContour(tess);
        while (contourbegin != contourend) {
            current_vertex = new_vertex(ctx, contourbegin[0], contourbegin[1]);
            contourbegin += 2;
            gluTessVertex(tess, current_vertex->pt, current_vertex);
        }
        gluTessEndContour(tess);
    } while (contoursbegin != (contoursend - 1));
    gluTessEndPolygon(tess);

    write_output(ctx, verts, tris, nverts, ntris);
    destroy_tess_context(ctx);
    gluDeleteTess(tess);
}
Ejemplo n.º 7
0
//only draws the GL polygon face without normals and colors
//dir implyes if it is in inverse or direct order (false==inverse)
void Face::drawPrimitive(bool dir)
{
	int num=(int)(vertex.size());
	int i;

	if(convex){
		glBegin(GL_POLYGON);
		if(clockwise==dir){
			for(i=0;i<num;i++)
				glVertex3dv(vertex[i].values);
		}
		else{
			for(i=num-1;i>=0;i--)
				glVertex3dv(vertex[i].values);
		}
		glEnd();
	}
	else{
		GLUtesselator *TESS=gluNewTess();
		gluTessCallback(TESS,GLU_BEGIN,MR_TESS glBegin);
		gluTessCallback(TESS,GLU_VERTEX,MR_TESS glVertex3dv);
		gluTessCallback(TESS,GLU_END, glEnd);
		
		gluTessBeginPolygon(TESS, NULL);
		gluTessBeginContour(TESS);

		if(clockwise==dir){
			for(i=0;i<num;i++)gluTessVertex(TESS,vertex[i].values,vertex[i].values);		
		}
		else{ 		
			for(i=num-1;i>=0;i--)gluTessVertex(TESS,vertex[i].values,vertex[i].values);
		}
		gluTessEndContour(TESS);
		gluTessEndPolygon(TESS);
		gluDeleteTess(TESS);
	}
}
Ejemplo n.º 8
0
//      Build PolyTessGeo Object from OGR Polygon
//      Using OpenGL/GLU tesselator
int PolyTessGeo::PolyTessGeoGL(OGRPolygon *poly, bool bSENC_SM, double ref_lat, double ref_lon)
{
#ifdef ocpnUSE_GL
    
    int iir, ip;
    int *cntr;
    GLdouble *geoPt;

    wxString    sout;
    wxString    sout1;
    wxString    stemp;

    //  Make a quick sanity check of the polygon coherence
    bool b_ok = true;
    OGRLineString *tls = poly->getExteriorRing();
    if(!tls) {
        b_ok = false;
    }
    else {
        int tnpta  = poly->getExteriorRing()->getNumPoints();
        if(tnpta < 3 )
            b_ok = false;
    }

    
    for( iir=0 ; iir < poly->getNumInteriorRings() ; iir++)
    {
        int tnptr = poly->getInteriorRing(iir)->getNumPoints();
        if( tnptr < 3 )
            b_ok = false;
    }
    
    if( !b_ok )
        return ERROR_BAD_OGRPOLY;
    

#ifdef __WXMSW__
//  If using the OpenGL dlls provided with Windows,
//  load the dll and establish addresses of the entry points needed

#ifdef USE_GLU_DLL

    if(!s_glu_dll_ready)
    {


        s_hGLU_DLL = LoadLibrary("glu32.dll");
        if (s_hGLU_DLL != NULL)
        {
            s_lpfnTessProperty = (LPFNDLLTESSPROPERTY)GetProcAddress(s_hGLU_DLL,"gluTessProperty");
            s_lpfnNewTess = (LPFNDLLNEWTESS)GetProcAddress(s_hGLU_DLL, "gluNewTess");
            s_lpfnTessBeginContour = (LPFNDLLTESSBEGINCONTOUR)GetProcAddress(s_hGLU_DLL, "gluTessBeginContour");
            s_lpfnTessEndContour = (LPFNDLLTESSENDCONTOUR)GetProcAddress(s_hGLU_DLL, "gluTessEndContour");
            s_lpfnTessBeginPolygon = (LPFNDLLTESSBEGINPOLYGON)GetProcAddress(s_hGLU_DLL, "gluTessBeginPolygon");
            s_lpfnTessEndPolygon = (LPFNDLLTESSENDPOLYGON)GetProcAddress(s_hGLU_DLL, "gluTessEndPolygon");
            s_lpfnDeleteTess = (LPFNDLLDELETETESS)GetProcAddress(s_hGLU_DLL, "gluDeleteTess");
            s_lpfnTessVertex = (LPFNDLLTESSVERTEX)GetProcAddress(s_hGLU_DLL, "gluTessVertex");
            s_lpfnTessCallback = (LPFNDLLTESSCALLBACK)GetProcAddress(s_hGLU_DLL, "gluTessCallback");

            s_glu_dll_ready = true;
        }
        else
        {
            return ERROR_NO_DLL;
        }
    }

#endif
#endif


    //  Allocate a work buffer, which will be grown as needed
#define NINIT_BUFFER_LEN 10000
    s_pwork_buf = (GLdouble *)malloc(NINIT_BUFFER_LEN * 2 * sizeof(GLdouble));
    s_buf_len = NINIT_BUFFER_LEN * 2;
    s_buf_idx = 0;

      //    Create an array to hold pointers to allocated vertices created by "combine" callback,
      //    so that they may be deleted after tesselation.
    s_pCombineVertexArray = new wxArrayPtrVoid;

    //  Create tesselator
    GLUtessobj = gluNewTess();

    //  Register the callbacks
    gluTessCallback(GLUtessobj, GLU_TESS_BEGIN,   (GLvoid (__CALL_CONVENTION *) ())&beginCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_BEGIN,   (GLvoid (__CALL_CONVENTION *) ())&beginCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_VERTEX,  (GLvoid (__CALL_CONVENTION *) ())&vertexCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_END,     (GLvoid (__CALL_CONVENTION *) ())&endCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_COMBINE, (GLvoid (__CALL_CONVENTION *) ())&combineCallback);

//    gluTessCallback(GLUtessobj, GLU_TESS_ERROR,   (GLvoid (__CALL_CONVENTION *) ())&errorCallback);

//    glShadeModel(GL_SMOOTH);
    gluTessProperty(GLUtessobj, GLU_TESS_WINDING_RULE,
                    GLU_TESS_WINDING_POSITIVE );

    //  gluTess algorithm internally selects vertically oriented triangle strips and fans.
    //  This orientation is not optimal for conventional memory-mapped raster display shape filling.
    //  We can "fool" the algorithm by interchanging the x and y vertex values passed to gluTessVertex
    //  and then reverting x and y on the resulting vertexCallbacks.
    //  In this implementation, we will explicitely set the preferred orientation.

    //Set the preferred orientation
    tess_orient = TESS_HORZ;                    // prefer horizontal tristrips



//    PolyGeo BBox as lat/lon
    OGREnvelope Envelope;
    poly->getEnvelope(&Envelope);
    xmin = Envelope.MinX;
    ymin = Envelope.MinY;
    xmax = Envelope.MaxX;
    ymax = Envelope.MaxY;


//      Get total number of contours
    m_ncnt = 1;                         // always exterior ring
    int nint = poly->getNumInteriorRings();  // interior rings
    m_ncnt += nint;


//      Allocate cntr array
    cntr = (int *)malloc(m_ncnt * sizeof(int));


//      Get total number of points(vertices)
    int npta  = poly->getExteriorRing()->getNumPoints();
    cntr[0] = npta;
    npta += 2;                            // fluff

    for( iir=0 ; iir < nint ; iir++)
    {
        int nptr = poly->getInteriorRing(iir)->getNumPoints();
        cntr[iir+1] = nptr;

        npta += nptr + 2;
    }

//    printf("pPoly npta: %d\n", npta);

    geoPt = (GLdouble *)malloc((npta) * 3 * sizeof(GLdouble));     // vertex array



   //  Grow the work buffer if necessary

    if((npta * 4) > s_buf_len)
    {
        s_pwork_buf = (GLdouble *)realloc(s_pwork_buf, npta * 4 * sizeof(GLdouble));
        s_buf_len = npta * 4;
    }


//  Define the polygon
    gluTessBeginPolygon(GLUtessobj, NULL);


//      Create input structures

//    Exterior Ring
    int npte  = poly->getExteriorRing()->getNumPoints();
    cntr[0] = npte;

    GLdouble *ppt = geoPt;


//  Check and account for winding direction of ring
    bool cw = !(poly->getExteriorRing()->isClockwise() == 0);

    double x0, y0, x, y;
    OGRPoint p;

    if(cw)
    {
        poly->getExteriorRing()->getPoint(0, &p);
        x0 = p.getX();
        y0 = p.getY();
    }
    else
    {
        poly->getExteriorRing()->getPoint(npte-1, &p);
        x0 = p.getX();
        y0 = p.getY();
    }

    //  Transcribe contour to an array of doubles, with duplicates eliminated
    double *DPbuffer = (double *)malloc(npte * 2 * sizeof(double));
    double *DPrun = DPbuffer;
    int nPoints = npte;
    
    for(ip = 0 ; ip < npte ; ip++)
    {
        int pidx;
        if(cw)
            pidx = npte - ip - 1;
    
        else
            pidx = ip;
    
        poly->getExteriorRing()->getPoint(pidx, &p);
        x = p.getX();
        y = p.getY();
    
        if(  ((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS)))
        {
            GLdouble *ppt_temp = ppt;
            if(tess_orient == TESS_VERT)
            {
                *DPrun++ = x;
                *DPrun++ = y;
            }
            else
            {
                *DPrun++ = y;
                *DPrun++ = x;
            }
        
            x0 = x;
            y0 = y;
        }
        else
            nPoints--;
    
    }

 
    if(nPoints > 5 && (m_LOD_meters > .01)){
        index_keep.Clear();
        index_keep.Add(0);
        index_keep.Add(nPoints-1);
        index_keep.Add(1);
        index_keep.Add(nPoints-2);
        
        DouglasPeucker(DPbuffer, 1, nPoints-2, m_LOD_meters/(1852 * 60), &index_keep);
//        printf("DP Reduction: %d/%d\n", index_keep.GetCount(), nPoints);
        
        g_keep += index_keep.GetCount();
        g_orig += nPoints;
//        printf("...................Running: %g\n", (double)g_keep/g_orig);
    }
    else {
        index_keep.Clear();
        for(int i = 0 ; i < nPoints ; i++)
            index_keep.Add(i);
    }
    
    cntr[0] = index_keep.GetCount();
 
    
    // Mark the keepers by adding a simple constant to X
    for(unsigned int i=0 ; i < index_keep.GetCount() ; i++){
        int k = index_keep.Item(i);
        DPbuffer[2*k] += 2000.;
    }

    

    //  Declare the gluContour and copy the points
    gluTessBeginContour(GLUtessobj);
    
    DPrun = DPbuffer;
    for(ip = 0 ; ip < nPoints ; ip++)
    {
        x = *DPrun++;
        y = *DPrun++;
        
        if(x > 1000.){
            
            GLdouble *ppt_top = ppt;
            *ppt++ = x-2000;
            *ppt++ = y;
            *ppt++ = 0;
            
            gluTessVertex( GLUtessobj, ppt_top, ppt_top ) ;
        }
    }
    
    gluTessEndContour(GLUtessobj);
    
    free(DPbuffer);    
    
  
//  Now the interior contours
    for(iir=0 ; iir < nint ; iir++)
    {
        gluTessBeginContour(GLUtessobj);

        int npti = poly->getInteriorRing(iir)->getNumPoints();

      //  Check and account for winding direction of ring
        bool cw = !(poly->getInteriorRing(iir)->isClockwise() == 0);

        if(!cw)
        {
            poly->getInteriorRing(iir)->getPoint(0, &p);
            x0 = p.getX();
            y0 = p.getY();
        }
        else
        {
            poly->getInteriorRing(iir)->getPoint(npti-1, &p);
            x0 = p.getX();
            y0 = p.getY();
        }

//  Transcribe points to vertex array, in proper order with no duplicates
//   also, accounting for tess_orient
        for(int ip = 0 ; ip < npti ; ip++)
        {
            OGRPoint p;
            int pidx;
            if(!cw)                               // interior contours must be cw
                pidx = npti - ip - 1;
            else
                pidx = ip;

            poly->getInteriorRing(iir)->getPoint(pidx, &p);
            x = p.getX();
            y = p.getY();

            if((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS))
            {
                GLdouble *ppt_temp = ppt;
                if(tess_orient == TESS_VERT)
                {
                    *ppt++ = x;
                    *ppt++ = y;
                }
                else
                {
                    *ppt++ = y;
                    *ppt++ = x;
                }
                *ppt++ = 0.0;

                gluTessVertex( GLUtessobj, ppt_temp, ppt_temp ) ;

//       printf("tess from Poly, internal vertex %d %g %g\n", ip, x, y);

            }
            else
                cntr[iir+1]--;

            x0 = x;
            y0 = y;

        }

        gluTessEndContour(GLUtessobj);
    }

    //  Store some SM conversion data in static store,
    //  for callback access
    s_ref_lat = ref_lat;
    s_ref_lon = ref_lon;
    s_bSENC_SM = bSENC_SM;

    s_bmerc_transform = false;

    //      Ready to kick off the tesselator

    s_pTPG_Last = NULL;
    s_pTPG_Head = NULL;

    s_nvmax = 0;

    gluTessEndPolygon(GLUtessobj);          // here it goes

    m_nvertex_max = s_nvmax;               // record largest vertex count, updates in callback


    //  Tesselation all done, so...

    //  Create the data structures

    m_ppg_head = new PolyTriGroup;
    m_ppg_head->m_bSMSENC = s_bSENC_SM;

    m_ppg_head->nContours = m_ncnt;

    m_ppg_head->pn_vertex = cntr;             // pointer to array of poly vertex counts
    m_ppg_head->data_type = DATA_TYPE_DOUBLE;
    

//  Transcribe the raw geometry buffer
//  Converting to float as we go, and
//  allowing for tess_orient
//  Also, convert to SM if requested

// Recalculate the size of the geometry buffer
    int nptfinal = cntr[0] + 2;
    for(int i=0 ; i < nint ; i++)
        nptfinal += cntr[i+1] + 2;
    
    //  No longer need the full geometry in the SENC,
    nptfinal = 1;
    
    m_nwkb = (nptfinal + 1) * 2 * sizeof(float);
    m_ppg_head->pgroup_geom = (float *)calloc(sizeof(float), (nptfinal + 1) * 2);
    float *vro = m_ppg_head->pgroup_geom;
    ppt = geoPt;
    float tx,ty;

    for(ip = 0 ; ip < nptfinal ; ip++)
    {
        if(TESS_HORZ == tess_orient)
        {
            ty = *ppt++;
            tx = *ppt++;
        }
        else
        {
            tx = *ppt++;
            ty = *ppt++;
        }

        if(bSENC_SM)
        {
            //  Calculate SM from chart common reference point
            double easting, northing;
            toSM(ty, tx, ref_lat, ref_lon, &easting, &northing);
            *vro++ = easting;              // x
            *vro++ = northing;             // y
        }
        else
        {
            *vro++ = tx;                  // lon
            *vro++ = ty;                  // lat
        }

        ppt++;                      // skip z
    }

    m_ppg_head->tri_prim_head = s_pTPG_Head;         // head of linked list of TriPrims


    //  Convert the Triangle vertex arrays into a single memory allocation of floats
    //  to reduce SENC size and enable efficient access later
    
    //  First calculate the total byte size
    int total_byte_size = 2 * sizeof(float);
    TriPrim *p_tp = m_ppg_head->tri_prim_head;
    while( p_tp ) {
        total_byte_size += p_tp->nVert * 2 * sizeof(float);
        p_tp = p_tp->p_next; // pick up the next in chain
    }
    
    float *vbuf = (float *)malloc(total_byte_size);
    p_tp = m_ppg_head->tri_prim_head;
    float *p_run = vbuf;
    while( p_tp ) {
        float *pfbuf = p_run;
        GLdouble *pdouble_buf = (GLdouble *)p_tp->p_vertex;
        
        for( int i=0 ; i < p_tp->nVert * 2 ; ++i){
            float x = (float)( *((GLdouble *)pdouble_buf) );
            pdouble_buf++;
            *p_run++ = x;
        }
        
        free(p_tp->p_vertex);
        p_tp->p_vertex = (double *)pfbuf;
        p_tp = p_tp->p_next; // pick up the next in chain
    }
    m_ppg_head->bsingle_alloc = true;
    m_ppg_head->single_buffer = (unsigned char *)vbuf;
    m_ppg_head->single_buffer_size = total_byte_size;
    m_ppg_head->data_type = DATA_TYPE_FLOAT;
    
    
    
    
    
    
    gluDeleteTess(GLUtessobj);

    free( s_pwork_buf );
    s_pwork_buf = NULL;

    free (geoPt);

    //      Free up any "Combine" vertices created
    for(unsigned int i = 0; i < s_pCombineVertexArray->GetCount() ; i++)
          free (s_pCombineVertexArray->Item(i));
    delete s_pCombineVertexArray;

    m_bOK = true;

#endif          //    #ifdef ocpnUSE_GL
    
    return 0;
}
Ejemplo n.º 9
0
//      Build PolyTessGeo Object from OGR Polygon
//      Using OpenGL/GLU tesselator
int PolyTessGeo::BuildTessGLU()
{
    
    unsigned int iir, ip;
    GLdouble *geoPt;


#if 0    
    //  Make a quick sanity check of the polygon coherence
    bool b_ok = true;
    OGRLineString *tls = poly->getExteriorRing();
    if(!tls) {
        b_ok = false;
    }
    else {
        int tnpta  = poly->getExteriorRing()->getNumPoints();
        if(tnpta < 3 )
            b_ok = false;
    }

    
    for( iir=0 ; iir < poly->getNumInteriorRings() ; iir++)
    {
        int tnptr = poly->getInteriorRing(iir)->getNumPoints();
        if( tnptr < 3 )
            b_ok = false;
    }
    
    if( !b_ok )
        return ERROR_BAD_OGRPOLY;
    
#endif
    


    //  Allocate a work buffer, which will be grown as needed
#define NINIT_BUFFER_LEN 10000
    m_pwork_buf = (GLdouble *)malloc(NINIT_BUFFER_LEN * 2 * sizeof(GLdouble));
    m_buf_len = NINIT_BUFFER_LEN * 2;
    m_buf_idx = 0;

      //    Create an array to hold pointers to allocated vertices created by "combine" callback,
      //    so that they may be deleted after tesselation.
    m_pCombineVertexArray = new wxArrayPtrVoid;

    //  Create tesselator
    GLUtessobj = gluNewTess();

    //  Register the callbacks
    gluTessCallback(GLUtessobj, GLU_TESS_BEGIN_DATA,   (GLvoid (*) ())&beginCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_BEGIN_DATA,   (GLvoid (*) ())&beginCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_VERTEX_DATA,  (GLvoid (*) ())&vertexCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_END_DATA,     (GLvoid (*) ())&endCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_COMBINE_DATA, (GLvoid (*) ())&combineCallback);
    gluTessCallback(GLUtessobj, GLU_TESS_ERROR_DATA,   (GLvoid (*) ())&errorCallback);

    gluTessProperty(GLUtessobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
    gluTessNormal(GLUtessobj, 0, 0, 1);

//      Get total number of points(vertices)  to build a buffer
    int npta  = 0;

    for( int i=0 ; i < m_ncnt ; i++)
        npta += m_cntr[i];


    geoPt = (GLdouble *)malloc((npta + 6) * 3 * sizeof(GLdouble));     // vertex array



   //  Grow the work buffer if necessary

    if((npta * 4) > m_buf_len)
    {
        m_pwork_buf = (GLdouble *)realloc(m_pwork_buf, npta * 4 * sizeof(GLdouble));
        m_buf_len = npta * 4;
    }


//  Define the polygon
    gluTessBeginPolygon(GLUtessobj, this);


    
    //  Check and account for winding direction of ring


      double x0, y0, x, y;
//      OGRPoint p;

      wxPoint2DDouble *pp = (wxPoint2DDouble *)m_vertexPtrArray[0];
      bool cw = !isRingClockwise(pp, m_cntr[0]);
      
      //pp++;       // skip 0?

      if(cw)
      {
            x0 = pp->m_x;
            y0 = pp->m_y;
      }
      else
      {
            x0 = pp[m_cntr[0]-1].m_x;
            y0 = pp[m_cntr[0]-1].m_y;
      }



      unsigned int ptValid = m_cntr[0];
      
//  Transcribe points to vertex array, in proper order with no duplicates
//   also, accounting for tess_orient
      GLdouble *ppt = geoPt;
      
      for(ip = 0 ; ip < (unsigned int)m_cntr[0] ; ip++)
      {
            int pidx;
            if(cw)
                  pidx = m_cntr[0] - ip - 1;

            else
                  pidx = ip;

            x = pp[pidx].m_x;
            y = pp[pidx].m_y;

            if((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS))
            {
                  if(m_tess_orient == TESS_VERT)
                  {
                        *ppt++ = x;
                        *ppt++ = y;
                        *ppt++ = 0;
                  }
                  else
                  {
                        *ppt++ = y;
                        *ppt++ = x;
                        *ppt++ = 0;
                  }
            }
            else
                  ptValid--;

            x0 = x;
            y0 = y;
      }

      //  Apply LOD reduction
    int beforeLOD = ptValid;
    int afterLOD = beforeLOD;
   
 
    if(ptValid > 20 && (m_LOD_meters > .01)) {
        std::vector<bool> bool_keep(ptValid, false);

        // Keep a few key points
        bool_keep[0] = true;
        bool_keep[1] = true;
        bool_keep[ptValid-1] = true;
        bool_keep[ptValid-2] = true;
        
        DouglasPeuckerDI(geoPt, 1, ptValid-2, m_LOD_meters, bool_keep);
            
        // Create a new buffer
        double *LOD_result = (double *)malloc((m_cntr[0]) * 3 * sizeof(double));     
        double *plod = LOD_result;
        int kept_LOD =0;
        
        for(unsigned int i=0 ; i < ptValid ; i++){
            if(bool_keep[i]){
                double x = geoPt[i*3];
                double y = geoPt[(i*3) + 1];
                *plod++ = x;
                *plod++ = y;
                *plod++ = 0;
                kept_LOD++;
            }
        }

        beforeLOD = ptValid;
        afterLOD = kept_LOD;

        // Copy the lod points back into the vertex buffer
        memcpy(geoPt, LOD_result, kept_LOD * 3 * sizeof(double));
        
        free(LOD_result);
        ptValid = kept_LOD;
    }

    //  Declare the gluContour and copy the points
    gluTessBeginContour(GLUtessobj);
    
    double *DPrun = geoPt;
    for(ip = 0 ; ip < ptValid ; ip++) {
        gluTessVertex( GLUtessobj, DPrun, DPrun ) ;
        DPrun += 3;
    }
  
    gluTessEndContour(GLUtessobj);

    //  Now the interior contours
#if 1    
    int gpIndex = m_cntr[0];
    
    for(iir=0; iir < (unsigned int)m_ncnt-1; iir++){
        
            wxPoint2DDouble *pp = (wxPoint2DDouble *)m_vertexPtrArray[iir + 1];

            int npti  = m_cntr[iir+1];
            ptValid = npti;
            
            double *ppt = &geoPt[gpIndex * 3]; // next available location in geoPT
            double *DPStart = ppt;
            
      //  Check and account for winding direction of ring
            bool cw = isRingClockwise(pp, m_cntr[iir+1]);

            if(cw)
            {
                  x0 = pp[0].m_x;
                  y0 = pp[0].m_y;
            }
            else
            {
                  x0 = pp[npti-1].m_x;
                  y0 = pp[npti-1].m_y;
            }

//  Transcribe points to vertex array, in proper order with no duplicates
//   also, accounting for tess_orient
            for(int ip = 0 ; ip < npti ; ip++)
            {
                  int pidx;
                  if(cw)                               // interior contours must be cw
                        pidx = npti - ip - 1;
                  else
                        pidx = ip;


                  x = pp[pidx].m_x;
                  y = pp[pidx].m_y;

                  if((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS))
                  {
                        if(m_tess_orient == TESS_VERT)
                        {
                              *ppt++ = x;
                              *ppt++ = y;
                              *ppt++ = 0;
                        }
                        else
                        {
                              *ppt++ = y;
                              *ppt++ = x;
                              *ppt++ = 0;
                        }
                  }
                  else
                        ptValid--;

                  x0 = x;
                  y0 = y;

            }
            
                       //  Declare the gluContour and reference the points
            gluTessBeginContour(GLUtessobj);
    
            double *DPruni = DPStart;
            for(ip = 0 ; ip < ptValid ; ip++)
            {
                gluTessVertex( GLUtessobj, DPruni, DPruni ) ;
                DPruni += 3;
            }
        
            gluTessEndContour(GLUtessobj);

            gpIndex +=  m_cntr[iir+1];
      }
#endif
        
        
        
        

    m_pTPG_Last = NULL;
    m_pTPG_Head = NULL;
    m_nvmax = 0;

    //      Ready to kick off the tesselator
    gluTessEndPolygon(GLUtessobj);          // here it goes

    m_nvertex_max = m_nvmax;               // record largest vertex count, updates in callback


    //  Tesselation all done, so...

    //  Create the data structures

    m_ppg_head = new PolyTriGroup;
    m_ppg_head->m_bSMSENC = m_b_senc_sm;

    m_ppg_head->nContours = m_ncnt;

    m_ppg_head->pn_vertex = m_cntr;             // pointer to array of poly vertex counts
    m_ppg_head->data_type = DATA_TYPE_DOUBLE;
    

//  Transcribe the raw geometry buffer
//  Converting to float as we go, and
//  allowing for tess_orient
//  Also, convert to SM if requested

// Recalculate the size of the geometry buffer
    unsigned int nptfinal = m_cntr[0] + 2;
//     for(int i=0 ; i < nint ; i++)
//         nptfinal += cntr[i+1] + 2;
    
    //  No longer need the full geometry in the SENC,
    nptfinal = 1;
    
    m_nwkb = (nptfinal + 1) * 2 * sizeof(float);
    m_ppg_head->pgroup_geom = (float *)calloc(sizeof(float), (nptfinal + 1) * 2);
    float *vro = m_ppg_head->pgroup_geom;
    ppt = geoPt;
    float tx,ty;

    for(ip = 0 ; ip < nptfinal ; ip++)
    {
        if(TESS_HORZ == m_tess_orient)
        {
            ty = *ppt++;
            tx = *ppt++;
        }
        else
        {
            tx = *ppt++;
            ty = *ppt++;
        }

        if(m_b_senc_sm)
        {
            //  Calculate SM from chart common reference point
            double easting, northing;
            toSM(ty, tx, m_ref_lat, m_ref_lon, &easting, &northing);
            *vro++ = easting;              // x
            *vro++ = northing;             // y
        }
        else
        {
            *vro++ = tx;                  // lon
            *vro++ = ty;                  // lat
        }

        ppt++;                      // skip z
    }

    m_ppg_head->tri_prim_head = m_pTPG_Head;         // head of linked list of TriPrims


    //  Convert the Triangle vertex arrays into a single memory allocation of floats
    //  to reduce SENC size and enable efficient access later
    
    //  First calculate the total byte size
    int total_byte_size = 2 * sizeof(float);
    TriPrim *p_tp = m_ppg_head->tri_prim_head;
    while( p_tp ) {
        total_byte_size += p_tp->nVert * 2 * sizeof(float);
        p_tp = p_tp->p_next; // pick up the next in chain
    }
    
    float *vbuf = (float *)malloc(total_byte_size);
    p_tp = m_ppg_head->tri_prim_head;
    float *p_run = vbuf;
    while( p_tp ) {
        float *pfbuf = p_run;
        GLdouble *pdouble_buf = (GLdouble *)p_tp->p_vertex;
        
        for( int i=0 ; i < p_tp->nVert * 2 ; ++i){
            float x = (float)( *((GLdouble *)pdouble_buf) );
            pdouble_buf++;
            *p_run++ = x;
        }
        
        free(p_tp->p_vertex);
        p_tp->p_vertex = (double *)pfbuf;
        p_tp = p_tp->p_next; // pick up the next in chain
    }
    m_ppg_head->bsingle_alloc = true;
    m_ppg_head->single_buffer = (unsigned char *)vbuf;
    m_ppg_head->single_buffer_size = total_byte_size;
    m_ppg_head->data_type = DATA_TYPE_FLOAT;
    
    
    
    
    
    
    gluDeleteTess(GLUtessobj);

    free( m_pwork_buf );
    m_pwork_buf = NULL;

    free (geoPt);

    //      Free up any "Combine" vertices created
    for(unsigned int i = 0; i < m_pCombineVertexArray->GetCount() ; i++)
          free (m_pCombineVertexArray->Item(i));
    delete m_pCombineVertexArray;

    m_bOK = true;

    
    return 0;
}
Ejemplo n.º 10
0
void CMFCTessView::OnDraw(CDC* pDC)
{
	CMFCTessDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	//some per-drawing init stuff
	glLoadIdentity();

	//setup drawing dimensions, etc
	CPoint vptorg = m_pDC->GetViewportOrg() ; //note m_pDC, NOT pDC
	CRect rect ;
	GetWindowRect( &rect ) ;
	int dx = rect.Width() ;
	int dy = rect.Height() ;
	glViewport( 0, 0, dx, dy );

	glMatrixMode( GL_MODELVIEW );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	// create bitmaps for the device context font's first 256 glyphs 
	HDC hdc = m_pDC->GetSafeHdc() ;
	wglUseFontBitmaps(hdc, 0, 256, 1000); 
	glListBase(1000);

	float R ;
	if( pDoc->m_ContourList.GetCount() > 0 )
	{
		CalculateExtents() ; // Collect overall figure extents (in meters)
		R = Radius ;

		//11/29/03 experiment to eliminate probs w/non-square windows
		float glleft = -R ;
		float gltop = +R ;
		float nearplane = -R ; //rev 07/25/03
		float farplane = R ; //rev 07/25/03

		float glleft2 = glleft ;
		float gltop2 = gltop ;
		float glright2 = ( glleft + 2*R ) ;
		float glbottom2 = ( gltop - 2*R ) ;

		//adjust for non-square viewing window
		float dxdy = (float)dx/(float)dy ;  //=1.00 for square window
		if( dxdy > 1 )
		{
			glOrtho( glleft2*dxdy , glright2*dxdy, glbottom2, gltop2, nearplane, farplane ) ;
		}
		else
		{
			glOrtho( glleft2 , glright2, glbottom2/dxdy, gltop2/dxdy, nearplane, farplane ) ;
		}
		
		glTranslatef( -m_Center.x, -m_Center.y, -m_Center.z ) ;
	}
	else
	{  
		CString txtstr ;
		glOrtho( -1.f , 1.f, -1.f, 1.f, -1.f, 1.f ) ;
		glTranslatef( 0.f, 0.f, 0.f ) ;
		txtstr = "Nothing to draw" ;
		glColor3f( 0.f, 0.f, 0.f ) ;
		glRasterPos3f(0.0F, 0.0F, 0.0F ); 
		glCallLists(txtstr.GetLength(), GL_UNSIGNED_BYTE, txtstr); 

		//clean up & exit
		glFlush(); 
		glDeleteLists(1000, 256) ; 
		SwapBuffers( m_pDC->GetSafeHdc() );
		return ;
	}

	glPushMatrix() ;

	//01/09/05 implement tessellation
	GLUtesselator *tobj;
	tobj = gluNewTess();

	//added 02/09/05 as part of mem leak fix
	while( gm_VertexPtrList.GetCount() > 0 )
	{
		GLdouble* pV = (GLdouble*)gm_VertexPtrList.RemoveHead() ;
		delete[] pV ;
		pV = NULL ;
	}

	gluTessCallback(tobj, GLU_TESS_BEGIN, (void (CALLBACK *) ())beginCallback);
	gluTessCallback(tobj, GLU_TESS_VERTEX, (void (CALLBACK *) ()) vertexCallback);
	gluTessCallback(tobj, GLU_TESS_END, (void (CALLBACK *) ())endCallback);
	gluTessCallback(tobj, GLU_TESS_ERROR,(void (CALLBACK *) ())errorCallback);
	gluTessCallback(tobj, GLU_TESS_COMBINE, (void (CALLBACK *) ())combineCallback);

	glShadeModel(GL_SMOOTH);    
	gluTessProperty(tobj, GLU_TESS_WINDING_RULE,
               m_WindingRule );

	//only one polygon, but multiple contours
	gluTessBeginPolygon(tobj, NULL);


	POSITION pos = pDoc->m_ContourList.GetHeadPosition() ;
	while ( pos ) 
	{
		CContour* pCtr = (CContour*)pDoc->m_ContourList.GetNext( pos ) ;
		ASSERT( pCtr != NULL && pCtr->m_NumVertex > 0 && pCtr->m_ppVertexArray != NULL ) ;
		int numcorners = pCtr->m_NumVertex ;

		gluTessBeginContour(tobj);

		for( int cnridx = 0; cnridx < numcorners; cnridx++ )
		{
			GLdouble* glvert = pCtr->m_ppVertexArray[cnridx];
			gluTessVertex( tobj, glvert, glvert ) ;
		   TRACE( "Draw: Sent vertex(%f,%f,%f,%f,%f,%f)\n", glvert[0],glvert[1],glvert[2],glvert[3],glvert[4],glvert[5] ) ;
		}

		gluTessEndContour(tobj);
		
	} //end of all contour definitions

		gluTessEndPolygon(tobj);

	//clean up & exit
	glFlush(); 
	glDeleteLists(1000, 256) ; // delete our 256 glyph display lists 
	SwapBuffers( m_pDC->GetSafeHdc() );
	gluDeleteTess( tobj ) ;

	//added 02/09/05 as part of mem leak fix
	while( gm_VertexPtrList.GetCount() > 0 )
	{
		GLdouble* pV = (GLdouble*)gm_VertexPtrList.RemoveHead() ;
		delete[] pV ;
		pV = NULL ;
	}
}
Ejemplo n.º 11
0
PsychError SCREENFillPoly(void)  
{	
	PsychColorType				color;
	PsychWindowRecordType		*windowRecord;
	double						whiteValue;
	int							i, mSize, nSize, pSize;
	psych_bool					isArgThere;
	double						*pointList;
	double						isConvex;
	int							j,k;
	int							flag;
	double						z;
	
	combinerCacheSlot = 0;
	combinerCacheSize = 0;
	combinerCache = NULL;
	
	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous arguments
	PsychErrorExit(PsychCapNumInputArgs(4));   //The maximum number of inputs
	PsychErrorExit(PsychCapNumOutputArgs(0));  //The maximum number of outputs
	
	//get the window record from the window record argument and get info from the window record
	PsychAllocInWindowRecordArg(1, kPsychArgRequired, &windowRecord);
	
	//Get the color argument or use the default, then coerce to the form determened by the window depth.  
	isArgThere=PsychCopyInColorArg(2, FALSE, &color);
	if(!isArgThere){
		whiteValue=PsychGetWhiteValueFromWindow(windowRecord);
		PsychLoadColorStruct(&color, kPsychIndexColor, whiteValue ); //index mode will coerce to any other.
	}
 	PsychCoerceColorMode( &color);
	
	//get the list of pairs and validate.  
	PsychAllocInDoubleMatArg(3, kPsychArgRequired, &mSize, &nSize, &pSize, &pointList);
	if(nSize!=2) PsychErrorExitMsg(PsychError_user, "Width of pointList must be 2");
	if(mSize<3)  PsychErrorExitMsg(PsychError_user, "Polygons must consist of at least 3 points; M dimension of pointList was < 3!");
	if(pSize>1)  PsychErrorExitMsg(PsychError_user, "pointList must be a 2D matrix, not a 3D matrix!");
	
	isConvex = -1;
	PsychCopyInDoubleArg(4, kPsychArgOptional, &isConvex);
	
    // On non-OpenGL1/2 we always force isConvex to zero, so the GLU tesselator is
    // always used. This because the tesselator only emits GL_TRIANGLES and GL_TRIANGLE_STRIP
    // and GL_TRIANGLE_FANS primitives which are supported on all current OpenGL API's, whereas
    // or "classic" fast-path needs GL_POLYGONS, which are only supported on classic OpenGL1/2:
    if (!PsychIsGLClassic(windowRecord)) isConvex = 0;

	// Enable this windowRecords framebuffer as current drawingtarget:
	PsychSetDrawingTarget(windowRecord);
	
	// Set default drawshader:
	PsychSetShader(windowRecord, -1);
	
	PsychUpdateAlphaBlendingFactorLazily(windowRecord);		 
	PsychSetGLColor(&color, windowRecord);
	
	///////// Test for convexity ////////
	// This algorithm checks, if the polygon is definitely convex, or not.
	// We take the slow-path, if polygon is non-convex or if we can't prove
	// that it is convex.
	//
	// Algorithm adapted from: http://astronomy.swin.edu.au/~pbourke/geometry/clockwise/
	// Which was written by Paul Bourke, 1998.
	//
	// -> This webpage explains the mathematical principle behind the test and provides
	// a C-Source file which has been adapted for use here.
	//	
	if (isConvex == -1) {
		flag = 0;
		for (i=0; i < mSize; i++) {
			j = (i + 1) % mSize;
			k = (i + 2) % mSize;
			z  = (pointList[j] - pointList[i]) * (pointList[k+mSize] - pointList[j+mSize]);
			z -= (pointList[j+mSize] - pointList[i+mSize]) * (pointList[k] - pointList[j]);
			
			if (z < 0) {
				flag |= 1;
			}
			else if (z > 0) {
				flag |= 2;
			}
			
			if (flag == 3) {
				// This is definitely a CONCAVE polygon --> not Convex --> Take slow but safe path.
				break;
			}
		}
		
		if (flag!=0 && flag!=3) {
			// This is a convex polygon --> Take fast path.
			isConvex = 1;
		}
		else {
			// This is a complex polygon --> can't determine if it is convex or not --> Take slow but safe path.
			isConvex = 0;
		}
	}
			
	////// Switch between fast path and slow path, depending on convexity of polygon:
	if (isConvex > 0) {
		// Convex, non-self-intersecting polygon - Take the fast-path:
		glBegin(GL_POLYGON);
		for(i=0;i<mSize;i++) glVertex2d((GLdouble)pointList[i], (GLdouble)pointList[i+mSize]);
		glEnd();
	}
	else {
		// Possibly concave and/or self-intersecting polygon - At least we couldn't prove it is convex.
		// Take the slow, but safe, path using GLU-Tesselators to break it up into a couple of convex, simple
		// polygons:
		
		// Create and initialize a new GLU-Tesselator object, if needed:
		if (NULL == tess) {
			// Create tesselator:
			tess = gluNewTess();
			if (NULL == tess) PsychErrorExitMsg(PsychError_outofMemory, "Out of memory condition in Screen('FillPoly')! Not enough space.");

			// Assign our callback-functions:
			gluTessCallback(tess, GLU_TESS_BEGIN, GLUTESSCBCASTER PsychtcbBegin);
			gluTessCallback(tess, GLU_TESS_VERTEX, GLUTESSCBCASTER PsychtcbVertex);
			gluTessCallback(tess, GLU_TESS_END, GLUTESSCBCASTER PsychtcbEnd);
			gluTessCallback(tess, GLU_TESS_COMBINE, GLUTESSCBCASTER PsychtcbCombine);

			// Define all tesselated polygons to lie in the x-y plane:
			gluTessNormal(tess, 0, 0, 1);
		}

		// We need to hold the values in a temporary array:
		if (tempvsize < mSize) {
			tempvsize = ((mSize / 1000) + 1) * 1000;
			tempv = (double*) realloc((void*) tempv, sizeof(double) * 3 * tempvsize);
			if (NULL == tempv) PsychErrorExitMsg(PsychError_outofMemory, "Out of memory condition in Screen('FillPoly')! Not enough space.");
		}

		// Now submit our Polygon for tesselation:
		gluTessBeginPolygon(tess, NULL);
		gluTessBeginContour(tess);

		for(i=0; i < mSize; i++) {
			tempv[i*3]=(GLdouble) pointList[i];
			tempv[i*3+1]=(GLdouble) pointList[i+mSize];
			tempv[i*3+2]=0;
			gluTessVertex(tess, (GLdouble*) &(tempv[i*3]), (void*) &(tempv[i*3]));
		}
		
		// Process, finalize and render it by calling our callback-functions:
		gluTessEndContour(tess);
		gluTessEndPolygon (tess);
		
		// Done with drawing the filled polygon. (Slow-Path)
	}
	
	// Mark end of drawing op. This is needed for single buffered drawing:
	PsychFlushGL(windowRecord);
	
	// printf("CombinerCalls %i out of %i allocated.\n", combinerCacheSlot, combinerCacheSize);

	return(PsychError_none);
}
Ejemplo n.º 12
0
void SeedGLWidget::selectRegion()
{
	/*if (_seedRegions.empty())
	{
		return;
	}*/

	glViewport (0, 0, 1024, 1024);

	glBindTexture(GL_TEXTURE_2D, 0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboId);
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

	glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
	glClear (GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, _widgetWidth-_planeWidth, _widgetHeight, 0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glColor3f(1, 1, 1);

	gluTessBeginPolygon(tessObj, NULL);
	gluTessBeginContour(tessObj);
	for (int i=0; i<_penTrack.size(); ++i)
	{
		gluTessVertex(tessObj, _penTrack[i], _penTrack[i]);
	}
	gluTessEndContour(tessObj);
	gluTessEndPolygon(tessObj);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	GLubyte * tempBuffer = new GLubyte [1024*1024];
	glBindTexture(GL_TEXTURE_2D, _texId);
	glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, tempBuffer);

	GLdouble modelMatrix[16];
	GLdouble projMatrix[16];
	int viewport[4];

	int viewportWidth = _viewportHeight*(_widgetWidth-_planeWidth)*1.0/_widgetHeight;
	glViewport (0, 0, 1024, 1024);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, viewportWidth, 0, _viewportHeight, -2000, 2000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(_translateX, _translateY, 0);
	glTranslatef(viewportWidth/2.0, _viewportHeight/2.0, 0);
	setRotationMatrix();
	_volumeData->setTransformMatrix();

	glGetIntegerv(GL_VIEWPORT, viewport);
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);

	int minX = floor(_minDrawX*1023.0/(_widgetWidth-_planeWidth-1));
	int maxX = ceil(_maxDrawX*1023.0/(_widgetWidth-_planeWidth-1));
	int minY = floor((_widgetHeight-_maxDrawY)*1023.0/(_widgetHeight-1));
	int maxY = ceil((_widgetHeight-_minDrawY)*1023.0/(_widgetHeight-1));

	for (int i=minX; i<=maxX; ++i)
	{
		for (int j=minY; j<maxY; ++j)
		{
			if (tempBuffer[j*1024+i]>0)
			{
				double x, y, z;
				gluUnProject(i, j, 0, modelMatrix, projMatrix, viewport, &x, &y, &z);
				//add to seed region list

				switch (_viewpoint)
				{
				case 1: //AXIAL
					z = _seedData->_aSliceIdx;
					break;
				case 2: //CORONAL
					y = _seedData->_cSliceIdx;
					break;
				case 3: //SAGITTAL
					x = _seedData->_pSliceIdx;
					break;
				}
				if (_bAddRegion)
				{
					_seedData->addSeedPoint(x,y,z, _currentSeedIndex);
				} else
				{
					_seedData->removeSeedPoint(x,y,z,_currentSeedIndex);
				}
			}
		}
	}

	delete tempBuffer;

	_seedData->setASlice(_aSlicePos);
	_seedData->setPSlice(_pSlicePos);
	_seedData->setCSlice(_cSlicePos);

}
Ejemplo n.º 13
0
// tesselates the contours in preparation for a 3D output;
// returns true if all was fine, false otherwise
bool VRML_LAYER::Tesselate( VRML_LAYER* holes, bool aHolesOnly )
{
    if( !tess )
    {
        error = "Tesselate(): GLU tesselator was not initialized";
        return false;
    }

    pholes  = holes;
    Fault   = false;

    if( aHolesOnly )
        gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NEGATIVE );
    else
        gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );


    if( contours.size() < 1 || vertices.size() < 3 )
    {
        error = "Tesselate(): not enough vertices";
        return false;
    }

    // finish the winding calculation on all vertices prior to setting 'fix'
    if( !fix )
    {
        for( unsigned int i = 0; i < contours.size(); ++i )
        {
            if( contours[i]->size() < 3 )
                continue;

            VERTEX_3D* vp0 = vertices[ contours[i]->back() ];
            VERTEX_3D* vp1 = vertices[ contours[i]->front() ];
            areas[i] += ( vp1->x - vp0->x ) * ( vp1->y + vp0->y );
        }
    }

    // prevent the addition of any further contours and contour vertices
    fix = true;

    // clear temporary internals which may have been used in a previous run
    clearTmp();

    // request an outline
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE );

    // adjust internal indices for extra points and holes
    if( holes )
        hidx = holes->GetSize();
    else
        hidx = 0;

    eidx = idx + hidx;

    if( aHolesOnly && ( checkNContours( true ) == 0 ) )
    {
        error = "tesselate(): no hole contours";
        return false;
    }
    else if( !aHolesOnly && ( checkNContours( false ) == 0 ) )
    {
        error = "tesselate(): no solid contours";
        return false;
    }

    // open the polygon
    gluTessBeginPolygon( tess, this );

    if( aHolesOnly )
    {
        pholes = NULL;  // do not accept foreign holes
        hidx = 0;
        eidx = idx;

        // add holes
        pushVertices( true );

        gluTessEndPolygon( tess );

        if( Fault )
            return false;

        return true;
    }

    // add solid outlines
    pushVertices( false );

    // close the polygon
    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    // if there are no outlines we cannot proceed
    if( outline.empty() )
    {
        error = "tesselate(): no points in result";
        return false;
    }

    // at this point we have a solid outline; add it to the tesselator
    gluTessBeginPolygon( tess, this );

    if( !pushOutline( NULL ) )
        return false;

    // add the holes contained by this object
    pushVertices( true );

    // import external holes (if any)
    if( hidx && ( holes->Import( idx, tess ) < 0 ) )
    {
        std::ostringstream ostr;
        ostr << "Tesselate():FAILED: " << holes->GetError();
        error = ostr.str();
        return false;
    }

    if( Fault )
        return false;

    // erase the previous outline data and vertex order
    // but preserve the extra vertices
    while( !outline.empty() )
    {
        delete outline.back();
        outline.pop_back();
    }

    ordmap.clear();
    ord = 0;

    // go through the vertex lists and reset ephemeral parameters
    for( unsigned int i = 0; i < vertices.size(); ++i )
    {
        vertices[i]->o = -1;
    }

    for( unsigned int i = 0; i < extra_verts.size(); ++i )
    {
        extra_verts[i]->o = -1;
    }

    // close the polygon; this creates the outline points
    // and the point ordering list 'ordmap'
    solid.clear();
    gluTessEndPolygon( tess );

    // repeat the last operation but request a tesselated surface
    // rather than an outline; this creates the triangles list.
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE );

    gluTessBeginPolygon( tess, this );

    if( !pushOutline( holes ) )
        return false;

    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    return true;
}
Ejemplo n.º 14
0
void MapDrawFunction(AG_Event *event)
{
    GLdouble vz = -2.0;
    GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
    GLfloat diffuse[4] = { 1.f, 1.0f, 1.0f, 1.0f };
    GLfloat specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
    int wireframe = 0;
    enum { FLATSHADING, SMOOTHSHADING } shading = FLATSHADING;

    int i;
	GLfloat pos[4];

	glLoadIdentity();
	glPushAttrib(GL_POLYGON_BIT|GL_LIGHTING_BIT|GL_DEPTH_BUFFER_BIT);

    glEnable(GL_POINT_SMOOTH);

    glEnable(GL_DEPTH_TEST);

    //glEnable(GL_LIGHTING);
    //glEnable(GL_LIGHT0);

// Create light components
    //GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 0.1f };
    GLfloat diffuseLight[] = { 1, 1, 1, 1.0f };
    GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
    GLfloat position[] = { cursorwX, cursorwY, 0.5f, 1.0f };

// Assign created components to GL_LIGHT0
    //glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
    glLightfv(GL_LIGHT0, GL_POSITION, position);

    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
    glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.002f);
    glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

    glClearColor(0.0f,0.0f,0.0f,1.0f);

	glPushMatrix();
	glTranslated(0.0, 0.0, vz);
    GLfloat visi[4]={1.0,0.0,0.0,1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, visi);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, visi);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, visi);




    glColor3f(0.9,0.9,0.6);

    mapdraw();

    for (int i=0;i<sceneVertices.size();i++){
        glBegin(GL_LINE_LOOP);
        for (int j=0;j<sceneVertices[i].size();j++){
            glVertex3f( sceneVertices[i][j][0], sceneVertices[i][j][1], 0.0f);
        };
        glEnd();
    };



    glColor3f(0.9,0.9,0.0);
    for (int i=0;i<mapEnvCollision.h()+1;i++){
        glBegin(GL_LINE_LOOP);
        for (int j=0;j<mapEnvCollision[i].n();j++){
            glVertex3f( mapEnvCollision[i][j].x(), mapEnvCollision[i][j].y(), 0.0f);
        };
        //glVertex3f( sceneVertices[i][0].x(), sceneVertices[i][0].y(), 0.0f);
        glEnd();
    };



    gluTessBeginPolygon (tess, NULL);
    gluTessBeginContour (tess);

    GLdouble data[visiBounded.outer_boundary().size()][3];

    CGAL::Polygon_2<Kernel>::Vertex_iterator  vit;
    i=0;
    for  (vit=visiBounded.outer_boundary().vertices_begin();vit!=visiBounded.outer_boundary().vertices_end();++vit)
    {
        data[i][0]=vit->x();
        data[i][1]=vit->y();
        data[i][2]=0;
        gluTessVertex (tess, data[i], data[i]);
        i++;
    }
    /*
    for (i=0; i<visiPoly.n();i++)
    {
        data[i][0]=visiPoly[i].x();
        data[i][1]=visiPoly[i].y();
        data[i][2]=0;
        gluTessVertex (tess, data[i], data[i]);
    }
    */
    gluTessEndContour (tess);
    gluEndPolygon (tess);

    glBegin(GL_LINE_LOOP);
        for (int i=0;i<visiPoly.n();i++){
            glVertex3f(visiPoly[i].x(),visiPoly[i].y(),0.0f);
        }
    glEnd();

    glColor3f(1.0,0.0,0.0);
    glBegin(GL_LINE_STRIP);
        for (int i=0;i<motionPath.size();i++){
            glVertex3f(motionPath[i].x(),motionPath[i].y(),0.1f);
        }
    glEnd();


    //glPopMatrix();
    GLfloat marker[4]={1.0,0.0,0.0,1.0};
    //glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, marker);
    glColor3f(1.0,0.0,0.0);
    guest1.Draw();


    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
    glGetDoublev(GL_PROJECTION_MATRIX,projection);
    glGetIntegerv(GL_VIEWPORT,viewport) ;


    glColor3f(1.0,1.0,1.0);
    glBegin(GL_TRIANGLES);
        glVertex3f(cursorwX,cursorwY+1/sqrt(2)*10,1.0f);
        glVertex3f(cursorwX-1/sqrt(2)*10,cursorwY-1/sqrt(2)*10,1.0f);
        glVertex3f(cursorwX+1/sqrt(2)*10,cursorwY-1/sqrt(2)*10,1.0f);
    glEnd();


    glPopMatrix();
    glPopAttrib();

    };
void ProtoTessellator::beginPolygon() {
	//tessellatedPrims = tessPrims;
	
	gluTessBeginPolygon(tesselator, NULL);
}
Ejemplo n.º 16
0
void Boundary::render(bool invert) {
  // Calculate the geometry of the border
  calculate();

  //glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE);

  // Render the border
  glBegin(GL_QUADS);
  for (int i = 0; i < outerEdges.size(); i++) {
    Edge out = outerEdges[i];
    Edge in = innerEdges[i];

    if (!invert) {
      glColor4f(0.0, 0.0, 0.0, 0.0);
    } else {
      glColor4f(1.0, 1.0, 1.0, 1.0);
    }
    glVertex3f(out.a.x, out.a.y, 0.0);
    glVertex3f(out.b.x, out.b.y, 0.0);
    
    if (!invert) {
      glColor4f(1.0, 1.0, 1.0, 1.0);
    } else {
      glColor4f(0.0, 0.0, 0.0, 0.0);
    }
    glVertex3f(in.b.x, in.b.y, 0.0);
    glVertex3f(in.a.x, in.a.y, 0.0);
  }
  glEnd();
  
  // Fill the border
  if (!invert) {
    glColor3f(1.0, 1.0, 1.0);
  } else {
    glColor3f(0.0, 0.0, 0.0);
  }

  GLUtesselator *tess = gluNewTess();

  gluTessCallback(tess, GLU_TESS_BEGIN, (GLvoid (*) ()) &glBegin);
  gluTessCallback(tess, GLU_TESS_END, (GLvoid (*) ()) &glEnd);
  gluTessCallback(tess, GLU_TESS_VERTEX, (GLvoid (*) ()) &glVertex3dv); 
  
  gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);   
  gluTessNormal(tess, 0, 0, 1);

  gluTessBeginPolygon(tess, NULL);
  gluTessBeginContour(tess);

  GLdouble *vertices = new GLdouble[innerEdges.size() * 3];
  for (int i = 0; i < innerEdges.size(); i++) {
    vertices[(i * 3) + 0] = innerEdges[i].a.x;
    vertices[(i * 3) + 1] = innerEdges[i].a.y;
    vertices[(i * 3) + 2] = 0.0;

    gluTessVertex(tess, vertices + (i * 3), vertices + (i * 3));
  }

  gluTessEndContour(tess);
  gluTessEndPolygon(tess);

  delete [] vertices;
  gluDeleteTess(tess);
}
Ejemplo n.º 17
0
void XMGPolygon::SetCoordArray ( const XMGVector2X* src_arr_coord, XMGTexUnit unit, GLuint src_idx_shape, GLuint src_idx_facet )
{
	XMGPolygonImpl*	impl = (XMGPolygonImpl *) m_impl;
	XMGRenderImpl*  impl_parent = (XMGRenderImpl *) XMGRender::m_impl;

	XMGTess*		data;

	XMGShape*		shape;
	XMGFacet*		facet;

	GLuint			idx_tess;
	GLuint			idx_shape;
	GLuint			idx_facet;
	GLuint			idx_vertex;

	GLuint			num_shape;
	GLuint			num_facet;
	GLuint			num_vertex;

	GLuint			off_src;

	XMGVector2F*	farr_coord;
	XMGVector2X*	xarr_coord;

	XMGRender::SetCoordArray ( src_arr_coord, unit, src_idx_shape, src_idx_facet );	

	if ( impl_parent->m_has_face[ 0 ] == XMG_FALSE && impl_parent->m_has_face[ 1 ] )
	{
		return;
	}

	if ( src_idx_facet != XMG_FACET_ALL )
	{
		shape = impl_parent->m_vec_shape[ src_idx_facet ];
		facet = shape->m_vec_facet[ src_idx_facet ];
		if ( facet->m_vec_contour.size ( ) == 0 )
		{
			return;
		}
	}

	off_src = 0;
	for ( impl_parent->RangeArray ( src_idx_shape, impl_parent->m_vec_shape.size ( ), idx_shape, num_shape ); idx_shape < num_shape; idx_shape++ )
	{
		shape = impl_parent->m_vec_shape[ idx_shape ];
		
		for ( impl_parent->RangeArray ( src_idx_facet, shape->m_vec_facet.size ( ), idx_facet, num_facet ); idx_facet < num_facet; idx_facet++ )
		{
			facet = shape->m_vec_facet[ idx_facet ];

			if ( idx_facet < 2 )
			{
				switch ( impl_parent->m_geo_type )
				{
					case XMG_GEO_CONE	:
					case XMG_GEO_CWALL	:	idx_tess = 1;			break;
					default				:	idx_tess = idx_facet;	break;
				}

				if ( impl->m_tess[ idx_tess ] )
				{
					data = impl->m_data[ idx_tess ][ idx_shape ];
					data->Init ( XMG_TESS_COORD );

					gluTessBeginPolygon ( impl->m_tess[ idx_tess ], (GLvoid *) data );
					gluTessBeginContour ( impl->m_tess[ idx_tess ] );	

					for ( idx_vertex = 0, num_vertex = shape->m_num_basic; idx_vertex < num_vertex; idx_vertex++ )
					{
						data->m_arr_vertex[ idx_vertex * 8 + 6 ] = XMG_X2F ( src_arr_coord[ off_src + idx_vertex ].m_x );
						data->m_arr_vertex[ idx_vertex * 8 + 7 ] = XMG_X2F ( src_arr_coord[ off_src + idx_vertex ].m_y );

						if ( shape->m_idx_hole != 0 && shape->m_idx_hole == idx_vertex )
						{
							gluNextContour ( impl->m_tess[ idx_tess ], GLU_INTERIOR );
						}

						gluTessVertex ( impl->m_tess[ idx_tess ], &data->m_arr_vertex[ idx_vertex * 8 ], &data->m_arr_vertex[ idx_vertex * 8 ] );
					}

					gluTessEndContour ( impl->m_tess[ idx_tess ] );
					gluTessEndPolygon ( impl->m_tess[ idx_tess ] );

					if ( impl_parent->m_type_coords[ unit ] == XMG_TYPE_FLOAT )
					{
						XMGAssert ( farr_coord = (XMGVector2F *) kdMalloc ( sizeof ( XMGVector2F ) * facet->m_num_ext ) );

						for ( idx_vertex = 0, num_vertex = facet->m_num_ext; idx_vertex < num_vertex; idx_vertex++ )
						{
							farr_coord[ idx_vertex ] = data->m_vec_coord[ idx_vertex ];
						}

						impl_parent->SetBuffer ( impl_parent->m_id_coords[ unit ], farr_coord, sizeof ( XMGVector2F ) * facet->m_off_ext, sizeof ( XMGVector2F ) * facet->m_num_ext );
						kdFree ( farr_coord );
					}
					else
					{
						XMGAssert ( xarr_coord = (XMGVector2X *) kdMalloc ( sizeof ( XMGVector2X ) * facet->m_num_ext ) );

						for ( idx_vertex = 0, num_vertex = facet->m_num_ext; idx_vertex < num_vertex; idx_vertex++ )
						{
							xarr_coord[ idx_vertex ] = data->m_vec_coord[ idx_vertex ];
						}

						impl_parent->SetBuffer ( impl_parent->m_id_coords[ unit ], xarr_coord, sizeof ( XMGVector2X ) * facet->m_off_ext, sizeof ( XMGVector2X ) * facet->m_num_ext );
						kdFree ( xarr_coord );
					}
				}			
			}

			off_src += facet->m_num_vertex;
		}
	}
}
Ejemplo n.º 18
0
void XMGPolygon::SetVertexArray ( const XMGVector3X* src_arr_vertex, const GLuint* arr_idx_hole )
{
	XMGPolygonImpl*	impl = (XMGPolygonImpl *) m_impl;
	XMGRenderImpl*  impl_parent = (XMGRenderImpl *) XMGRender::m_impl;

	XMGTess*		data[2];
	XMGShape*		shape;
	XMGFacet*		facet;
	XMGContour*		contour;

	GLuint			idx_tess;
	GLuint			idx_shape;
	GLuint			idx_facet;
	GLuint			idx_vertex;
	GLuint			idx_vec;
	
	GLuint			num_shape;
	GLuint			num_vertex;
	GLuint			num_vec;

	GLuint			off_vertex;
	GLuint			off_ext;

	XMGVector3X		src_vertex;
	XMGVector3X*	arr_vertex;

	off_vertex = 0;
	off_ext = impl_parent->m_num_vertex;
	impl_parent->m_ext_vertex = 0;
	for ( idx_shape = 0, num_shape = impl_parent->m_vec_shape.size ( ); idx_shape < num_shape; idx_shape++ )
	{
		shape = impl_parent->m_vec_shape[ idx_shape ];
		shape->m_idx_hole = arr_idx_hole ? arr_idx_hole[ idx_shape ] : XMG_HOLE_NULL;

		// Set tess vertices
		if ( impl->m_tess[ 0 ] || impl->m_tess[ 1 ] )
		{
			for ( idx_tess = 0; idx_tess < 2; idx_tess++ )
			{
				if ( impl->m_tess[ idx_tess ] )
				{
					data[ idx_tess ] = impl->m_data[ idx_tess ][ idx_shape ];
					data[ idx_tess ]->Init ( XMG_TESS_VERTEX );

					gluTessBeginPolygon ( impl->m_tess[ idx_tess ], (GLvoid *) data[ idx_tess ] );
					gluTessBeginContour ( impl->m_tess[ idx_tess ] );	
				}
			}

			for ( idx_vertex = 0, num_vertex = shape->m_num_basic; idx_vertex < num_vertex; idx_vertex++ )
			{
				for ( idx_tess = 0; idx_tess < 2; idx_tess++ )
				{
					if ( idx_tess == 0 )
					{
						if ( impl->m_tess[ idx_tess ] )
						{
							src_vertex = src_arr_vertex[ off_vertex + idx_vertex ];
						}
						else
						{
							continue;
						}
					}
					else if ( idx_tess == 1 )
					{
						if ( impl->m_tess[ idx_tess ] )
						{
							switch ( impl_parent->m_geo_type )
							{
								case XMG_GEO_SOLID :

									src_vertex = src_arr_vertex[ off_vertex + num_vertex + idx_vertex ];

									break;

								case XMG_GEO_BSOLID :

									if ( shape->m_idx_hole )
									{
										src_vertex = src_arr_vertex[ idx_vertex < shape->m_idx_hole ? shape->m_idx_hole - idx_vertex - 1 : num_vertex + shape->m_idx_hole - idx_vertex - 1 ];
									}
									else
									{				
										src_vertex = src_arr_vertex[ num_vertex - idx_vertex - 1 ];
									}

									src_vertex.m_z = 0;

									break;
							}							
						}
						else
						{
							continue;
						}
					}

					data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 0 ] = XMG_X2F ( src_vertex.m_x );
					data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 1 ] = XMG_X2F ( src_vertex.m_y );
					data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 2 ] = XMG_X2F ( src_vertex.m_z );	

					if ( shape->m_idx_hole != 0 && shape->m_idx_hole == idx_vertex )
					{
						gluNextContour ( impl->m_tess[ idx_tess ], GLU_INTERIOR );
					}

					gluTessVertex ( impl->m_tess[ idx_tess ], &data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 ], &data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 ] );
				}				
			}

			idx_facet = 0;
			for ( idx_tess = 0; idx_tess < 2; idx_tess++ )
			{
				if ( impl->m_tess[ idx_tess ] )
				{
					gluTessEndContour ( impl->m_tess[ idx_tess ] );	
					gluTessEndPolygon ( impl->m_tess[ idx_tess ] );	

					// Set contours with original
					facet = shape->m_vec_facet[ idx_facet ];
					facet->ClearContour ( );

					if ( shape->m_idx_hole == XMG_HOLE_NULL )
					{
						XMGAssert ( contour = new XMGContour ( ) );

						contour->m_draw_limit = XMG_LIMIT_LINE;
						contour->m_off_vertex = facet->m_off_vertex;
						contour->m_num_vertex = facet->m_num_vertex;

						facet->m_vec_contour.push_back ( contour );
					}
					else
					{
						XMGAssert ( contour = new XMGContour ( ) );

						contour->m_draw_limit = XMG_LIMIT_LINE;
						contour->m_off_vertex = facet->m_off_vertex;
						contour->m_num_vertex = shape->m_idx_hole;						
						
						facet->m_vec_contour.push_back ( contour );

						XMGAssert ( contour = new XMGContour ( ) );

						contour->m_draw_limit = XMG_LIMIT_LINE;
						contour->m_off_vertex = facet->m_off_vertex + shape->m_idx_hole;
						contour->m_num_vertex = facet->m_num_vertex - shape->m_idx_hole;
						
						facet->m_vec_contour.push_back ( contour );
					}
					
					// Set contours with tessed
					facet->m_off_ext = off_ext;
					for ( idx_vec = 0, num_vec = data[ idx_tess ]->m_vec_num_vertex.size ( ); idx_vec < num_vec; idx_vec++ )
					{
						XMGAssert ( contour = new XMGContour ( ) );
						
						contour->m_draw_limit = XMG_LIMIT_TRI;
						contour->m_disp_mode  = data[ idx_tess ]->m_vec_mode[ idx_vec ];
						contour->m_off_vertex = off_ext;
						contour->m_num_vertex = data[ idx_tess ]->m_vec_num_vertex[ idx_vec ];	

						facet->m_vec_contour.push_back ( contour );
						off_ext += contour->m_num_vertex;
					}
					
					idx_facet++;
					facet->m_num_ext = data[ idx_tess ]->m_vec_vertex.size ( );
					impl_parent->m_ext_vertex += facet->m_num_ext;
				}
			}
		}

		off_vertex += shape->m_num_input;
	}

	XMGRender::SetVertexArray ( src_arr_vertex, XMG_SHAPE_ALL );

	if ( impl->m_tess[ 0 ] || impl->m_tess[ 1 ] )
	{
		off_vertex = 0;
		num_vertex = impl_parent->m_ext_vertex;
		XMGAssert ( arr_vertex = (XMGVector3X *) kdMalloc ( sizeof ( XMGVector3X ) * num_vertex ) );

		for ( idx_shape = 0, num_shape = impl_parent->m_vec_shape.size ( ); idx_shape < num_shape; idx_shape++ )
		{
			for ( idx_tess = 0; idx_tess < 2; idx_tess++ )
			{
				if ( impl->m_tess[ idx_tess ] )
				{
					data[ idx_tess ] = impl->m_data[ idx_tess ][ idx_shape ];
					for ( idx_vertex = 0, num_vertex = data[ idx_tess ]->m_vec_vertex.size ( ); idx_vertex < num_vertex; idx_vertex++ )
					{
						arr_vertex[ off_vertex ] = data[ idx_tess ]->m_vec_vertex[ idx_vertex ];
						off_vertex++;
					}
					data[ idx_tess ]->ClearVector ( );
				}
			}
		}

		impl_parent->SetBuffer ( impl_parent->m_id_vertex, arr_vertex, sizeof ( XMGVector3X ) * impl_parent->m_num_vertex, sizeof ( XMGVector3X ) * impl_parent->m_ext_vertex );
		kdFree ( arr_vertex );
	}
}
Ejemplo n.º 19
0
void init (void) 
{
   GLUtesselator *tobj;
   GLdouble rect[4][3] = {50.0, 50.0, 0.0,
                          200.0, 50.0, 0.0,
                          200.0, 200.0, 0.0,
                          50.0, 200.0, 0.0};
   GLdouble tri[3][3] = {75.0, 75.0, 0.0,
                         125.0, 175.0, 0.0,
                         175.0, 75.0, 0.0};
   GLdouble star[5][6] = {250.0, 50.0, 0.0, 1.0, 0.0, 1.0,
                          325.0, 200.0, 0.0, 1.0, 1.0, 0.0,
                          400.0, 50.0, 0.0, 0.0, 1.0, 1.0,
                          250.0, 150.0, 0.0, 1.0, 0.0, 0.0,
                          400.0, 150.0, 0.0, 0.0, 1.0, 0.0};

   glClearColor(0.0, 0.0, 0.0, 0.0);

   startList = glGenLists(2);

   tobj = gluNewTess();
   gluTessCallback(tobj, GLU_TESS_VERTEX, 
                   glVertex3dv);
   gluTessCallback(tobj, GLU_TESS_BEGIN, 
                   beginCallback);
   gluTessCallback(tobj, GLU_TESS_END, 
                   endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, 
                   errorCallback);

   /*  rectangle with triangular hole inside  */
   glNewList(startList, GL_COMPILE);
   glShadeModel(GL_FLAT);    
   gluTessBeginPolygon(tobj, NULL);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, rect[0], rect[0]);
         gluTessVertex(tobj, rect[1], rect[1]);
         gluTessVertex(tobj, rect[2], rect[2]);
         gluTessVertex(tobj, rect[3], rect[3]);
      gluTessEndContour(tobj);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, tri[0], tri[0]);
         gluTessVertex(tobj, tri[1], tri[1]);
         gluTessVertex(tobj, tri[2], tri[2]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);
   glEndList();

   gluTessCallback(tobj, GLU_TESS_VERTEX, 
                   vertexCallback);
   gluTessCallback(tobj, GLU_TESS_BEGIN, 
                   beginCallback);
   gluTessCallback(tobj, GLU_TESS_END, 
                   endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, 
                   errorCallback);
   gluTessCallback(tobj, GLU_TESS_COMBINE, 
                   combineCallback);

   /*  smooth shaded, self-intersecting star  */
   glNewList(startList + 1, GL_COMPILE);
   glShadeModel(GL_SMOOTH);    
   gluTessProperty(tobj, GLU_TESS_WINDING_RULE,
                   GLU_TESS_WINDING_POSITIVE);
   gluTessBeginPolygon(tobj, NULL);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, star[0], star[0]);
         gluTessVertex(tobj, star[1], star[1]);
         gluTessVertex(tobj, star[2], star[2]);
         gluTessVertex(tobj, star[3], star[3]);
         gluTessVertex(tobj, star[4], star[4]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);
   glEndList();
   gluDeleteTess(tobj);
}
Ejemplo n.º 20
0
  void MapPainterOpenGL::DrawArea(const Projection& projection,
                                  const MapParameter& /*parameter*/,
                                  const MapPainter::AreaData& area)
  {
    if (area.fillStyle->GetFillColor().IsVisible()) {
      glColor4d(area.fillStyle->GetFillColor().GetR(),
                area.fillStyle->GetFillColor().GetG(),
                area.fillStyle->GetFillColor().GetB(),
                area.fillStyle->GetFillColor().GetA());

      gluTessProperty(tesselator,
                      GLU_TESS_BOUNDARY_ONLY,
                      GL_FALSE);

      gluTessBeginPolygon(tesselator,
                          NULL);

      gluTessBeginContour(tesselator);

      for (size_t i=area.transStart; i<=area.transEnd; i++) {

        gluTessVertex(tesselator,
                      (GLdouble*)&coordBuffer->buffer[i],
                      (GLdouble*)&coordBuffer->buffer[i]);
      }

      gluTessEndContour(tesselator);

      if (!area.clippings.empty()) {
        // Clip areas within the area by using CAIRO_FILL_RULE_EVEN_ODD
        for (std::list<PolyData>::const_iterator c=area.clippings.begin();
            c!=area.clippings.end();
            c++) {
          const PolyData& data=*c;

          gluTessBeginContour(tesselator);

          for (size_t i=data.transStart; i<=data.transEnd; i++) {
            gluTessVertex(tesselator,
                          (GLdouble*)&coordBuffer->buffer[i],
                          (GLdouble*)&coordBuffer->buffer[i]);
          }

          gluTessEndContour(tesselator);
        }
      }

      gluTessEndPolygon(tesselator);
    }

    if (area.fillStyle->GetBorderWidth()>0 &&
        area.fillStyle->GetBorderColor().IsVisible()) {
      double borderWidth=projection.ConvertWidthToPixel(area.fillStyle->GetBorderWidth());

      glColor4d(area.fillStyle->GetBorderColor().GetR(),
                area.fillStyle->GetBorderColor().GetG(),
                area.fillStyle->GetBorderColor().GetB(),
                area.fillStyle->GetBorderColor().GetA());

      glLineWidth(borderWidth);

      glBegin(GL_LINE_LOOP);

      for (size_t i=area.transStart; i<=area.transEnd; i++) {
        glVertex3d(coordBuffer->buffer[i].GetX(),
                   coordBuffer->buffer[i].GetY(),
                   0.0);
      }

      glEnd();
    }
  }
Ejemplo n.º 21
0
int PolyTessGeo::BuildTessGL(void)
{
#ifdef ocpnUSE_GL
    
      int iir, ip;
      int *cntr;
      GLdouble *geoPt;

      wxString    sout;
      wxString    sout1;
      wxString    stemp;


#ifdef __WXMSW__
//  If using the OpenGL dlls provided with Windows,
//  load the dll and establish addresses of the entry points needed

#ifdef USE_GLU_DLL

      if(!s_glu_dll_ready)
      {


            s_hGLU_DLL = LoadLibrary("glu32.dll");
            if (s_hGLU_DLL != NULL)
            {
                  s_lpfnTessProperty = (LPFNDLLTESSPROPERTY)GetProcAddress(s_hGLU_DLL,"gluTessProperty");
                  s_lpfnNewTess = (LPFNDLLNEWTESS)GetProcAddress(s_hGLU_DLL, "gluNewTess");
                  s_lpfnTessBeginContour = (LPFNDLLTESSBEGINCONTOUR)GetProcAddress(s_hGLU_DLL, "gluTessBeginContour");
                  s_lpfnTessEndContour = (LPFNDLLTESSENDCONTOUR)GetProcAddress(s_hGLU_DLL, "gluTessEndContour");
                  s_lpfnTessBeginPolygon = (LPFNDLLTESSBEGINPOLYGON)GetProcAddress(s_hGLU_DLL, "gluTessBeginPolygon");
                  s_lpfnTessEndPolygon = (LPFNDLLTESSENDPOLYGON)GetProcAddress(s_hGLU_DLL, "gluTessEndPolygon");
                  s_lpfnDeleteTess = (LPFNDLLDELETETESS)GetProcAddress(s_hGLU_DLL, "gluDeleteTess");
                  s_lpfnTessVertex = (LPFNDLLTESSVERTEX)GetProcAddress(s_hGLU_DLL, "gluTessVertex");
                  s_lpfnTessCallback = (LPFNDLLTESSCALLBACK)GetProcAddress(s_hGLU_DLL, "gluTessCallback");

                  s_glu_dll_ready = true;
            }
            else
            {
                  return ERROR_NO_DLL;
            }
      }

#endif
#endif


    //  Allocate a work buffer, which will be grown as needed
#define NINIT_BUFFER_LEN 10000
      s_pwork_buf = (GLdouble *)malloc(NINIT_BUFFER_LEN * 2 * sizeof(GLdouble));
      s_buf_len = NINIT_BUFFER_LEN * 2;
      s_buf_idx = 0;

      //    Create an array to hold pointers to allocated vertices created by "combine" callback,
      //    so that they may be deleted after tesselation.
      s_pCombineVertexArray = new wxArrayPtrVoid;

    //  Create tesselator
      GLUtessobj = gluNewTess();

    //  Register the callbacks
      gluTessCallback(GLUtessobj, GLU_TESS_BEGIN,   (GLvoid (__CALL_CONVENTION *) ())&beginCallback);
      gluTessCallback(GLUtessobj, GLU_TESS_BEGIN,   (GLvoid (__CALL_CONVENTION *) ())&beginCallback);
      gluTessCallback(GLUtessobj, GLU_TESS_VERTEX,  (GLvoid (__CALL_CONVENTION *) ())&vertexCallback);
      gluTessCallback(GLUtessobj, GLU_TESS_END,     (GLvoid (__CALL_CONVENTION *) ())&endCallback);
      gluTessCallback(GLUtessobj, GLU_TESS_COMBINE, (GLvoid (__CALL_CONVENTION *) ())&combineCallback);

//    gluTessCallback(GLUtessobj, GLU_TESS_ERROR,   (GLvoid (__CALL_CONVENTION *) ())&errorCallback);

//    glShadeModel(GL_SMOOTH);
      gluTessProperty(GLUtessobj, GLU_TESS_WINDING_RULE,
                      GLU_TESS_WINDING_POSITIVE );

    //  gluTess algorithm internally selects vertically oriented triangle strips and fans.
    //  This orientation is not optimal for conventional memory-mapped raster display shape filling.
    //  We can "fool" the algorithm by interchanging the x and y vertex values passed to gluTessVertex
    //  and then reverting x and y on the resulting vertexCallbacks.
    //  In this implementation, we will explicitely set the preferred orientation.

    //Set the preferred orientation
      tess_orient = TESS_HORZ;                    // prefer horizontal tristrips



//      Get total number of contours
      m_ncnt  = m_pxgeom->n_contours;

//      Allocate cntr array
      cntr = (int *)malloc(m_ncnt * sizeof(int));

//      Get total number of points(vertices)
      int npta  = m_pxgeom->contour_array[0];
      cntr[0] = npta;
      npta += 2;                            // fluff

      for( iir=0 ; iir < m_ncnt-1 ; iir++)
      {
            int nptr = m_pxgeom->contour_array[iir+1];
            cntr[iir+1] = nptr;

            npta += nptr + 2;             // fluff
      }



//      printf("xgeom npta: %d\n", npta);
      geoPt = (GLdouble *)malloc((npta) * 3 * sizeof(GLdouble));     // vertex array



   //  Grow the work buffer if necessary

      if((npta * 4) > s_buf_len)
      {
            s_pwork_buf = (GLdouble *)realloc(s_pwork_buf, npta * 4 * sizeof(GLdouble));
            s_buf_len = npta * 4;
      }


//  Define the polygon
      gluTessBeginPolygon(GLUtessobj, NULL);


//      Create input structures

//    Exterior Ring
      int npte = m_pxgeom->contour_array[0];
      cntr[0] = npte;

      GLdouble *ppt = geoPt;


//  Check and account for winding direction of ring
      bool cw = true;

      double x0, y0, x, y;
      OGRPoint p;

      wxPoint2DDouble *pp = m_pxgeom->vertex_array;
      pp++;       // skip 0?

      if(cw)
      {
//            poly->getExteriorRing()->getPoint(0, &p);
            x0 = pp->m_x;
            y0 = pp->m_y;
      }
      else
      {
//            poly->getExteriorRing()->getPoint(npte-1, &p);
            x0 = pp[npte-1].m_x;
            y0 = pp[npte-1].m_y;
//            x0 = p.getX();
//            y0 = p.getY();
      }

//      pp++;

      gluTessBeginContour(GLUtessobj);

//  Transcribe points to vertex array, in proper order with no duplicates
//   also, accounting for tess_orient
      for(ip = 0 ; ip < npte ; ip++)
      {
            int pidx;
            if(cw)
                  pidx = npte - ip - 1;

            else
                  pidx = ip;

//            poly->getExteriorRing()->getPoint(pidx, &p);
            x = pp[pidx].m_x;
            y = pp[pidx].m_y;

//            pp++;

            if((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS))
            {
                  GLdouble *ppt_temp = ppt;
                  if(tess_orient == TESS_VERT)
                  {
                        *ppt++ = x;
                        *ppt++ = y;
                  }
                  else
                  {
                        *ppt++ = y;
                        *ppt++ = x;
                  }

                  *ppt++ = 0.0;

                  gluTessVertex( GLUtessobj, ppt_temp, ppt_temp ) ;
 //printf("tess from xgeom, external vertex %g %g\n", x, y);

            }
            else
                  cntr[0]--;

            x0 = x;
            y0 = y;
      }

      gluTessEndContour(GLUtessobj);


      int index_offset = npte;
#if 1
//  Now the interior contours
      for(iir=0; iir < m_ncnt-1; iir++)
      {
            gluTessBeginContour(GLUtessobj);

//            int npti = cntr[iir];
            int npti  = m_pxgeom->contour_array[iir+1];

      //  Check and account for winding direction of ring
            bool cw = false; //!(poly->getInteriorRing(iir)->isClockwise() == 0);

            if(!cw)
            {
                  x0 = pp[index_offset].m_x;
                  y0 = pp[index_offset].m_y;
            }
            else
            {
                  x0 = pp[index_offset + npti-1].m_x;
                  y0 = pp[index_offset + npti-1].m_y;
            }

//  Transcribe points to vertex array, in proper order with no duplicates
//   also, accounting for tess_orient
            for(int ip = 0 ; ip < npti ; ip++)
            {
                  OGRPoint p;
                  int pidx;
                  if(!cw)                               // interior contours must be cw
                        pidx = npti - ip - 1;
                  else
                        pidx = ip;


                  x = pp[pidx + index_offset].m_x;
                  y = pp[pidx + index_offset].m_y;

                  if((fabs(x-x0) > EQUAL_EPS) || (fabs(y-y0) > EQUAL_EPS))
                  {
                        GLdouble *ppt_temp = ppt;
                        if(tess_orient == TESS_VERT)
                        {
                              *ppt++ = x;
                              *ppt++ = y;
                        }
                        else
                        {
                              *ppt++ = y;
                              *ppt++ = x;
                        }
                        *ppt++ = 0.0;

                        gluTessVertex( GLUtessobj, ppt_temp, ppt_temp ) ;
//      printf("tess from xgeom, internal vertex %d %g %g\n", ip, x, y);

                  }
                  else
                        cntr[iir+1]--;

                  x0 = x;
                  y0 = y;

            }

            gluTessEndContour(GLUtessobj);

            index_offset += npti;
      }
#endif

    //  Store some SM conversion data in static store,
    //  for callback access
      s_bSENC_SM =  false;

      s_bmerc_transform = true;
      s_transform_x_rate   =  m_pxgeom->x_rate;
      s_transform_x_origin =  m_pxgeom->x_offset;
      s_transform_y_rate   =  m_pxgeom->y_rate;
      s_transform_y_origin =  m_pxgeom->y_offset;


    //      Ready to kick off the tesselator

      s_pTPG_Last = NULL;
      s_pTPG_Head = NULL;

      s_nvmax = 0;

      gluTessEndPolygon(GLUtessobj);          // here it goes

      m_nvertex_max = s_nvmax;               // record largest vertex count, updates in callback


    //  Tesselation all done, so...

    //  Create the data structures

      m_ppg_head = new PolyTriGroup;
      m_ppg_head->m_bSMSENC = s_bSENC_SM;

      m_ppg_head->nContours = m_ncnt;
      m_ppg_head->pn_vertex = cntr;             // pointer to array of poly vertex counts
      m_ppg_head->data_type = DATA_TYPE_DOUBLE;
      

//  Transcribe the raw geometry buffer
//  Converting to float as we go, and
//  allowing for tess_orient
//  Also, convert to SM if requested

      int nptfinal = npta;
      
      //  No longer need the full geometry in the SENC,
      nptfinal = 1;
      
      m_nwkb = (nptfinal +1) * 2 * sizeof(float);
      m_ppg_head->pgroup_geom = (float *)malloc(m_nwkb);
      float *vro = m_ppg_head->pgroup_geom;
      ppt = geoPt;
      float tx,ty;

      for(ip = 0 ; ip < nptfinal ; ip++)
      {
            if(TESS_HORZ == tess_orient)
            {
                  ty = *ppt++;
                  tx = *ppt++;
            }
            else
            {
                  tx = *ppt++;
                  ty = *ppt++;
            }

            if(0/*bSENC_SM*/)
            {
            //  Calculate SM from chart common reference point
                  double easting, northing;
//                  toSM(ty, tx, ref_lat, ref_lon, &easting, &northing);
                  *vro++ = easting;              // x
                  *vro++ = northing;             // y
            }
            else
            {
                  *vro++ = tx;                  // lon
                  *vro++ = ty;                  // lat
            }

            ppt++;                      // skip z
      }

      m_ppg_head->tri_prim_head = s_pTPG_Head;         // head of linked list of TriPrims

      //  Convert the Triangle vertex arrays into a single memory allocation of floats
      //  to reduce SENC size and enable efficient access later
      
      //  First calculate the total byte size
      int total_byte_size = 2 * sizeof(float);
      TriPrim *p_tp = m_ppg_head->tri_prim_head;
      while( p_tp ) {
          total_byte_size += p_tp->nVert * 2 * sizeof(float);
          p_tp = p_tp->p_next; // pick up the next in chain
      }
      
      float *vbuf = (float *)malloc(total_byte_size);
      p_tp = m_ppg_head->tri_prim_head;
      float *p_run = vbuf;
      while( p_tp ) {
          float *pfbuf = p_run;
          GLdouble *pdouble_buf = (GLdouble *)p_tp->p_vertex;
          
          for( int i=0 ; i < p_tp->nVert * 2 ; ++i){
              float x = (float)( *((GLdouble *)pdouble_buf) );
              *p_run++ = x;
              pdouble_buf++;
          }
          
          free(p_tp->p_vertex);
          p_tp->p_vertex = (double *)pfbuf;
          p_tp = p_tp->p_next; // pick up the next in chain
      }
      m_ppg_head->bsingle_alloc = true;
      m_ppg_head->single_buffer = (unsigned char *)vbuf;
      m_ppg_head->single_buffer_size = total_byte_size;
      m_ppg_head->data_type = DATA_TYPE_FLOAT;
      
      gluDeleteTess(GLUtessobj);

      free( s_pwork_buf );
      s_pwork_buf = NULL;

      free (geoPt);

      //    All allocated buffers are owned now by the m_ppg_head
      //    And will be freed on dtor of this object
      delete m_pxgeom;

      //      Free up any "Combine" vertices created
      for(unsigned int i = 0; i < s_pCombineVertexArray->GetCount() ; i++)
            free (s_pCombineVertexArray->Item(i));
      delete s_pCombineVertexArray;


      m_pxgeom = NULL;

      m_bOK = true;

#endif          //#ifdef ocpnUSE_GL
      
      return 0;
}
Ejemplo n.º 22
0
void REGALGLU_CALL
gluBeginPolygon( GLUtesselator *tess )
{
  gluTessBeginPolygon( tess, NULL );
  gluTessBeginContour( tess );
}
Ejemplo n.º 23
0
void GLAPIENTRY
gluBeginPolygon( GLUtesselator *tess )
{
  gluTessBeginPolygon( tess, NULL );
  gluTessBeginContour( tess );
}
Ejemplo n.º 24
0
void tesselateComplexPolygon(Array<Vector3>& input, Array<Triangle>& output) {
    // Use the GLU triangulator to do the hard work.

    static GLUtriangulatorObj* tobj = NULL;

    if (tobj == NULL) {
        tobj = gluNewTess();
#if defined(G3D_OSX) 
        #define CAST(x) reinterpret_cast<void (*)(...)>(x)
#elif defined(G3D_LINUX)
        #define CAST(x) reinterpret_cast<void (*)()>(x)
#else
        #define CAST(x) reinterpret_cast<void (__stdcall *)(void)>(x) 
#endif
	gluTessCallback(tobj, GLU_TESS_BEGIN_DATA,    CAST(_tesselateBegin));
        gluTessCallback(tobj, GLU_TESS_VERTEX_DATA,   CAST(_tesselateVertex));
        gluTessCallback(tobj, GLU_TESS_END_DATA,      CAST(_tesselateEnd));
        gluTessCallback(tobj, GLU_TESS_COMBINE_DATA,  CAST(_tesselateCombine));
        gluTessCallback(tobj, GLU_TESS_ERROR,         CAST(_tesselateError));
        gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
        gluTessProperty(tobj, GLU_TESS_WINDING_RULE,  GLU_TESS_WINDING_ODD);
        #undef CAST
    }

    double v[3];
    int i;
    TessData data;

    gluTessBeginPolygon(tobj, &data);
        gluTessBeginContour(tobj);
            for (i = 0; i < input.size(); ++i) {
                // Expand the input to double precision
                v[0] = input[i].x;
                v[1] = input[i].y;
                v[2] = input[i].z;
                gluTessVertex(tobj, v, &(input[i]));
            }
        gluTessEndContour(tobj);
    gluTessEndPolygon(tobj);


    for (int p = 0; p < data.primitive.size(); ++p) {
        const TessData::Primitive& primitive = data.primitive[p];

        // Turn the tesselated primitive into triangles
        switch (primitive.primitiveType) {
        case GL_TRIANGLES:
            // This is easy, just walk through them in order.
            for (i = 0; i < primitive.vertex.size(); i += 3) {
                output.append(Triangle(primitive.vertex[i], primitive.vertex[i + 1], primitive.vertex[i + 2]));
            }
            break;

        case GL_TRIANGLE_FAN:
            {
                // Make a triangle between every pair of vertices and the 1st vertex
                for (i = 1; i < primitive.vertex.size() - 1; ++i) {
                    output.append(Triangle(primitive.vertex[0], primitive.vertex[i], primitive.vertex[i + 1]));
                }
            }
            break;

        case GL_TRIANGLE_STRIP:
            for (i = 0; i < primitive.vertex.size() - 3; i += 2) {
                output.append(Triangle(primitive.vertex[i], primitive.vertex[i + 1], primitive.vertex[i + 2]));
                output.append(Triangle(primitive.vertex[i + 2], primitive.vertex[i + 1], primitive.vertex[i + 3]));
            }
            if (i < primitive.vertex.size() - 2) {
                output.append(Triangle(primitive.vertex[i], primitive.vertex[i + 1], primitive.vertex[i + 2]));
            }
            break;

        default:
            //debugAssertM(false, GLenumToString(primitive.primitiveType));
            // Ignore other primitives
            ;
        }
    }
}
Ejemplo n.º 25
0
static void
_cogl_path_build_fill_attribute_buffer (CoglPath *path)
{
  CoglPathTesselator tess;
  unsigned int path_start = 0;
  CoglPathData *data = path->data;
  int i;

  /* If we've already got a vbo then we don't need to do anything */
  if (data->fill_attribute_buffer)
    return;

  tess.primitive_type = FALSE;

  /* Generate a vertex for each point on the path */
  tess.vertices = g_array_new (FALSE, FALSE, sizeof (CoglPathTesselatorVertex));
  g_array_set_size (tess.vertices, data->path_nodes->len);
  for (i = 0; i < data->path_nodes->len; i++)
    {
      CoglPathNode *node =
        &g_array_index (data->path_nodes, CoglPathNode, i);
      CoglPathTesselatorVertex *vertex =
        &g_array_index (tess.vertices, CoglPathTesselatorVertex, i);

      vertex->x = node->x;
      vertex->y = node->y;

      /* Add texture coordinates so that a texture would be drawn to
         fit the bounding box of the path and then cropped by the
         path */
      if (data->path_nodes_min.x == data->path_nodes_max.x)
        vertex->s = 0.0f;
      else
        vertex->s = ((node->x - data->path_nodes_min.x)
                     / (data->path_nodes_max.x - data->path_nodes_min.x));
      if (data->path_nodes_min.y == data->path_nodes_max.y)
        vertex->t = 0.0f;
      else
        vertex->t = ((node->y - data->path_nodes_min.y)
                     / (data->path_nodes_max.y - data->path_nodes_min.y));
    }

  tess.indices_type =
    _cogl_path_tesselator_get_indices_type_for_size (data->path_nodes->len);
  _cogl_path_tesselator_allocate_indices_array (&tess);

  tess.glu_tess = gluNewTess ();

  if (data->fill_rule == COGL_PATH_FILL_RULE_EVEN_ODD)
    gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE,
                     GLU_TESS_WINDING_ODD);
  else
    gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE,
                     GLU_TESS_WINDING_NONZERO);

  /* All vertices are on the xy-plane */
  gluTessNormal (tess.glu_tess, 0.0, 0.0, 1.0);

  gluTessCallback (tess.glu_tess, GLU_TESS_BEGIN_DATA,
                   _cogl_path_tesselator_begin);
  gluTessCallback (tess.glu_tess, GLU_TESS_VERTEX_DATA,
                   _cogl_path_tesselator_vertex);
  gluTessCallback (tess.glu_tess, GLU_TESS_END_DATA,
                   _cogl_path_tesselator_end);
  gluTessCallback (tess.glu_tess, GLU_TESS_COMBINE_DATA,
                   _cogl_path_tesselator_combine);

  gluTessBeginPolygon (tess.glu_tess, &tess);

  while (path_start < data->path_nodes->len)
    {
      CoglPathNode *node =
        &g_array_index (data->path_nodes, CoglPathNode, path_start);

      gluTessBeginContour (tess.glu_tess);

      for (i = 0; i < node->path_size; i++)
        {
          double vertex[3] = { node[i].x, node[i].y, 0.0 };
          gluTessVertex (tess.glu_tess, vertex,
                         GINT_TO_POINTER (i + path_start));
        }

      gluTessEndContour (tess.glu_tess);

      path_start += node->path_size;
    }

  gluTessEndPolygon (tess.glu_tess);

  gluDeleteTess (tess.glu_tess);

  data->fill_attribute_buffer =
    cogl_attribute_buffer_new (data->context,
                               sizeof (CoglPathTesselatorVertex) *
                               tess.vertices->len,
                               tess.vertices->data);
  g_array_free (tess.vertices, TRUE);

  data->fill_attributes[0] =
    cogl_attribute_new (data->fill_attribute_buffer,
                        "cogl_position_in",
                        sizeof (CoglPathTesselatorVertex),
                        G_STRUCT_OFFSET (CoglPathTesselatorVertex, x),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);
  data->fill_attributes[1] =
    cogl_attribute_new (data->fill_attribute_buffer,
                        "cogl_tex_coord0_in",
                        sizeof (CoglPathTesselatorVertex),
                        G_STRUCT_OFFSET (CoglPathTesselatorVertex, s),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);

  data->fill_vbo_indices = cogl_indices_new (data->context,
                                             tess.indices_type,
                                             tess.indices->data,
                                             tess.indices->len);
  data->fill_vbo_n_indices = tess.indices->len;
  g_array_free (tess.indices, TRUE);
}
Ejemplo n.º 26
0
void FTVectoriser::MakeMesh(FTGL_DOUBLE zNormal, int outsetType, float outsetSize)
{
    if(mesh)
    {
        delete mesh;
    }

    mesh = new FTMesh;

    GLUtesselator* tobj = gluNewTess();

    gluTessCallback(tobj, GLU_TESS_BEGIN_DATA,     (GLUTesselatorFunction)ftglBegin);
    gluTessCallback(tobj, GLU_TESS_VERTEX_DATA,    (GLUTesselatorFunction)ftglVertex);
    gluTessCallback(tobj, GLU_TESS_COMBINE_DATA,   (GLUTesselatorFunction)ftglCombine);
    gluTessCallback(tobj, GLU_TESS_END_DATA,       (GLUTesselatorFunction)ftglEnd);
    gluTessCallback(tobj, GLU_TESS_ERROR_DATA,     (GLUTesselatorFunction)ftglError);

    if(contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill
    {
        gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
    }
    else
    {
        gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
    }


    gluTessProperty(tobj, GLU_TESS_TOLERANCE, 0);
    gluTessNormal(tobj, 0.0f, 0.0f, zNormal);
    gluTessBeginPolygon(tobj, mesh);

        for(size_t c = 0; c < ContourCount(); ++c)
        {
            /* Build the */
            switch(outsetType)
            {
                case 1 : contourList[c]->buildFrontOutset(outsetSize); break;
                case 2 : contourList[c]->buildBackOutset(outsetSize); break;
            }
            const FTContour* contour = contourList[c];


            gluTessBeginContour(tobj);
                for(size_t p = 0; p < contour->PointCount(); ++p)
                {
                    const FTGL_DOUBLE* d;
                    switch(outsetType)
                    {
                        case 1: d = contour->FrontPoint(p); break;
                        case 2: d = contour->BackPoint(p); break;
                        case 0: default: d = contour->Point(p); break;
                    }
                    // XXX: gluTessVertex doesn't modify the data but does not
                    // specify "const" in its prototype, so we cannot cast to
                    // a const type.
                    gluTessVertex(tobj, (GLdouble *)d, (GLvoid *)d);
                }

            gluTessEndContour(tobj);
        }
    gluTessEndPolygon(tobj);

    gluDeleteTess(tobj);
}
Ejemplo n.º 27
0
void init_scene(int width, int height)
{
   GLubyte* tex;

   GLUtesselator* tobj;
   GLfloat rect[4][3]={
                         {50.0f,  50.0f,  0.0f},
                         {200.0f, 50.0f,  0.0f},
                         {200.0f, 200.0f, 0.0f},
                         {50.0f,  200.0f, 0.0f}
                      };
   GLfloat tri[3][3]={
                        {75.0f,  75.0f,  0.0f},
                        {125.0f, 175.0f, 0.0f},
                        {175.0f, 75.0f,  0.0f}
                     };
   GLfloat star[5][6]={
                         {250.0f, 50.0f,  0.0f, 1.0f, 0.0f, 1.0f},
                         {325.0f, 200.0f, 0.0f, 1.0f, 1.0f, 0.0f},
                         {400.0f, 50.0f,  0.0f, 0.0f, 1.0f, 1.0f},
                         {250.0f, 150.0f, 0.0f, 1.0f, 0.0f, 0.0f},
                         {400.0f, 150.0f, 0.0f, 0.0f, 1.0f, 0.0f}
                      };
   GLfloat triangle[9][8]={
                             {450.0f, 50.0f,  0.0f, 1.0f,  0.0f,  0.0f,  0.0f,  0.0f},
                             {525.0f, 200.0f, 0.0f, 1.0f,  1.0f,  1.0f,  0.5f,  1.0f},
                             {600.0f, 50.0f,  0.0f, 0.0f,  0.0f,  1.0f,  1.0f,  0.0f},
                             {500.0f, 50.0f,  0.0f, 0.666f, 0.000f, 0.333f, 0.333f, 0.000f},
                             {550.0f, 150.0f, 0.0f, 0.666f, 0.666f, 1.000f, 0.666f, 0.666f},
                             {500.0f, 150.0f, 0.0f, 1.000f, 0.666f, 0.666f, 0.333f, 0.666f},
                             {550.0f, 50.0f,  0.0f, 0.333f, 0.000f, 0.666f, 0.666f, 0.000f},
                             {575.0f, 100.0f, 0.0f, 0.333f, 0.333f, 1.000f, 0.825f, 0.333f},
                             {475.0f, 100.0f, 0.0f, 1.000f, 0.333f, 0.333f, 0.175f, 0.333f}
                          };

   glViewport(0, 0, (GLsizei)width, (GLsizei)height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0f, (GLfloat)width, 0.0f, (GLfloat)height);

   glClearColor(0.0, 0.0, 0.0, 0.0);

   /* Create new triangulator */
   tobj=gluNewTess();

   /* Set triangulator's callbacks */
   gluTessCallback(tobj, GLU_TESS_VERTEX_DATA, (GLvoid (*)())&vertexCallback);
   gluTessCallback(tobj, GLU_TESS_BEGIN_DATA, (GLvoid (*)())&beginCallback);
   gluTessCallback(tobj, GLU_TESS_END_DATA, (GLvoid (*)())&endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (*)())&errorCallback);

   /* reset object */
   object1.sequences=0;

   /* rectangle with triangular hole inside */
   gluTessBeginPolygon(tobj, (void*)&object1);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, rect[0], rect[0]);
         gluTessVertex(tobj, rect[1], rect[1]);
         gluTessVertex(tobj, rect[2], rect[2]);
         gluTessVertex(tobj, rect[3], rect[3]);
      gluTessEndContour(tobj);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, tri[0], tri[0]);
         gluTessVertex(tobj, tri[1], tri[1]);
         gluTessVertex(tobj, tri[2], tri[2]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);

   /* Set triangulator's callbacks */
   gluTessCallback(tobj, GLU_TESS_VERTEX_DATA, (GLvoid (*)())&vertexColorCallback);
   gluTessCallback(tobj, GLU_TESS_BEGIN_DATA, (GLvoid (*)())&beginCallback);
   gluTessCallback(tobj, GLU_TESS_END_DATA, (GLvoid (*)())&endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (*)())&errorCallback);
   gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid (*)())&combineColorCallback);

   /* reset object */
   object2.sequences=0;

   /*  self-intersecting star  */
   gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
   gluTessBeginPolygon(tobj, (void*)&object2);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, star[0], star[0]);
         gluTessVertex(tobj, star[1], star[1]);
         gluTessVertex(tobj, star[2], star[2]);
         gluTessVertex(tobj, star[3], star[3]);
         gluTessVertex(tobj, star[4], star[4]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);

   /* Set triangulator's callbacks */
   gluTessCallback(tobj, GLU_TESS_VERTEX_DATA, (GLvoid (*)())&vertexTexColorCallback);
   gluTessCallback(tobj, GLU_TESS_BEGIN_DATA, (GLvoid (*)())&beginCallback);
   gluTessCallback(tobj, GLU_TESS_END_DATA, (GLvoid (*)())&endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (*)())&errorCallback);
   gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid (*)())&combineTexColorCallback);

   /* reset object */
   object3.sequences=0;

   /*  self-intersecting star  */
   gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
   gluTessBeginPolygon(tobj, (void*)&object3);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, triangle[0], triangle[0]);
         gluTessVertex(tobj, triangle[1], triangle[1]);
         gluTessVertex(tobj, triangle[2], triangle[2]);
      gluTessEndContour(tobj);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, triangle[3], triangle[3]);
         gluTessVertex(tobj, triangle[4], triangle[4]);
         gluTessVertex(tobj, triangle[5], triangle[5]);
         gluTessVertex(tobj, triangle[6], triangle[6]);
         gluTessVertex(tobj, triangle[7], triangle[7]);
         gluTessVertex(tobj, triangle[8], triangle[8]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);

   /* Destroy triangulator object */
   gluDeleteTess(tobj);

   /* enable filtering */
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

   tex=make_texture(256, 256);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, tex);
   free(tex);
}
Ejemplo n.º 28
0
void init (void) 
{
   int i;
   GLUtesselator *tobj;
   GLdouble rect[4][3] = {50.0, 50.0, 0.0,
                          200.0, 50.0, 0.0,
                          200.0, 200.0, 0.0,
                          50.0, 200.0, 0.0};
   GLdouble tri[3][3] = {75.0, 75.0, 0.0,
                         125.0, 175.0, 0.0,
                         175.0, 75.0, 0.0};
   GLdouble star[5][6] = {250.0, 50.0, 0.0, 1.0, 0.0, 1.0,
                          325.0, 200.0, 0.0, 1.0, 1.0, 0.0,
                          400.0, 50.0, 0.0, 0.0, 1.0, 1.0,
                          250.0, 150.0, 0.0, 1.0, 0.0, 0.0,
                          400.0, 150.0, 0.0, 0.0, 1.0, 0.0};

   glClearColor(0.0, 0.0, 0.0, 0.0);


   startList = glGenLists(2);

   tobj = gluNewTess();
   gluTessCallback(tobj, GLU_TESS_VERTEX, 
                   glVertex3dv);
   gluTessCallback(tobj, GLU_TESS_BEGIN, 
                   beginCallback);
   gluTessCallback(tobj, GLU_TESS_END, 
                   endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, 
                   errorCallback);

   /*  rectangle with triangular hole inside  */
   glNewList(startList, GL_COMPILE);
   glShadeModel(GL_FLAT);    
printf("a");
   gluTessBeginPolygon(tobj, NULL);
printf("b");
      gluTessBeginContour(tobj);
printf("c");
         gluTessVertex(tobj, rect[0], rect[0]);
         gluTessVertex(tobj, rect[1], rect[1]);
         gluTessVertex(tobj, rect[2], rect[2]);
         gluTessVertex(tobj, rect[3], rect[3]);
      gluTessEndContour(tobj);
printf(" d");
      gluTessBeginContour(tobj);
printf("e");
         gluTessVertex(tobj, tri[0], tri[0]);
         gluTessVertex(tobj, tri[1], tri[1]);
         gluTessVertex(tobj, tri[2], tri[2]);
printf("f");
      gluTessEndContour(tobj);
printf("g");
   gluTessEndPolygon(tobj);
printf(" h");
   glEndList();

   gluTessCallback(tobj, GLU_TESS_VERTEX, 
                   vertexCallback);
   gluTessCallback(tobj, GLU_TESS_BEGIN, 
                   beginCallback);
   gluTessCallback(tobj, GLU_TESS_END, 
                   endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR, 
                   errorCallback);
   gluTessCallback(tobj, GLU_TESS_COMBINE, 
                   combineCallback);

   /*  smooth shaded, self-intersecting star  */
   glNewList(startList + 1, GL_COMPILE);
   glShadeModel(GL_SMOOTH);    
   gluTessProperty(tobj, GLU_TESS_WINDING_RULE,
                   GLU_TESS_WINDING_POSITIVE);
   gluTessBeginPolygon(tobj, NULL);
      gluTessBeginContour(tobj);
         gluTessVertex(tobj, star[0], star[0]);
         gluTessVertex(tobj, star[1], star[1]);
         gluTessVertex(tobj, star[2], star[2]);
         gluTessVertex(tobj, star[3], star[3]);
         gluTessVertex(tobj, star[4], star[4]);
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);


	glPushMatrix();
		glTranslatef(-100.0, 200.0, 0.0);
		glBegin(GL_POLYGON);
		for (i=0; i<5; i++) {
			glColor3f(star[i][3], star[i][4], star[i][5]);
			glVertex3f(star[i][0], star[i][1], star[i][2]);
		}
		glEnd();
		glColor3f(1,1,1);
		glBegin(GL_LINE_STRIP);
			glVertex3f(100, 100, 0);
			glVertex3f(100, -100, 0);
			glVertex3f(-100, 0, 0);
			glVertex3f(100, 0, 0);
		glEnd();
	glPopMatrix();


   glEndList();
   gluDeleteTess(tobj);
}
Ejemplo n.º 29
0
void GeneralPolygon::render()
{
	//http://www.flipcode.com/archives/Polygon_Tessellation_In_OpenGL.shtml

	glPushMatrix();
	
	glTranslatef(_position.x, _position.y, 0.0f);
	glRotatef(_rotation,0.0f, 0.0f, 1.0f);
	glScalef(_size.x, _size.y, 1.0f);

	glColor4f( _r, _g, _b, _a);

	switch( _renderMode )
	{
		case RenderMethod::GLU_Tessalation:
		{

			// first time rendering? then create the GLUTesselate object
			if( _gluTesselator == NULL )
			{
				// helper lambda function that creates a vertex for OpenGL
				auto combineTesselate = [&](GLdouble coords[3], GLdouble *data[4], GLfloat weight[4], GLdouble **dataOut ) {GLdouble *vert = _newCombineVertexData(coords[0], coords[1]); *dataOut = vert;};
				auto errorTesselate = [] (GLenum errorCode) { std::cerr<< (char *)gluErrorString(errorCode); };

				_gluTesselator = gluNewTess();

				// defines all the callback to render the polygons
				gluTessCallback(_gluTesselator, GLU_TESS_BEGIN, (void (CALLBACK*)()) glBegin );
				gluTessCallback(_gluTesselator, GLU_TESS_VERTEX, (void (CALLBACK*)()) glVertex3dv );
				gluTessCallback(_gluTesselator, GLU_TESS_END, (void (CALLBACK*)()) glEnd );
				gluTessCallback(_gluTesselator, GLU_TESS_COMBINE, (void (CALLBACK*)()) &combineTesselate );
				gluTessCallback(_gluTesselator, GLU_TESS_ERROR, (void (CALLBACK*)()) &errorTesselate );

				// tells to all polygons that the normal is in +z direction
				gluTessNormal(_gluTesselator, 0.0, 0.0, 1.0);
				gluTessProperty(_gluTesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
				gluTessProperty(_gluTesselator, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
			}	
			
			gluTessBeginPolygon(_gluTesselator, NULL); 
			for(unsigned int i = 0; i < _contours.size(); ++i)
			{
				const Contour& contour = _contours[i];
				gluTessBeginContour(_gluTesselator);

				for(unsigned int j = 0; j < contour.size(); ++j)
				{
					GLdouble *vert = _newCombineVertexData((GLdouble)contour[j].x, (GLdouble)contour[j].y);
					gluTessVertex(_gluTesselator, vert, vert); 
				}
				gluTessEndContour(_gluTesselator); 
			}

			// here at the TessEnd is where GLU makes its magic and tesselate our stuff
			gluTessEndPolygon(_gluTesselator);

			_clearCombineVertexData();
		}
		break;
		
		case RenderMethod::ConvexTessalation:
		{
			list<TPPLPoly>::iterator it = _optimalConvexTesselation.begin();

			while( it != _optimalConvexTesselation.end() )
			{
				glBegin(GL_POLYGON);// render convex polygon only

				TPPLPoly &poly = *it;

				for(unsigned int p=0; p < poly.GetNumPoints() ; ++p)
					glVertex3f(poly[p].x, poly[p].y, 0);

				if( poly.GetNumPoints() > 0 )
					glVertex3f(poly[0].x, poly[0].y, 0);
		
				glEnd();

				++it;
			}
		}
		break;

		default:
			std::cerr<<"GeneralPolygon::render -> Render Method set not valid"<<std::endl;
		break;
	}

	glPopMatrix();
}
//----------------------------------------------------------
ofVboMesh ofTessellator::tessellate( const ofPolyline& polyline, bool bIs2D ){

	mutex.lock();
	
	clear();
	resultMesh = ofVboMesh();
//	resultMesh.clear();
	
	// now get the tesselator object up and ready:
	GLUtesselator * ofShapeTobj = gluNewTess();
	
#if defined( TARGET_OSX)
#ifndef MAC_OS_X_VERSION_10_5
#define OF_NEED_GLU_FIX
#endif
#endif
	
	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	// MAC - XCODE USERS PLEASE NOTE - some machines will not be able to compile the code below
	// if this happens uncomment the "OF_NEED_GLU_FIX" line below and it
	// should compile also please post to the forums with the error message, you OS X version,
	// Xcode verison and the CPU type - PPC or Intel. Thanks!
	// (note: this is known problem based on different version of glu.h, we are working on a fix)
	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	
	//#define OF_NEED_GLU_FIX
	
#ifdef OF_NEED_GLU_FIX
#define OF_GLU_CALLBACK_HACK (void(CALLBACK*)(...))
#else
#define OF_GLU_CALLBACK_HACK (void(CALLBACK*)())
#endif
	gluTessCallback( ofShapeTobj, GLU_TESS_BEGIN, OF_GLU_CALLBACK_HACK &ofTessellator::begin);
	gluTessCallback( ofShapeTobj, GLU_TESS_VERTEX, OF_GLU_CALLBACK_HACK &ofTessellator::vertex);
	gluTessCallback( ofShapeTobj, GLU_TESS_COMBINE, OF_GLU_CALLBACK_HACK &ofTessellator::combine);
	gluTessCallback( ofShapeTobj, GLU_TESS_END, OF_GLU_CALLBACK_HACK &ofTessellator::end);
	gluTessCallback( ofShapeTobj, GLU_TESS_ERROR, OF_GLU_CALLBACK_HACK &ofTessellator::error);
	
	gluTessProperty( ofShapeTobj, GLU_TESS_WINDING_RULE, ofGetStyle().polyMode);
	if (!ofGetStyle().bFill){
		gluTessProperty( ofShapeTobj, GLU_TESS_BOUNDARY_ONLY, true);
	} else {
		gluTessProperty( ofShapeTobj, GLU_TESS_BOUNDARY_ONLY, false);
	}
	gluTessProperty( ofShapeTobj, GLU_TESS_TOLERANCE, 0);
	
	/* ------------------------------------------
	 for 2d, this next call (normal) likely helps speed up ....
	 quote : The computation of the normal represents about 10% of
	 the computation time. For example, if all polygons lie in
	 the x-y plane, you can provide the normal by using the
	 -------------------------------------------  */
	if( bIs2D) 
		gluTessNormal(ofShapeTobj, 0.0, 0.0, 1.0);

	gluTessBeginPolygon( ofShapeTobj, NULL);
	
	for ( int i=0; i<polyline.size(); i++ ) {
		double* point = new double[3];
		point[0] = polyline[i].x;
		point[1] = polyline[i].y;
		point[2] = polyline[i].z;
		ofShapePolyVertexs.push_back(point);
	}

	gluTessBeginContour( ofShapeTobj );
	
	for (int i=0; i<(int)ofShapePolyVertexs.size(); i++) {
		gluTessVertex( ofShapeTobj, ofShapePolyVertexs[i], ofShapePolyVertexs[i]);
	}
	
	gluTessEndContour( ofShapeTobj );

	
	
	// no matter what we did / do, we need to delete the tesselator object
	gluTessEndPolygon( ofShapeTobj);
	gluDeleteTess( ofShapeTobj);
	ofShapeTobj = NULL;
	
   	// now clear the vertices on the dynamically allocated data
   	clear();

	mutex.unlock();
	
	return resultMesh;
	
}