Beispiel #1
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);

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

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

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

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

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

		glMaterialfv(GL_FRONT, GL_DIFFUSE, sideColor);
		glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
		glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);		
		
			glCallList(side);
		glPopMatrix();
	glEndList();
}
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;
		}
	}
}
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 );
	}
}
Beispiel #5
0
void gluauxNextContour (GLUtriangulatorObj* tessobj, GLenum type)
{
 current(tessobj);
 gluNextContour(tessobj,type);
}
Beispiel #6
0
int
Tesselate (Tcl_Interp *interp, int argc, char* argv [])
{
   int result = TCL_OK;
   int icoord = 0;
   int edgeflags = 1;
   int iarg;
   GLUtriangulatorObj* obj;
   int dlist = -1;
   GLdouble coord [3];
   GLfloat* vtx;
   GLfloat* vtxptr;

   globalinterp = interp;
   globalresult = TCL_OK;

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

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

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

   assert (vtx != NULL);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	std::list<GLdouble *>::iterator beginIt, endIt;
	endIt = Combine_data.end();
	beginIt = Combine_data.begin();
	for (; beginIt != endIt; ++beginIt)
		delete[](*beginIt);
}