SUMO - Simulation of Urban MObility
GLHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // Some methods which help to draw certain geometrical objects in openGL
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <cassert>
33 #include <utils/geom/GeomHelper.h>
34 #include <utils/common/StdDefs.h>
37 #include <utils/common/ToString.h>
38 #define FONTSTASH_IMPLEMENTATION // Expands implementation
39 #ifdef _MSC_VER
40 #pragma warning(disable: 4505) // do not warn about unused functions
41 #endif
42 #if __GNUC__ > 3
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Wunused-function"
45 #endif
48 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation
50 #include "Roboto.h"
51 #include "GLHelper.h"
52 
53 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
54 
55 // ===========================================================================
56 // static member definitions
57 // ===========================================================================
58 std::vector<std::pair<double, double> > GLHelper::myCircleCoords;
60 double GLHelper::myFontSize = 50.0;
61 
62 void APIENTRY combCallback(GLdouble coords[3],
63  GLdouble* vertex_data[4],
64  GLfloat weight[4], GLdouble** dataOut) {
65  UNUSED_PARAMETER(weight);
66  UNUSED_PARAMETER(*vertex_data);
67  GLdouble* vertex;
68 
69  vertex = (GLdouble*)malloc(7 * sizeof(GLdouble));
70 
71  vertex[0] = coords[0];
72  vertex[1] = coords[1];
73  vertex[2] = coords[2];
74  *dataOut = vertex;
75 }
76 
77 // ===========================================================================
78 // method definitions
79 // ===========================================================================
80 
81 
82 void
84  if (v.size() == 0) {
85  return;
86  }
87  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
88  glBegin(GL_POLYGON);
89  for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
90  const Position& p = *i;
91  glVertex2d(p.x(), p.y());
92  }
93  if (close) {
94  const Position& p = *(v.begin());
95  glVertex2d(p.x(), p.y());
96  }
97  glEnd();
98 }
99 
100 
101 void
103  if (v.size() == 0) {
104  return;
105  }
106  GLUtesselator* tobj = gluNewTess();
107  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
108  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
109  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
110  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combCallback);
111  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
112  gluTessBeginPolygon(tobj, NULL);
113  gluTessBeginContour(tobj);
114  double* points = new double[(v.size() + int(close)) * 3];
115 
116  for (int i = 0; i != (int)v.size(); ++i) {
117  points[3 * i] = v[i].x();
118  points[3 * i + 1] = v[i].y();
119  points[3 * i + 2] = 0;
120  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
121  }
122  if (close) {
123  const int i = (int)v.size();
124  points[3 * i] = v[0].x();
125  points[3 * i + 1] = v[0].y();
126  points[3 * i + 2] = 0;
127  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
128  }
129  gluTessEndContour(tobj);
130  gluTessEndPolygon(tobj);
131  gluDeleteTess(tobj);
132  delete[] points;
133 }
134 
135 
136 void
137 GLHelper::drawBoxLine(const Position& beg, double rot, double visLength,
138  double width, double offset) {
139  glPushMatrix();
140  glTranslated(beg.x(), beg.y(), 0);
141  glRotated(rot, 0, 0, 1);
142  glBegin(GL_QUADS);
143  glVertex2d(-width - offset, 0);
144  glVertex2d(-width - offset, -visLength);
145  glVertex2d(width - offset, -visLength);
146  glVertex2d(width - offset, 0);
147  glEnd();
148  glPopMatrix();
149 }
150 
151 
152 void
153 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
154  double rot, double visLength,
155  double width) {
156  glPushMatrix();
157  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
158  glRotated(rot, 0, 0, 1);
159  glBegin(GL_QUADS);
160  glVertex2d(-width, 0);
161  glVertex2d(-width, -visLength);
162  glVertex2d(width, -visLength);
163  glVertex2d(width, 0);
164  glEnd();
165  glPopMatrix();
166 }
167 
168 
169 bool
170 GLHelper::rightTurn(double angle1, double angle2) {
171  double delta = angle2 - angle1;
172  while (delta > 180) {
173  delta -= 360;
174  }
175  while (delta < -180) {
176  delta += 360;
177  }
178  return delta <= 0;
179 }
180 
181 
182 void
184  const std::vector<double>& rots,
185  const std::vector<double>& lengths,
186  double width, int cornerDetail, double offset) {
187  // draw the lane
188  int e = (int) geom.size() - 1;
189  for (int i = 0; i < e; i++) {
190  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
191  }
192  // draw the corner details
193  if (cornerDetail > 0) {
194  for (int i = 1; i < e; i++) {
195  glPushMatrix();
196  glTranslated(geom[i].x(), geom[i].y(), 0.1);
197  if (rightTurn(rots[i - 1], rots[i])) {
198  // inside corner
199  drawFilledCircle(MIN2(lengths[i], width - offset), cornerDetail);
200  } else {
201  // outside corner, make sure to only draw a segment of the circle
202  double angleBeg = -rots[i - 1];
203  double angleEnd = 180 - rots[i];
204  // avoid drawing more than 360 degrees
205  if (angleEnd - angleBeg > 360) {
206  angleBeg += 360;
207  }
208  if (angleEnd - angleBeg < -360) {
209  angleEnd += 360;
210  }
211  // for a left tur, draw the right way around
212  if (angleEnd > angleBeg) {
213  angleEnd -= 360;
214  }
215  drawFilledCircle(MIN2(lengths[i], width + offset), cornerDetail, angleBeg, angleEnd);
216  }
217  glEnd();
218  glPopMatrix();
219  }
220  }
221 }
222 
223 
224 void
226  const std::vector<double>& rots,
227  const std::vector<double>& lengths,
228  const std::vector<RGBColor>& cols,
229  double width, int cornerDetail, double offset) {
230  int e = (int) geom.size() - 1;
231  for (int i = 0; i < e; i++) {
232  setColor(cols[i]);
233  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
234  }
235  if (cornerDetail > 0) {
236  for (int i = 1; i < e; i++) {
237  glPushMatrix();
238  setColor(cols[i]);
239  glTranslated(geom[i].x(), geom[i].y(), 0);
240  drawFilledCircle(width, cornerDetail);
241  glEnd();
242  glPopMatrix();
243  }
244  }
245 }
246 
247 
248 void
250  const PositionVector& geom2,
251  const std::vector<double>& rots,
252  const std::vector<double>& lengths,
253  double width) {
254  int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
255  for (int i = 0; i < minS; i++) {
256  GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
257  }
258 }
259 
260 
261 void
262 GLHelper::drawBoxLines(const PositionVector& geom, double width) {
263  int e = (int) geom.size() - 1;
264  for (int i = 0; i < e; i++) {
265  const Position& f = geom[i];
266  const Position& s = geom[i + 1];
267  drawBoxLine(f,
268  RAD2DEG(atan2((s.x() - f.x()), (f.y() - s.y()))),
269  f.distanceTo(s),
270  width);
271  }
272 }
273 
274 
275 void
276 GLHelper::drawLine(const Position& beg, double rot, double visLength) {
277  glPushMatrix();
278  glTranslated(beg.x(), beg.y(), 0);
279  glRotated(rot, 0, 0, 1);
280  glBegin(GL_LINES);
281  glVertex2d(0, 0);
282  glVertex2d(0, -visLength);
283  glEnd();
284  glPopMatrix();
285 }
286 
287 
288 void
289 GLHelper::drawLine(const Position& beg1, const Position& beg2,
290  double rot, double visLength) {
291  glPushMatrix();
292  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
293  glRotated(rot, 0, 0, 1);
294  glBegin(GL_LINES);
295  glVertex2d(0, 0);
296  glVertex2d(0, -visLength);
297  glEnd();
298  glPopMatrix();
299 }
300 
301 
302 
303 void
305  glBegin(GL_LINES);
306  int e = (int) v.size() - 1;
307  for (int i = 0; i < e; ++i) {
308  glVertex2d(v[i].x(), v[i].y());
309  glVertex2d(v[i + 1].x(), v[i + 1].y());
310  }
311  glEnd();
312 }
313 
314 
315 void
316 GLHelper::drawLine(const PositionVector& v, const std::vector<RGBColor>& cols) {
317  glBegin(GL_LINES);
318  int e = (int) v.size() - 1;
319  for (int i = 0; i < e; ++i) {
320  setColor(cols[i]);
321  glVertex2d(v[i].x(), v[i].y());
322  glVertex2d(v[i + 1].x(), v[i + 1].y());
323  }
324  glEnd();
325 }
326 
327 
328 void
329 GLHelper::drawLine(const Position& beg, const Position& end) {
330  glBegin(GL_LINES);
331  glVertex2d(beg.x(), beg.y());
332  glVertex2d(end.x(), end.y());
333  glEnd();
334 }
335 
336 
337 int
338 GLHelper::angleLookup(double angleDeg) {
339  const int numCoords = (int)myCircleCoords.size() - 1;
340  int index = ((int)(floor(angleDeg * CIRCLE_RESOLUTION + 0.5))) % numCoords;
341  if (index < 0) {
342  index += numCoords;
343  }
344  assert(index >= 0);
345  return (int)index;
346 }
347 
348 
349 void
350 GLHelper::drawFilledCircle(double width, int steps) {
351  drawFilledCircle(width, steps, 0, 360);
352 }
353 
354 
355 void
356 GLHelper::drawFilledCircle(double width, int steps, double beg, double end) {
357  if (myCircleCoords.size() == 0) {
358  for (int i = 0; i <= (int)(360 * CIRCLE_RESOLUTION); ++i) {
359  const double x = (double) sin(DEG2RAD(i / CIRCLE_RESOLUTION));
360  const double y = (double) cos(DEG2RAD(i / CIRCLE_RESOLUTION));
361  myCircleCoords.push_back(std::pair<double, double>(x, y));
362  }
363  }
364  const double inc = (end - beg) / (double)steps;
365  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
366  std::pair<double, double> p1 = myCircleCoords[angleLookup(beg)];
367 
368  for (int i = 0; i <= steps; ++i) {
369  const std::pair<double, double>& p2 = myCircleCoords[angleLookup(beg + i * inc)];
370  glBegin(GL_TRIANGLES);
371  glVertex2d(p1.first * width, p1.second * width);
372  glVertex2d(p2.first * width, p2.second * width);
373  glVertex2d(0, 0);
374  glEnd();
375  p1 = p2;
376  }
377 }
378 
379 
380 void
381 GLHelper::drawOutlineCircle(double width, double iwidth, int steps) {
382  drawOutlineCircle(width, iwidth, steps, 0, 360);
383 }
384 
385 
386 void
387 GLHelper::drawOutlineCircle(double width, double iwidth, int steps,
388  double beg, double end) {
389  if (myCircleCoords.size() == 0) {
390  for (int i = 0; i < 360; i += 10) {
391  double x = (double) sin(DEG2RAD(i));
392  double y = (double) cos(DEG2RAD(i));
393  myCircleCoords.push_back(std::pair<double, double>(x, y));
394  }
395  }
396  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
397  std::pair<double, double> p1 =
398  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
399  for (int i = (int)(beg / 10); i < steps && (36.0 / (double) steps * (double) i) * 10 < end; i++) {
400  const std::pair<double, double>& p2 =
401  myCircleCoords[(int)(36.0 / (double) steps * (double) i)];
402  glBegin(GL_TRIANGLES);
403  glVertex2d(p1.first * width, p1.second * width);
404  glVertex2d(p2.first * width, p2.second * width);
405  glVertex2d(p2.first * iwidth, p2.second * iwidth);
406 
407  glVertex2d(p2.first * iwidth, p2.second * iwidth);
408  glVertex2d(p1.first * iwidth, p1.second * iwidth);
409  glVertex2d(p1.first * width, p1.second * width);
410  glEnd();
411  p1 = p2;
412  }
413  const std::pair<double, double>& p2 =
414  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
415  glBegin(GL_TRIANGLES);
416  glVertex2d(p1.first * width, p1.second * width);
417  glVertex2d(p2.first * width, p2.second * width);
418  glVertex2d(p2.first * iwidth, p2.second * iwidth);
419 
420  glVertex2d(p2.first * iwidth, p2.second * iwidth);
421  glVertex2d(p1.first * iwidth, p1.second * iwidth);
422  glVertex2d(p1.first * width, p1.second * width);
423  glEnd();
424 }
425 
426 
427 void
429  double tLength, double tWidth) {
430  const double length = p1.distanceTo(p2);
431  if (length < tLength) {
432  tWidth *= length / tLength;
433  tLength = length;
434  }
435  Position rl(PositionVector::positionAtOffset(p1, p2, length - tLength));
436  glPushMatrix();
437  glTranslated(rl.x(), rl.y(), 0);
438  glRotated(-GeomHelper::naviDegree(p1.angleTo2D(p2)), 0, 0, 1);
439  glBegin(GL_TRIANGLES);
440  glVertex2d(0, tLength);
441  glVertex2d(-tWidth, 0);
442  glVertex2d(+tWidth, 0);
443  glEnd();
444  glPopMatrix();
445 }
446 
447 
448 void
450  glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
451 }
452 
453 
454 RGBColor
456  GLdouble current[4];
457  glGetDoublev(GL_CURRENT_COLOR, current);
458  return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
459  static_cast<unsigned char>(current[1] * 255. + 0.5),
460  static_cast<unsigned char>(current[2] * 255. + 0.5),
461  static_cast<unsigned char>(current[3] * 255. + 0.5));
462 }
463 
464 
465 void
468  myFont = 0;
469 }
470 
471 
472 bool
474  if (myFont == 0) {
476  if (myFont != 0) {
478  fonsSetFont(myFont, fontNormal);
479  fonsSetSize(myFont, (float)myFontSize);
480  }
481  }
482  return myFont != 0;
483 }
484 
485 
486 void
487 GLHelper::drawText(const std::string& text, const Position& pos,
488  const double layer, const double size,
489  const RGBColor& col, const double angle, const int align,
490  double width) {
491  if (width <= 0) {
492  width = size;
493  }
494  if (!initFont()) {
495  return;
496  };
497  glPushMatrix();
498  glAlphaFunc(GL_GREATER, 0.5);
499  glEnable(GL_ALPHA_TEST);
500  glTranslated(pos.x(), pos.y(), layer);
501  glScaled(width / myFontSize, size / myFontSize, 1.);
502  glRotated(-angle, 0, 0, 1);
503  fonsSetAlign(myFont, align == 0 ? FONS_ALIGN_CENTER | FONS_ALIGN_MIDDLE : align);
504  fonsSetColor(myFont, glfonsRGBA(col.red(), col.green(), col.blue(), col.alpha()));
505  fonsDrawText(myFont, 0., 0., text.c_str(), NULL);
506  glPopMatrix();
507 }
508 
509 
510 void
511 GLHelper::drawTextBox(const std::string& text, const Position& pos,
512  const double layer, const double size,
513  const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
514  const double angle) {
515  if (!initFont()) {
516  return;
517  };
518  double boxAngle = angle + 90;
519  if (boxAngle > 360) {
520  boxAngle -= 360;
521  }
522  const double stringWidth = size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), NULL, NULL);
523  const double borderWidth = size / 20;
524  const double boxHeight = size * 0.8;
525  const double boxWidth = stringWidth + size / 2;
526  glPushMatrix();
527  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
528  glTranslated(0, 0, layer);
529  setColor(borderColor);
530  Position left = pos;
531  left.sub(boxWidth / 2, 0);
532  drawBoxLine(left, boxAngle, boxWidth, boxHeight);
533  left.add(borderWidth * 1.5, 0);
534  setColor(bgColor);
535  glTranslated(0, 0, 0.01);
536  drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
537  glPopMatrix();
538  drawText(text, pos, layer + 0.02, size, txtColor, angle);
539 }
540 
541 
542 void
543 GLHelper::drawTextAtEnd(const std::string& text, const PositionVector& shape, double x, double size, RGBColor color) {
544  glPushMatrix();
545  const Position& end = shape.back();
546  const Position& f = shape[-2];
547  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
548  glTranslated(end.x(), end.y(), 0);
549  glRotated(rot, 0, 0, 1);
550  GLHelper::drawText(text, Position(x, 0.26), 0, .6 * size / 50, color, 180);
551  glPopMatrix();
552 }
553 
554 
555 void
556 GLHelper::debugVertices(const PositionVector& shape, double size, double layer) {
557  RGBColor color = RGBColor::fromHSV(RandHelper::rand(360), 1, 1);
558  for (int i = 0; i < (int)shape.size(); ++i) {
559  GLHelper::drawText(toString(i), shape[i], layer, size, color, 0);
560  }
561 }
562 
563 
564 /****************************************************************************/
565 
FONS_DEF void fonsSetAlign(FONScontext *s, int align)
static std::vector< std::pair< double, double > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
Definition: GLHelper.h:321
static void resetFont()
to be called when the font context is invalidated
Definition: GLHelper.cpp:466
FONS_DEF float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:183
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:132
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, double size, RGBColor color)
draw text and the end of shape
Definition: GLHelper.cpp:543
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb.
Definition: RGBColor.cpp:301
static bool initFont()
init myFont
Definition: GLHelper.cpp:473
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:89
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:94
static void debugVertices(const PositionVector &shape, double size, double layer=256)
draw vertex numbers for the given shape (in a random color)
Definition: GLHelper.cpp:556
double y() const
Returns the y-position.
Definition: Position.h:67
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:64
double x() const
Returns the x-position.
Definition: Position.h:62
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
Definition: GLHelper.cpp:487
void glfonsDelete(FONScontext *ctx)
FONS_DEF void fonsSetFont(FONScontext *s, int font)
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Definition: Position.h:259
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:83
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:82
#define RAD2DEG(x)
Definition: GeomHelper.h:45
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:350
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:102
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:186
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:449
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
A list of positions.
static double myFontSize
Definition: GLHelper.h:325
static int angleLookup(double angleDeg)
normalize angle for lookup in myCircleCoords
Definition: GLHelper.cpp:338
T MIN2(T a, T b)
Definition: StdDefs.h:67
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:381
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:276
#define DEG2RAD(x)
Definition: GeomHelper.h:44
static struct FONScontext * myFont
Font context.
Definition: GLHelper.h:324
FONS_DEF void fonsSetColor(FONScontext *s, unsigned int color)
static void drawTextBox(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const double angle=0)
draw Text box with given parameters
Definition: GLHelper.cpp:511
void APIENTRY combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GLHelper.cpp:62
FONS_DEF void fonsSetSize(FONScontext *s, float size)
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:75
unsigned char data_font_Roboto_Medium_ttf[]
Definition: Roboto.h:20
static bool rightTurn(double angle1, double angle2)
whether the road makes a right turn (or goes straight)
Definition: GLHelper.cpp:170
#define CIRCLE_RESOLUTION
Definition: GLHelper.cpp:53
unsigned int data_font_Roboto_Medium_ttf_len
Definition: Roboto.h:14361
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:68
FONScontext * glfonsCreate(int width, int height, int flags)
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:428
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:239
FONS_DEF int fonsAddFontMem(FONScontext *s, const char *name, unsigned char *data, int ndata, int freeData)
struct FONScontext FONScontext
Definition: fontstash.h:95
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:137
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
FONS_DEF float fonsTextBounds(FONScontext *s, float x, float y, const char *string, const char *end, float *bounds)
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:455
void sub(double dx, double dy)
Substracts the given position from this one.
Definition: Position.h:152