Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
8.2 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1989, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /* interface.c */
  13. /* Derrick Burns - 1989 */
  14. #include <glos.h>
  15. #include <GL/gl.h>
  16. #include <GL/glu.h>
  17. #ifndef NT
  18. #include <stdlib.h>
  19. #else
  20. #include "winmem.h"
  21. #include "bufpool.h"
  22. #endif
  23. #include "monotone.h"
  24. static void do_out_finish(GLUtriangulatorObj *);
  25. static void __gluTessEndContour(GLUtriangulatorObj *tobj);
  26. GLUtriangulatorObj * APIENTRY gluNewTess(void)
  27. {
  28. GLUtriangulatorObj *tobj;
  29. tobj = (GLUtriangulatorObj *) malloc(sizeof(GLUtriangulatorObj));
  30. tobj->init = 0;
  31. tobj->minit = 0;
  32. tobj->in_poly = 0;
  33. tobj->doingTriangles = 0;
  34. tobj->tritype = GL_TRIANGLES;
  35. tobj->vpool = 0;
  36. tobj->raypool = 0;
  37. tobj->begin = NULL;
  38. tobj->end = NULL;
  39. tobj->vertex = NULL;
  40. tobj->error = NULL;
  41. tobj->edgeflag = NULL;
  42. tobj->parray = (Vert **)NULL;
  43. tobj->inBegin = GL_FALSE;
  44. tobj->s = 0;
  45. tobj->t = 0;
  46. return tobj;
  47. }
  48. void APIENTRY
  49. gluTessCallback(GLUtriangulatorObj *tobj, GLenum which, void (CALLBACK *fn)())
  50. {
  51. switch(which) {
  52. case GLU_BEGIN:
  53. #ifndef NT
  54. tobj->begin = (void (*)(GLenum)) fn;
  55. #else
  56. tobj->begin = (GLUtessBeginProc) fn;
  57. #endif
  58. break;
  59. case GLU_VERTEX:
  60. #ifndef NT
  61. tobj->vertex = (void (*)(void *)) fn;
  62. #else
  63. tobj->vertex = (GLUtessVertexProc) fn;
  64. #endif
  65. break;
  66. case GLU_END:
  67. #ifndef NT
  68. tobj->end = (void (*)(void)) fn;
  69. #else
  70. tobj->end = (GLUtessEndProc) fn;
  71. #endif
  72. break;
  73. case GLU_ERROR:
  74. #ifndef NT
  75. tobj->error = (void (*)(GLenum)) fn;
  76. #else
  77. tobj->error = (GLUtessErrorProc) fn;
  78. #endif
  79. break;
  80. case GLU_EDGE_FLAG:
  81. #ifndef NT
  82. tobj->edgeflag = (void (*)(GLboolean)) fn;
  83. #else
  84. tobj->edgeflag = (GLUtessEdgeFlagProc) fn;
  85. #endif
  86. break;
  87. default:
  88. /* XXX */
  89. break;
  90. }
  91. }
  92. void APIENTRY
  93. gluDeleteTess(GLUtriangulatorObj *t)
  94. {
  95. #ifdef NT
  96. extern void __gl_free_pool( Pool * );
  97. #endif
  98. __gl_free_priorityq(t);
  99. if (t->raypool) __gl_free_pool(t->raypool);
  100. if (t->vpool) __gl_free_pool(t->vpool);
  101. __gl_clear_triangulate(t);
  102. __gl_clear_sort(t);
  103. free(t);
  104. }
  105. /*---------------------------------------------------------------------------
  106. * gluBeginPolygon - called before each input polygon
  107. *---------------------------------------------------------------------------
  108. */
  109. void APIENTRY
  110. gluBeginPolygon(GLUtriangulatorObj *tobj)
  111. {
  112. if(setjmp(tobj->in_env) != 0)
  113. return;
  114. if (tobj->in_poly++) {
  115. __gl_in_error(tobj, 1);
  116. }
  117. /* 17 arbitrarily */
  118. __gl_init_priorityq(tobj, 17);
  119. __gl_init_verts(tobj);
  120. __gl_init_raylist(tobj);
  121. tobj->nloops = 0;
  122. tobj->maxarea = (float)0.0;
  123. tobj->head = 0;
  124. tobj->looptype = GLU_EXTERIOR;
  125. }
  126. /*---------------------------------------------------------------------------
  127. * gluEndPolygon - called after each input polygon
  128. *---------------------------------------------------------------------------
  129. */
  130. void APIENTRY
  131. gluEndPolygon(GLUtriangulatorObj *tobj)
  132. {
  133. #ifdef NT
  134. extern void __gl_setpriority_priorityq( GLUtriangulatorObj *, int, int);
  135. #endif
  136. if(setjmp(tobj->in_env) != 0)
  137. return;
  138. if (--tobj->in_poly) {
  139. __gl_in_error(tobj, 2);
  140. }
  141. if (tobj->head) {
  142. __gluTessEndContour(tobj);
  143. }
  144. /* Set edge flag to -1 so that if the user wants edge flag info, we
  145. ** specify an edge flag for the first edge regardless (then we only
  146. ** report changes).
  147. */
  148. tobj->currentEdgeFlag = (GLboolean) -1;
  149. __gl_setpriority_priorityq(tobj, tobj->s, tobj->t);
  150. __gl_monotonize(tobj);
  151. do_out_finish(tobj);
  152. __gl_free_verts(tobj);
  153. __gl_free_priorityq(tobj);
  154. __gl_free_raylist(tobj);
  155. }
  156. static void
  157. do_out_finish(GLUtriangulatorObj *tobj)
  158. {
  159. if (tobj->doingTriangles) {
  160. if (tobj->end) {
  161. (*tobj->end)();
  162. tobj->inBegin = GL_FALSE;
  163. }
  164. tobj->doingTriangles = 0;
  165. }
  166. }
  167. /*---------------------------------------------------------------------------
  168. * gluNextContour - called before each input boundary loop
  169. *---------------------------------------------------------------------------
  170. */
  171. void APIENTRY
  172. gluNextContour(GLUtriangulatorObj *tobj, GLenum type)
  173. {
  174. if(setjmp(tobj->in_env) != 0)
  175. return;
  176. if(!tobj->in_poly) {
  177. __gl_in_error(tobj, 2);
  178. }
  179. if (tobj->head) {
  180. __gluTessEndContour(tobj);
  181. }
  182. tobj->head = 0;
  183. tobj->looptype = type;
  184. }
  185. /*---------------------------------------------------------------------------
  186. * gluTessEndContour - called after each input boundary loop
  187. *---------------------------------------------------------------------------
  188. */
  189. static void
  190. __gluTessEndContour(GLUtriangulatorObj *tobj)
  191. {
  192. double xyarea, xzarea, yzarea;
  193. Vert *v;
  194. tobj->nloops++;
  195. xyarea = xzarea = yzarea = 0.0;
  196. v = tobj->head;
  197. do {
  198. xyarea += v->v[0] * v->next->v[1] - v->v[1] * v->next->v[0];
  199. xzarea += v->v[0] * v->next->v[2] - v->v[2] * v->next->v[0];
  200. yzarea += v->v[1] * v->next->v[2] - v->v[2] * v->next->v[1];
  201. v = v->next;
  202. } while(v != tobj->head);
  203. if(xyarea < 0.0) {
  204. if(-xyarea > tobj->maxarea) {
  205. tobj->maxarea = -xyarea; tobj->s = 1; tobj->t = 0;
  206. }
  207. } else {
  208. if(xyarea > tobj->maxarea) {
  209. tobj->maxarea = xyarea; tobj->s = 0; tobj->t = 1;
  210. }
  211. }
  212. if(xzarea < 0.0) {
  213. if(-xzarea > tobj->maxarea) {
  214. tobj->maxarea = -xzarea; tobj->s = 2; tobj->t = 0;
  215. }
  216. } else {
  217. if(xzarea > tobj->maxarea) {
  218. tobj->maxarea = xzarea; tobj->s = 0; tobj->t = 2;
  219. }
  220. }
  221. if(yzarea < 0.0) {
  222. if(-yzarea > tobj->maxarea) {
  223. tobj->maxarea = -yzarea; tobj->s = 2; tobj->t = 1;
  224. }
  225. } else {
  226. if(yzarea > tobj->maxarea) {
  227. tobj->maxarea = yzarea; tobj->s = 1; tobj->t = 2;
  228. }
  229. }
  230. __gl_unclassify_all(tobj->head);
  231. }
  232. /*---------------------------------------------------------------------------
  233. * gluTessVertex - called for each input vertex
  234. *---------------------------------------------------------------------------
  235. */
  236. void APIENTRY
  237. gluTessVertex(GLUtriangulatorObj *tobj, GLdouble v[3], void *data)
  238. {
  239. Vert *vert;
  240. if(setjmp(tobj->in_env) != 0)
  241. return;
  242. if(!tobj->in_poly) {
  243. __gl_in_error(tobj, 2);
  244. }
  245. vert = __gl_new_vert(tobj);
  246. vert->myid = vert;
  247. vert->v[0] = v[0];
  248. vert->v[1] = v[1];
  249. vert->v[2] = v[2];
  250. vert->ray = 0;
  251. vert->data = data;
  252. #ifdef ADDED
  253. vert->added = 0;
  254. #endif
  255. if(tobj->head == 0) {
  256. tobj->head = vert->prev = vert->next = vert;
  257. } else {
  258. vert->prev = tobj->head->prev;
  259. vert->next = tobj->head;
  260. vert->prev->next = vert;
  261. vert->next->prev = vert;
  262. }
  263. __gl_add_priorityq(tobj, vert);
  264. }
  265. /*----------------------------------------------------------------------------
  266. * in_error - data input error, free all storage
  267. *----------------------------------------------------------------------------
  268. */
  269. void
  270. __gl_in_error(GLUtriangulatorObj *tobj, GLenum which)
  271. {
  272. __gl_clear_sort(tobj);
  273. __gl_clear_triangulate(tobj);
  274. __gl_free_raylist(tobj);
  275. __gl_free_verts(tobj);
  276. __gl_free_priorityq(tobj);
  277. __gl_cleanup(tobj);
  278. tobj->in_poly = 0;
  279. if (tobj->error) {
  280. (*tobj->error)(which + (GLU_TESS_ERROR1 - 1));
  281. }
  282. longjmp(tobj->in_env, (int) which);
  283. }