glutils.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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 <glcomp/glutils.h>
  11. #include <stdbool.h>
  12. #include <stdint.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <glcomp/glcompdefs.h>
  16. /*transforms 2d windows location to 3d gl coords but depth is calculated unlike the previous function*/
  17. int GetOGLPosRef(int x, int y, float *X, float *Y) {
  18. double wwinX;
  19. double wwinY;
  20. double wwinZ;
  21. double posX, posY, posZ;
  22. int32_t viewport[4];
  23. double modelview[16];
  24. double projection[16];
  25. float winX, winY;
  26. glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
  27. glGetDoublev(GL_PROJECTION_MATRIX, projection);
  28. glGetIntegerv(GL_VIEWPORT, viewport);
  29. //draw a point to a not important location to get window coordinates
  30. glColor4f(0.0f, 0.0f, 0.0f, 0.001f);
  31. glBegin(GL_POINTS);
  32. glVertex3f(-100.0f, -100.0f, 0.0f);
  33. glEnd();
  34. gluProject(-100.0, -100.0, 0.00, modelview, projection, viewport,
  35. &wwinX, &wwinY, &wwinZ);
  36. winX = (float) x;
  37. winY = (float) viewport[3] - (float) y;
  38. gluUnProject(winX, winY, wwinZ, modelview, projection, viewport, &posX,
  39. &posY, &posZ);
  40. *X = (float) posX;
  41. *Y = (float) posY;
  42. (void)posZ; // ignore Z that the caller does not need
  43. return 1;
  44. }
  45. float GetOGLDistance(float l) {
  46. double wwinX;
  47. double wwinY;
  48. double wwinZ;
  49. double posX, posY, posZ;
  50. double posXX, posYY, posZZ;
  51. int32_t viewport[4];
  52. double modelview[16];
  53. double projection[16];
  54. float winX, winY;
  55. glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
  56. glGetDoublev(GL_PROJECTION_MATRIX, projection);
  57. glGetIntegerv(GL_VIEWPORT, viewport);
  58. //draw a point to a not important location to get window coordinates
  59. glColor4f(0.0f, 0.0f, 0.0f, 0.001f);
  60. glBegin(GL_POINTS);
  61. glVertex3f(10.0f, 10.0f, 1.0f);
  62. glEnd();
  63. gluProject(10.0, 10.0, 1.00, modelview, projection, viewport, &wwinX,
  64. &wwinY, &wwinZ);
  65. float x = 50.0f;
  66. const float y = 50.0f;
  67. winX = x;
  68. winY = (float) viewport[3] - y;
  69. gluUnProject(winX, winY, wwinZ, modelview, projection, viewport, &posX,
  70. &posY, &posZ);
  71. x += l;
  72. winX = x;
  73. winY = (float) viewport[3] - y;
  74. gluUnProject(winX, winY, wwinZ, modelview, projection, viewport,
  75. &posXX, &posYY, &posZZ);
  76. return ((float) (posXX - posX));
  77. }
  78. /*
  79. functions def: returns opengl coordinates of firt hit object by using screen coordinates
  80. x,y; 2D screen coordiantes (usually received from mouse events
  81. X,Y,Z; pointers to coordinates values to be calculated
  82. return value: no return value
  83. */
  84. void to3D(int x, int y, float *X, float *Y, float *Z) {
  85. int const WIDTH = 20;
  86. int32_t viewport[4];
  87. double modelview[16];
  88. double projection[16];
  89. float winX, winY;
  90. float winZ[400];
  91. double posX, posY, posZ;
  92. int idx;
  93. glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
  94. glGetDoublev(GL_PROJECTION_MATRIX, projection);
  95. glGetIntegerv(GL_VIEWPORT, viewport);
  96. winX = (float) x;
  97. winY = (float) viewport[3] - (float) y;
  98. glReadPixels(x - WIDTH / 2, (int) winY - WIDTH / 2, WIDTH, WIDTH,
  99. GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
  100. float comp = -9999999;
  101. for (idx = 0; idx < WIDTH * WIDTH; idx++) {
  102. if (winZ[idx] > comp && winZ[idx] < 1)
  103. comp = winZ[idx];
  104. }
  105. gluUnProject(winX, winY, comp, modelview, projection, viewport, &posX,
  106. &posY, &posZ);
  107. *X = (float)posX;
  108. *Y = (float)posY;
  109. *Z = (float)posZ;
  110. return;
  111. }
  112. #include <math.h>
  113. static glCompPoint sub(glCompPoint p, glCompPoint q)
  114. {
  115. p.x -= q.x;
  116. p.y -= q.y;
  117. p.z -= q.z;
  118. return p;
  119. }
  120. static double dot(glCompPoint p, glCompPoint q)
  121. {
  122. return p.x * q.x + p.y * q.y + p.z * q.z;
  123. }
  124. static double len(glCompPoint p)
  125. {
  126. return sqrt(dot(p, p));
  127. }
  128. static glCompPoint blend(glCompPoint p, glCompPoint q, float m)
  129. {
  130. glCompPoint r;
  131. r.x = p.x + m * (q.x - p.x);
  132. r.y = p.y + m * (q.y - p.y);
  133. r.z = p.z + m * (q.z - p.z);
  134. return r;
  135. }
  136. static double dist(glCompPoint p, glCompPoint q)
  137. {
  138. return len(sub(p, q));
  139. }
  140. /*
  141. * Given a line segment determined by two points a and b, and a 3rd point p,
  142. * return the distance between the point and the segment.
  143. * If the perpendicular from p to the line a-b is outside of the segment,
  144. * return the distance to the closer of a or b.
  145. */
  146. double point_to_lineseg_dist(glCompPoint p, glCompPoint a, glCompPoint b)
  147. {
  148. float U;
  149. glCompPoint q;
  150. glCompPoint ba = sub(b, a);
  151. glCompPoint pa = sub(p, a);
  152. U = (float) (dot(pa, ba) / dot(ba, ba));
  153. if (U > 1)
  154. q = b;
  155. else if (U < 0)
  156. q = a;
  157. else
  158. q = blend(a, b, U);
  159. return dist(p, q);
  160. }
  161. void glCompCalcWidget(glCompCommon * parent, glCompCommon * child,
  162. glCompCommon * ref)
  163. {
  164. /*check alignments first , alignments overrides anchors */
  165. float borderWidth;
  166. ref->height = child->height;
  167. ref->width = child->width;
  168. if(!parent)
  169. {
  170. child->refPos.x = child->pos.x;
  171. child->refPos.y = child->pos.y;
  172. return;
  173. }
  174. borderWidth = parent->borderWidth;
  175. if (child->align != glAlignNone) //if alignment, make sure width and height is no greater than parent
  176. {
  177. if (child->width > parent->width)
  178. ref->width = parent->width - 2.0f *borderWidth;
  179. if (child->height > parent->height)
  180. ref->height = parent->height - 2.0f *borderWidth;;
  181. }
  182. ref->pos.x = parent->refPos.x + ref->pos.x + borderWidth;
  183. ref->pos.y = parent->refPos.y + ref->pos.y + borderWidth;
  184. switch (child->align) {
  185. case glAlignLeft:
  186. ref->pos.x = parent->refPos.x + borderWidth;
  187. ref->pos.y = parent->refPos.y + borderWidth;
  188. ref->height = parent->height - 2.0f * borderWidth;
  189. break;
  190. case glAlignRight:
  191. ref->pos.x =
  192. parent->refPos.x + parent->width - child->width - borderWidth;
  193. ref->pos.y = parent->refPos.y + borderWidth;
  194. ref->height = parent->height - 2.0f * borderWidth;
  195. break;
  196. case glAlignTop:
  197. ref->pos.y =
  198. parent->refPos.y + parent->height - child->height -
  199. borderWidth;
  200. ref->pos.x = parent->refPos.x;
  201. ref->width = parent->width - 2.0f * borderWidth;
  202. break;
  203. case glAlignBottom:
  204. ref->pos.y = parent->refPos.y + borderWidth;
  205. ref->pos.x = parent->refPos.x + borderWidth;
  206. ref->width = parent->width - 2.0f * borderWidth;
  207. break;
  208. case glAlignParent:
  209. ref->pos.y = parent->refPos.y + borderWidth;
  210. ref->pos.x = parent->refPos.x + borderWidth;;
  211. ref->width = parent->width - 2.0f * borderWidth;;
  212. ref->height = parent->height - 2.0f * borderWidth;
  213. break;
  214. case glAlignCenter:
  215. case glAlignNone:
  216. break;
  217. }
  218. if (child->align == glAlignNone) // No alignment , chekc anchors
  219. {
  220. ref->pos.x = parent->refPos.x + child->pos.x + borderWidth;
  221. ref->pos.y = parent->refPos.y + child->pos.y + borderWidth;
  222. if (child->anchor.leftAnchor)
  223. ref->pos.x =
  224. parent->refPos.x + child->anchor.left + borderWidth;
  225. if (child->anchor.bottomAnchor)
  226. ref->pos.y =
  227. parent->refPos.y + child->anchor.bottom + borderWidth;
  228. if (child->anchor.topAnchor)
  229. ref->height =
  230. parent->refPos.y + parent->height - ref->pos.y -
  231. child->anchor.top - borderWidth;
  232. if (child->anchor.rightAnchor)
  233. ref->width =
  234. parent->refPos.x + parent->width - ref->pos.x -
  235. child->anchor.right - borderWidth;
  236. }
  237. child->refPos.x = ref->pos.x;
  238. child->refPos.y = ref->pos.y;
  239. child->width = ref->width;
  240. child->height = ref->height;
  241. }
  242. static void glCompQuadVertex(glCompPoint * p0, glCompPoint * p1,
  243. glCompPoint * p2, glCompPoint * p3)
  244. {
  245. glVertex3f(p0->x, p0->y, p0->z);
  246. glVertex3f(p1->x, p1->y, p1->z);
  247. glVertex3f(p2->x, p2->y, p2->z);
  248. glVertex3f(p3->x, p3->y, p3->z);
  249. }
  250. void glCompSetColor(glCompColor c) { glColor4f(c.R, c.G, c.B, c.A); }
  251. void glCompDrawRectangle(glCompRect * r)
  252. {
  253. glBegin(GL_QUADS);
  254. glVertex3f(r->pos.x, r->pos.y, r->pos.z);
  255. glVertex3f(r->pos.x + r->w, r->pos.y, r->pos.z);
  256. glVertex3f(r->pos.x + r->w, r->pos.y + r->h, r->pos.z);
  257. glVertex3f(r->pos.x, r->pos.y + r->h, r->pos.z);
  258. glEnd();
  259. }
  260. void glCompDrawRectPrism(glCompPoint *p, float w, float h, float b, float d,
  261. glCompColor *c, bool bumped) {
  262. float color_fac;
  263. glCompPoint A, B, C, D, E, F, G, H;
  264. float dim = 1;
  265. if (!bumped) {
  266. color_fac = 1.3f;
  267. b = b - 2;
  268. dim = 0.5;
  269. } else
  270. color_fac = 1.0f / 1.3f;
  271. A.x = p->x;
  272. A.y = p->y;
  273. A.z = p->z;
  274. B.x = p->x + w;
  275. B.y = p->y;
  276. B.z = p->z;
  277. C.x = p->x + w;
  278. C.y = p->y + h;
  279. C.z = p->z;
  280. D.x = p->x;
  281. D.y = p->y + h;
  282. D.z = p->z;
  283. G.x = p->x + b;
  284. G.y = p->y + b;
  285. G.z = p->z + d;
  286. H.x = p->x + w - b;
  287. H.y = p->y + b;
  288. H.z = p->z + d;
  289. E.x = p->x + b;
  290. E.y = p->y + h - b;
  291. E.z = p->z + d;
  292. F.x = p->x + w - b;
  293. F.y = p->y + h - b;
  294. F.z = p->z + d;
  295. glBegin(GL_QUADS);
  296. glColor4f(c->R * dim, c->G * dim, c->B * dim, c->A);
  297. glCompQuadVertex(&G, &H, &F, &E);
  298. glColor4f(c->R * color_fac * dim, c->G * color_fac * dim,
  299. c->B * color_fac * dim, c->A);
  300. glCompQuadVertex(&A, &B, &H, &G);
  301. glCompQuadVertex(&B, &H, &F, &C);
  302. glColor4f(c->R / color_fac * dim, c->G / color_fac * dim,
  303. c->B / color_fac * dim, c->A);
  304. glCompQuadVertex(&A, &G, &E, &D);
  305. glCompQuadVertex(&E, &F, &C, &D);
  306. glEnd();
  307. }
  308. float distBetweenPts(glCompPoint A, glCompPoint B, float R) {
  309. float rv = (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) + (A.z - B.z) * (A.z - B.z);
  310. rv=sqrtf(rv);
  311. if (rv <=R)
  312. return 0;
  313. return rv;
  314. }
  315. int is_point_in_rectangle(float X, float Y, float RX, float RY, float RW,float RH)
  316. {
  317. if (X >= RX && X <= RX + RW && Y >= RY && Y <= RY + RH)
  318. return 1;
  319. else
  320. return 0;
  321. }
  322. /**
  323. * @dir lib/glcomp
  324. * @brief OpenGL GUI for cmd/smyrna
  325. */