123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- #include "polytess.h"
- #include <stddef.h>
- #include <util/alloc.h>
- #include <xdot/xdot.h>
- tessPoly TP;
- #ifndef _WIN32
- #define CALLBACK
- #endif
- static void CALLBACK combineCallback(double coords[3],
- double *vertex_data[4],
- float weight[4],
- double **dataOut) {
- (void)vertex_data;
- (void)weight;
- int i;
- double *vertex = gv_calloc(6, sizeof(double));
- vertex[0] = coords[0];
- vertex[1] = coords[1];
- vertex[2] = coords[2];
- for (i = 3; i < 6; i++)
- {
- vertex[i] = 0;
- }
- *dataOut = vertex;
- }
- static void CALLBACK vertexCallback(void *vertex) {
- glVertex3dv(vertex);
- }
- // OpenGL’s `gluTessCallback` function has a prototype indicating it takes a
- // `void(*)(void)`. But its documentation describes passing in various function
- // pointers with differing calling conventions. To use this API while also
- // pacifying all the various build environments, we need this rather silly
- // wrapper.
- #ifdef _MSC_VER
- // MSVC is of the (correct) opinion that casting between function pointers of
- // incompatible calling conventions is unacceptable behavior…
- #define MAKE_GLU_CALLBACK(f) f
- #else
- // …nevertheless other compilers insist we cast or they believe we have made a
- // typo
- #define MAKE_GLU_CALLBACK(f) ((void (*)(void))(f))
- #endif
- static GLUtesselator* Init(void)
- {
- // Create a new tessellation object
- GLUtesselator* tobj = gluNewTess();
- // Set callback functions
- gluTessCallback(tobj, GLU_TESS_VERTEX, MAKE_GLU_CALLBACK(vertexCallback));
- gluTessCallback(tobj, GLU_TESS_BEGIN, MAKE_GLU_CALLBACK(glBegin));
- gluTessCallback(tobj, GLU_TESS_END, MAKE_GLU_CALLBACK(glEnd));
- gluTessCallback(tobj, GLU_TESS_COMBINE, MAKE_GLU_CALLBACK(combineCallback));
- return tobj;
- }
- static void Set_Winding_Rule(GLUtesselator *tobj, GLenum winding_rule)
- {
- // Set the winding rule
- gluTessProperty(tobj, GLU_TESS_WINDING_RULE, winding_rule);
- }
- static void Render_Contour2(GLUtesselator *tobj, sdot_op* p)
- {
- double *d = gv_calloc(p->op.u.polygon.cnt * 3, sizeof(double));
- for (size_t x = 0; x < p->op.u.polygon.cnt; x++)
- {
- d[x * 3] = p->op.u.polygon.pts[x].x;
- d[x * 3 + 1] = p->op.u.polygon.pts[x].y;
- d[x * 3 + 2] = p->op.u.polygon.pts[x].z + view->Topview->global_z;
- }
- for (size_t x = 0; x < p->op.u.polygon.cnt; x++) //loop through the vertices
- {
- gluTessVertex(tobj, &d[x * 3], &d[x * 3]); //store the vertex
- }
- }
- static void Begin_Polygon(GLUtesselator *tobj)
- {
- gluTessBeginPolygon(tobj, NULL);
- }
- static void End_Polygon(GLUtesselator *tobj)
- {
- gluTessEndPolygon(tobj);
- }
- static void Begin_Contour(GLUtesselator *tobj)
- {
- gluTessBeginContour(tobj);
- }
- static void End_Contour(GLUtesselator *tobj)
- {
- gluTessEndContour(tobj);
- }
- void drawTessPolygon(sdot_op* p)
- {
- if (!TP.tobj)
- {
- TP.tobj=Init();
- TP.windingRule=GLU_TESS_WINDING_ODD;
- }
- Set_Winding_Rule(TP.tobj,TP.windingRule);
- Begin_Polygon(TP.tobj);
- Begin_Contour(TP.tobj);
- Render_Contour2(TP.tobj,p);
- End_Contour(TP.tobj);
- End_Polygon(TP.tobj);
- }
|