polytess.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include "polytess.h"
  11. #include <stddef.h>
  12. #include <util/alloc.h>
  13. #include <xdot/xdot.h>
  14. tessPoly TP;
  15. #ifndef _WIN32
  16. #define CALLBACK
  17. #endif
  18. static void CALLBACK combineCallback(double coords[3],
  19. double *vertex_data[4],
  20. float weight[4],
  21. double **dataOut) {
  22. (void)vertex_data;
  23. (void)weight;
  24. int i;
  25. double *vertex = gv_calloc(6, sizeof(double));
  26. vertex[0] = coords[0];
  27. vertex[1] = coords[1];
  28. vertex[2] = coords[2];
  29. for (i = 3; i < 6; i++)
  30. {
  31. vertex[i] = 0;
  32. }
  33. *dataOut = vertex;
  34. }
  35. static void CALLBACK vertexCallback(void *vertex) {
  36. glVertex3dv(vertex);
  37. }
  38. // OpenGL’s `gluTessCallback` function has a prototype indicating it takes a
  39. // `void(*)(void)`. But its documentation describes passing in various function
  40. // pointers with differing calling conventions. To use this API while also
  41. // pacifying all the various build environments, we need this rather silly
  42. // wrapper.
  43. #ifdef _MSC_VER
  44. // MSVC is of the (correct) opinion that casting between function pointers of
  45. // incompatible calling conventions is unacceptable behavior…
  46. #define MAKE_GLU_CALLBACK(f) f
  47. #else
  48. // …nevertheless other compilers insist we cast or they believe we have made a
  49. // typo
  50. #define MAKE_GLU_CALLBACK(f) ((void (*)(void))(f))
  51. #endif
  52. static GLUtesselator* Init(void)
  53. {
  54. // Create a new tessellation object
  55. GLUtesselator* tobj = gluNewTess();
  56. // Set callback functions
  57. gluTessCallback(tobj, GLU_TESS_VERTEX, MAKE_GLU_CALLBACK(vertexCallback));
  58. gluTessCallback(tobj, GLU_TESS_BEGIN, MAKE_GLU_CALLBACK(glBegin));
  59. gluTessCallback(tobj, GLU_TESS_END, MAKE_GLU_CALLBACK(glEnd));
  60. gluTessCallback(tobj, GLU_TESS_COMBINE, MAKE_GLU_CALLBACK(combineCallback));
  61. return tobj;
  62. }
  63. static void Set_Winding_Rule(GLUtesselator *tobj, GLenum winding_rule)
  64. {
  65. // Set the winding rule
  66. gluTessProperty(tobj, GLU_TESS_WINDING_RULE, winding_rule);
  67. }
  68. static void Render_Contour2(GLUtesselator *tobj, sdot_op* p)
  69. {
  70. double *d = gv_calloc(p->op.u.polygon.cnt * 3, sizeof(double));
  71. for (size_t x = 0; x < p->op.u.polygon.cnt; x++)
  72. {
  73. d[x * 3] = p->op.u.polygon.pts[x].x;
  74. d[x * 3 + 1] = p->op.u.polygon.pts[x].y;
  75. d[x * 3 + 2] = p->op.u.polygon.pts[x].z + view->Topview->global_z;
  76. }
  77. for (size_t x = 0; x < p->op.u.polygon.cnt; x++) //loop through the vertices
  78. {
  79. gluTessVertex(tobj, &d[x * 3], &d[x * 3]); //store the vertex
  80. }
  81. }
  82. static void Begin_Polygon(GLUtesselator *tobj)
  83. {
  84. gluTessBeginPolygon(tobj, NULL);
  85. }
  86. static void End_Polygon(GLUtesselator *tobj)
  87. {
  88. gluTessEndPolygon(tobj);
  89. }
  90. static void Begin_Contour(GLUtesselator *tobj)
  91. {
  92. gluTessBeginContour(tobj);
  93. }
  94. static void End_Contour(GLUtesselator *tobj)
  95. {
  96. gluTessEndContour(tobj);
  97. }
  98. void drawTessPolygon(sdot_op* p)
  99. {
  100. if (!TP.tobj)
  101. {
  102. TP.tobj=Init();
  103. TP.windingRule=GLU_TESS_WINDING_ODD;
  104. }
  105. Set_Winding_Rule(TP.tobj,TP.windingRule);
  106. Begin_Polygon(TP.tobj);
  107. Begin_Contour(TP.tobj);
  108. Render_Contour2(TP.tobj,p);
  109. End_Contour(TP.tobj);
  110. End_Polygon(TP.tobj);
  111. }