SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GLHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Some methods which help to draw certain geometrical objects in openGL
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include "GLHelper.h"
34 #include <utils/geom/GeomHelper.h>
35 #include <utils/common/StdDefs.h>
38 
39 #ifdef CHECK_MEMORY_LEAKS
40 #include <foreign/nvwa/debug_new.h>
41 #endif // CHECK_MEMORY_LEAKS
42 
43 
44 // ===========================================================================
45 // static member definitions
46 // ===========================================================================
47 std::vector<std::pair<SUMOReal, SUMOReal> > GLHelper::myCircleCoords;
48 
49 
50 void APIENTRY combCallback(GLdouble coords[3],
51  GLdouble* vertex_data[4],
52  GLfloat weight[4], GLdouble** dataOut) {
53  UNUSED_PARAMETER(weight);
54  UNUSED_PARAMETER(*vertex_data);
55  GLdouble* vertex;
56 
57  vertex = (GLdouble*)malloc(7 * sizeof(GLdouble));
58 
59  vertex[0] = coords[0];
60  vertex[1] = coords[1];
61  vertex[2] = coords[2];
62  *dataOut = vertex;
63 }
64 
65 // ===========================================================================
66 // method definitions
67 // ===========================================================================
68 
69 
70 void
72  if (v.size() == 0) {
73  return;
74  }
75  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
76  glBegin(GL_POLYGON);
77  for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
78  const Position& p = *i;
79  glVertex2d(p.x(), p.y());
80  }
81  if (close) {
82  const Position& p = *(v.begin());
83  glVertex2d(p.x(), p.y());
84  }
85  glEnd();
86 }
87 
88 
89 void
91  if (v.size() == 0) {
92  return;
93  }
94  GLUtesselator* tobj = gluNewTess();
95  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
96  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
97  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
98  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combCallback);
99  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
100  gluTessBeginPolygon(tobj, NULL);
101  gluTessBeginContour(tobj);
102  double* points = new double[(v.size() + int(close)) * 3];
103 
104  for (size_t i = 0; i != v.size(); ++i) {
105  points[3 * i] = v[(int)i].x();
106  points[3 * i + 1] = v[(int)i].y();
107  points[3 * i + 2] = 0;
108  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
109  }
110  if (close) {
111  const size_t i = v.size();
112  points[3 * i] = v[0].x();
113  points[3 * i + 1] = v[0].y();
114  points[3 * i + 2] = 0;
115  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
116  }
117  gluTessEndContour(tobj);
118  gluTessEndPolygon(tobj);
119  gluDeleteTess(tobj);
120 }
121 
122 
123 void
124 GLHelper::drawBoxLine(const Position& beg, SUMOReal rot, SUMOReal visLength,
125  SUMOReal width) {
126  glPushMatrix();
127  glTranslated(beg.x(), beg.y(), 0);
128  glRotated(rot, 0, 0, 1);
129  glBegin(GL_QUADS);
130  glVertex2d(-width, 0);
131  glVertex2d(-width, -visLength);
132  glVertex2d(width, -visLength);
133  glVertex2d(width, 0);
134  glEnd();
135  glPopMatrix();
136 }
137 
138 
139 void
140 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
141  SUMOReal rot, SUMOReal visLength,
142  SUMOReal width) {
143  glPushMatrix();
144  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
145  glRotated(rot, 0, 0, 1);
146  glBegin(GL_QUADS);
147  glVertex2d(-width, 0);
148  glVertex2d(-width, -visLength);
149  glVertex2d(width, -visLength);
150  glVertex2d(width, 0);
151  glEnd();
152  glPopMatrix();
153 }
154 
155 
156 void
158  const std::vector<SUMOReal>& rots,
159  const std::vector<SUMOReal>& lengths,
160  SUMOReal width) {
161  int e = (int) geom.size() - 1;
162  for (int i = 0; i < e; i++) {
163  drawBoxLine(geom[i], rots[i], lengths[i], width);
164  }
165 }
166 
167 
168 void
170  const PositionVector& geom2,
171  const std::vector<SUMOReal>& rots,
172  const std::vector<SUMOReal>& lengths,
173  SUMOReal width) {
174  int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
175  for (int i = 0; i < minS; i++) {
176  GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
177  }
178 }
179 
180 
181 void
183  int e = (int) geom.size() - 1;
184  for (int i = 0; i < e; i++) {
185  const Position& f = geom[i];
186  const Position& s = geom[i + 1];
187  drawBoxLine(f,
188  RAD2DEG(atan2((s.x() - f.x()), (f.y() - s.y()))),
189  f.distanceTo(s),
190  width);
191  }
192 }
193 
194 
195 void
196 GLHelper::drawLine(const Position& beg, SUMOReal rot, SUMOReal visLength) {
197  glPushMatrix();
198  glTranslated(beg.x(), beg.y(), 0);
199  glRotated(rot, 0, 0, 1);
200  glBegin(GL_LINES);
201  glVertex2d(0, 0);
202  glVertex2d(0, -visLength);
203  glEnd();
204  glPopMatrix();
205 }
206 
207 
208 void
209 GLHelper::drawLine(const Position& beg1, const Position& beg2,
210  SUMOReal rot, SUMOReal visLength) {
211  glPushMatrix();
212  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
213  glRotated(rot, 0, 0, 1);
214  glBegin(GL_LINES);
215  glVertex2d(0, 0);
216  glVertex2d(0, -visLength);
217  glEnd();
218  glPopMatrix();
219 }
220 
221 
222 
223 void
225  glBegin(GL_LINES);
226  int e = (int) v.size() - 1;
227  for (int i = 0; i < e; ++i) {
228  glVertex2d(v[i].x(), v[i].y());
229  glVertex2d(v[i + 1].x(), v[i + 1].y());
230  }
231  glEnd();
232 }
233 
234 
235 
236 void
237 GLHelper::drawLine(const Position& beg, const Position& end) {
238  glBegin(GL_LINES);
239  glVertex2d(beg.x(), beg.y());
240  glVertex2d(end.x(), end.y());
241  glEnd();
242 }
243 
244 
245 
246 void
248  drawFilledCircle(width, steps, 0, 360);
249 }
250 
251 
252 void
254  if (myCircleCoords.size() == 0) {
255  for (int i = 0; i < 360; i += 10) {
256  const SUMOReal x = (SUMOReal) sin(DEG2RAD(i));
257  const SUMOReal y = (SUMOReal) cos(DEG2RAD(i));
258  myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
259  }
260  }
261  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
262  std::pair<SUMOReal, SUMOReal> p1 =
263  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
264  for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
265  const std::pair<SUMOReal, SUMOReal>& p2 =
266  myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
267  glBegin(GL_TRIANGLES);
268  glVertex2d(p1.first * width, p1.second * width);
269  glVertex2d(p2.first * width, p2.second * width);
270  glVertex2d(0, 0);
271  glEnd();
272  p1 = p2;
273  }
274  const std::pair<SUMOReal, SUMOReal>& p2 =
275  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
276  glBegin(GL_TRIANGLES);
277  glVertex2d(p1.first * width, p1.second * width);
278  glVertex2d(p2.first * width, p2.second * width);
279  glVertex2d(0, 0);
280  glEnd();
281 }
282 
283 
284 void
285 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps) {
286  drawOutlineCircle(width, iwidth, steps, 0, 360);
287 }
288 
289 
290 void
292  SUMOReal beg, SUMOReal end) {
293  if (myCircleCoords.size() == 0) {
294  for (int i = 0; i < 360; i += 10) {
295  SUMOReal x = (SUMOReal) sin(DEG2RAD(i));
296  SUMOReal y = (SUMOReal) cos(DEG2RAD(i));
297  myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
298  }
299  }
300  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
301  std::pair<SUMOReal, SUMOReal> p1 =
302  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
303  for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
304  const std::pair<SUMOReal, SUMOReal>& p2 =
305  myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
306  glBegin(GL_TRIANGLES);
307  glVertex2d(p1.first * width, p1.second * width);
308  glVertex2d(p2.first * width, p2.second * width);
309  glVertex2d(p2.first * iwidth, p2.second * iwidth);
310 
311  glVertex2d(p2.first * iwidth, p2.second * iwidth);
312  glVertex2d(p1.first * iwidth, p1.second * iwidth);
313  glVertex2d(p1.first * width, p1.second * width);
314  glEnd();
315  p1 = p2;
316  }
317  const std::pair<SUMOReal, SUMOReal>& p2 =
318  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
319  glBegin(GL_TRIANGLES);
320  glVertex2d(p1.first * width, p1.second * width);
321  glVertex2d(p2.first * width, p2.second * width);
322  glVertex2d(p2.first * iwidth, p2.second * iwidth);
323 
324  glVertex2d(p2.first * iwidth, p2.second * iwidth);
325  glVertex2d(p1.first * iwidth, p1.second * iwidth);
326  glVertex2d(p1.first * width, p1.second * width);
327  glEnd();
328 }
329 
330 
331 void
333  SUMOReal tWidth) {
334  if (l.length() < tLength) {
335  tWidth = tWidth * l.length() / tLength;
336  tLength = l.length();
337  }
338  Line rl(l.getPositionAtDistance(l.length() - tLength), l.p2());
339  glPushMatrix();
340  glTranslated(rl.p1().x(), rl.p1().y(), 0);
341  glRotated(-l.atan2DegreeAngle(), 0, 0, 1);
342  glBegin(GL_TRIANGLES);
343  glVertex2d(0, -tLength);
344  glVertex2d(-tWidth, 0);
345  glVertex2d(+tWidth, 0);
346  glEnd();
347  glPopMatrix();
348 }
349 
350 
351 void
353  glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
354 }
355 
356 
357 RGBColor
359  GLdouble current[4];
360  glGetDoublev(GL_CURRENT_COLOR, current);
361  return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
362  static_cast<unsigned char>(current[1] * 255. + 0.5),
363  static_cast<unsigned char>(current[2] * 255. + 0.5),
364  static_cast<unsigned char>(current[3] * 255. + 0.5));
365 }
366 
367 
368 void
369 GLHelper::drawText(const std::string& text, const Position& pos,
370  const SUMOReal layer, const SUMOReal size,
371  const RGBColor& col, const SUMOReal angle) {
372  glPushMatrix();
373  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
374  setColor(col);
375  glTranslated(pos.x(), pos.y(), layer);
376  pfSetPosition(0, 0);
377  pfSetScale(size);
378  SUMOReal w = pfdkGetStringWidth(text.c_str());
379  glRotated(180, 1, 0, 0);
380  glRotated(angle, 0, 0, 1);
381  glTranslated(-w / 2., 0.4, 0);
382  pfDrawString(text.c_str());
383  glPopMatrix();
384 }
385 
386 void
387 GLHelper::drawTextBox(const std::string& text, const Position& pos,
388  const SUMOReal layer, const SUMOReal size,
389  const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
390  const SUMOReal angle) {
391  SUMOReal boxAngle = angle + 90;
392  if (boxAngle > 360) {
393  boxAngle -= 360;
394  }
395  pfSetScale(size);
396  const SUMOReal stringWidth = pfdkGetStringWidth(text.c_str());
397  const SUMOReal borderWidth = size / 20;
398  const SUMOReal boxHeight = size * 0.8;
399  const SUMOReal boxWidth = stringWidth + size / 2;
400  glPushMatrix();
401  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
402  glTranslated(0, 0, layer);
403  setColor(borderColor);
404  Position left = pos;
405  left.sub(boxWidth / 2, -boxHeight / 2.7);
406  drawBoxLine(left, boxAngle, boxWidth, boxHeight);
407  left.add(borderWidth * 1.5, 0);
408  setColor(bgColor);
409  glTranslated(0, 0, 0.01);
410  drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
411  // actually we should be able to use drawText here. however, there's
412  // something about the constant 0.4 offset which causes trouble
413  //drawText(text, pos, layer+0.02, size, txtColor, angle);
414  setColor(txtColor);
415  glTranslated(pos.x(), pos.y(), 0.01);
416  pfSetPosition(0, 0);
417  pfSetScale(size);
418  glRotated(180, 1, 0, 0);
419  glRotated(angle, 0, 0, 1);
420  glTranslated(-stringWidth / 2., 0, 0);
421  pfDrawString(text.c_str());
422  glPopMatrix();
423 }
424 
425 /****************************************************************************/
426 
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
Definition: Position.h:139
SUMOReal atan2DegreeAngle() const
Definition: Line.cpp:143
int pfDrawString(const char *c)
Definition: polyfonts.c:1070
const Position & p2() const
Definition: Line.cpp:86
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:119
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:92
static void drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:285
void pfSetPosition(SUMOReal x, SUMOReal y)
Definition: polyfonts.c:476
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:71
#define RAD2DEG(x)
Definition: GeomHelper.h:46
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:219
static void drawText(const std::string &text, const Position &pos, const SUMOReal layer, const SUMOReal size, const RGBColor &col=RGBColor::BLACK, const SUMOReal angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:369
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:90
static void drawFilledCircle(SUMOReal width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:247
Position getPositionAtDistance(SUMOReal offset) const
Definition: Line.cpp:92
static std::vector< std::pair< SUMOReal, SUMOReal > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
Definition: GLHelper.h:266
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:352
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:99
Definition: Line.h:51
#define DEG2RAD(x)
Definition: GeomHelper.h:45
static void drawBoxLines(const PositionVector &geom, const std::vector< SUMOReal > &rots, const std::vector< SUMOReal > &lengths, SUMOReal width)
Draws thick lines.
Definition: GLHelper.cpp:157
static void drawTextBox(const std::string &text, const Position &pos, const SUMOReal layer, const SUMOReal size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const SUMOReal angle=0)
draw Text box with given parameters
Definition: GLHelper.cpp:387
static void drawBoxLine(const Position &beg, SUMOReal rot, SUMOReal visLength, SUMOReal width)
Draws a thick line.
Definition: GLHelper.cpp:124
SUMOReal length() const
Definition: Line.cpp:183
void APIENTRY combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GLHelper.cpp:50
void pfSetScale(SUMOReal s)
Definition: polyfonts.c:461
static void drawTriangleAtEnd(const Line &l, SUMOReal tLength, SUMOReal tWidth)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:332
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
SUMOReal pfdkGetStringWidth(const char *c)
Definition: polyfonts.c:1109
static void drawLine(const Position &beg, SUMOReal rot, SUMOReal visLength)
Draws a thin line.
Definition: GLHelper.cpp:196
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:215
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:75
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:358