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.sourceforge.net/
12 // Copyright (C) 2001-2012 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 #ifdef _WIN32
34 #include <windows.h>
35 #endif
36 
37 #include <GL/gl.h>
38 
39 #include "GLHelper.h"
40 #include <utils/geom/GeomHelper.h>
41 #include <utils/common/StdDefs.h>
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // static member definitions
51 // ===========================================================================
52 std::vector<std::pair<SUMOReal, SUMOReal> > GLHelper::myCircleCoords;
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
58 void
60  if (v.size() == 0) {
61  return;
62  }
63  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
64  glBegin(GL_POLYGON);
65  for (PositionVector::ContType ::const_iterator i = v.begin(); i != v.end(); i++) {
66  const Position& p = *i;
67  glVertex2d(p.x(), p.y());
68  }
69  if (close) {
70  const Position& p = *(v.begin());
71  glVertex2d(p.x(), p.y());
72  }
73  glEnd();
74 }
75 
76 
77 void
78 GLHelper::drawBoxLine(const Position& beg, SUMOReal rot, SUMOReal visLength,
79  SUMOReal width) {
80  glPushMatrix();
81  glTranslated(beg.x(), beg.y(), 0);
82  glRotated(rot, 0, 0, 1);
83  glBegin(GL_QUADS);
84  glVertex2d(-width, 0);
85  glVertex2d(-width, -visLength);
86  glVertex2d(width, -visLength);
87  glVertex2d(width, 0);
88  glEnd();
89  glPopMatrix();
90 }
91 
92 
93 void
94 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
95  SUMOReal rot, SUMOReal visLength,
96  SUMOReal width) {
97  glPushMatrix();
98  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
99  glRotated(rot, 0, 0, 1);
100  glBegin(GL_QUADS);
101  glVertex2d(-width, 0);
102  glVertex2d(-width, -visLength);
103  glVertex2d(width, -visLength);
104  glVertex2d(width, 0);
105  glEnd();
106  glPopMatrix();
107 }
108 
109 
110 void
112  const std::vector<SUMOReal> &rots,
113  const std::vector<SUMOReal> &lengths,
114  SUMOReal width) {
115  int e = (int) geom.size() - 1;
116  for (int i = 0; i < e; i++) {
117  drawBoxLine(geom[i], rots[i], lengths[i], width);
118  }
119 }
120 
121 
122 void
124  const PositionVector& geom2,
125  const std::vector<SUMOReal> &rots,
126  const std::vector<SUMOReal> &lengths,
127  SUMOReal width) {
128  int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
129  for (int i = 0; i < minS; i++) {
130  GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
131  }
132 }
133 
134 
135 void
137  int e = (int) geom.size() - 1;
138  for (int i = 0; i < e; i++) {
139  const Position& f = geom[i];
140  const Position& s = geom[i + 1];
141  drawBoxLine(f,
142  (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI,
143  f.distanceTo(s),
144  width);
145  }
146 }
147 
148 
149 void
150 GLHelper::drawLine(const Position& beg, SUMOReal rot, SUMOReal visLength) {
151  glPushMatrix();
152  glTranslated(beg.x(), beg.y(), 0);
153  glRotated(rot, 0, 0, 1);
154  glBegin(GL_LINES);
155  glVertex2d(0, 0);
156  glVertex2d(0, -visLength);
157  glEnd();
158  glPopMatrix();
159 }
160 
161 
162 void
163 GLHelper::drawLine(const Position& beg1, const Position& beg2,
164  SUMOReal rot, SUMOReal visLength) {
165  glPushMatrix();
166  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
167  glRotated(rot, 0, 0, 1);
168  glBegin(GL_LINES);
169  glVertex2d(0, 0);
170  glVertex2d(0, -visLength);
171  glEnd();
172  glPopMatrix();
173 }
174 
175 
176 
177 void
179  glBegin(GL_LINES);
180  int e = (int) v.size() - 1;
181  for (int i = 0; i < e; ++i) {
182  glVertex2d(v[i].x(), v[i].y());
183  glVertex2d(v[i + 1].x(), v[i + 1].y());
184  }
185  glEnd();
186 }
187 
188 
189 
190 void
191 GLHelper::drawLine(const Position& beg, const Position& end) {
192  glBegin(GL_LINES);
193  glVertex2d(beg.x(), beg.y());
194  glVertex2d(end.x(), end.y());
195  glEnd();
196 }
197 
198 
199 
200 void
202  drawFilledCircle(width, steps, 0, 360);
203 }
204 
205 
206 void
208  if (myCircleCoords.size() == 0) {
209  for (int i = 0; i < 360; i += 10) {
210  SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI);
211  SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI);
212  myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
213  }
214  }
215  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
216  std::pair<SUMOReal, SUMOReal> p1 =
217  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
218  for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
219  const std::pair<SUMOReal, SUMOReal> &p2 =
220  myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
221  glBegin(GL_TRIANGLES);
222  glVertex2d(p1.first * width, p1.second * width);
223  glVertex2d(p2.first * width, p2.second * width);
224  glVertex2d(0, 0);
225  glEnd();
226  p1 = p2;
227  }
228  const std::pair<SUMOReal, SUMOReal> &p2 =
229  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
230  glBegin(GL_TRIANGLES);
231  glVertex2d(p1.first * width, p1.second * width);
232  glVertex2d(p2.first * width, p2.second * width);
233  glVertex2d(0, 0);
234  glEnd();
235 }
236 
237 
238 void
239 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps) {
240  drawOutlineCircle(width, iwidth, steps, 0, 360);
241 }
242 
243 
244 void
246  SUMOReal beg, SUMOReal end) {
247  if (myCircleCoords.size() == 0) {
248  for (int i = 0; i < 360; i += 10) {
249  SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI);
250  SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI);
251  myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
252  }
253  }
254  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
255  std::pair<SUMOReal, SUMOReal> p1 =
256  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
257  for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
258  const std::pair<SUMOReal, SUMOReal> &p2 =
259  myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
260  glBegin(GL_TRIANGLES);
261  glVertex2d(p1.first * width, p1.second * width);
262  glVertex2d(p2.first * width, p2.second * width);
263  glVertex2d(p2.first * iwidth, p2.second * iwidth);
264 
265  glVertex2d(p2.first * iwidth, p2.second * iwidth);
266  glVertex2d(p1.first * iwidth, p1.second * iwidth);
267  glVertex2d(p1.first * width, p1.second * width);
268  glEnd();
269  p1 = p2;
270  }
271  const std::pair<SUMOReal, SUMOReal> &p2 =
272  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
273  glBegin(GL_TRIANGLES);
274  glVertex2d(p1.first * width, p1.second * width);
275  glVertex2d(p2.first * width, p2.second * width);
276  glVertex2d(p2.first * iwidth, p2.second * iwidth);
277 
278  glVertex2d(p2.first * iwidth, p2.second * iwidth);
279  glVertex2d(p1.first * iwidth, p1.second * iwidth);
280  glVertex2d(p1.first * width, p1.second * width);
281  glEnd();
282 }
283 
284 
285 void
287  SUMOReal tWidth) {
288  if (l.length() < tLength) {
289  tWidth = tWidth * l.length() / tLength;
290  tLength = l.length();
291  }
292  Line rl(l.getPositionAtDistance(l.length() - tLength), l.p2());
293  glPushMatrix();
294  glTranslated(rl.p1().x(), rl.p1().y(), 0);
295  glRotated(-l.atan2DegreeAngle(), 0, 0, 1);
296  glBegin(GL_TRIANGLES);
297  glVertex2d(0, -tLength);
298  glVertex2d(-tWidth, 0);
299  glVertex2d(+tWidth, 0);
300  glEnd();
301  glPopMatrix();
302 }
303 
304 
305 void
307  glColor3d(c.red(), c.green(), c.blue());
308 }
309 
310 
311 RGBColor
313  GLdouble current[4];
314  glGetDoublev(GL_CURRENT_COLOR, current);
315  return RGBColor(current[0], current[1], current[2]);
316 }
317 
318 
319 void
320 GLHelper::drawText(const std::string& text, const Position& pos,
321  const SUMOReal layer, const SUMOReal size,
322  const RGBColor& col, const SUMOReal angle) {
323  glPushMatrix();
324  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
325  setColor(col);
326  glTranslated(pos.x(), pos.y(), layer);
327  pfSetPosition(0, 0);
328  pfSetScale(size);
329  SUMOReal w = pfdkGetStringWidth(text.c_str());
330  glRotated(180, 1, 0, 0);
331  glRotated(angle, 0, 0, 1);
332  glTranslated(-w / 2., 0.4, 0);
333  pfDrawString(text.c_str());
334  glPopMatrix();
335 }
336 
337 void
338 GLHelper::drawTextBox(const std::string& text, const Position& pos,
339  const SUMOReal layer, const SUMOReal size,
340  const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
341  const SUMOReal angle) {
342  SUMOReal boxAngle = angle + 90;
343  if (boxAngle > 360) {
344  boxAngle -= 360;
345  }
346  pfSetScale(size);
347  const SUMOReal stringWidth = pfdkGetStringWidth(text.c_str());
348  const SUMOReal borderWidth = size / 20;
349  const SUMOReal boxHeight = size * 0.8;
350  const SUMOReal boxWidth = stringWidth + size / 2;
351  glPushMatrix();
352  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
353  glTranslated(0, 0, layer);
354  setColor(borderColor);
355  Position left = pos;
356  left.sub(boxWidth / 2, -boxHeight / 2.7);
357  drawBoxLine(left, boxAngle, boxWidth, boxHeight);
358  left.add(borderWidth * 1.5, 0);
359  setColor(bgColor);
360  glTranslated(0, 0, 0.01);
361  drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
362  // actually we should be able to use drawText here. however, there's
363  // something about the constant 0.4 offset which causes trouble
364  //drawText(text, pos, layer+0.02, size, txtColor, angle);
365  setColor(txtColor);
366  glTranslated(pos.x(), pos.y(), 0.01);
367  pfSetPosition(0, 0);
368  pfSetScale(size);
369  glRotated(180, 1, 0, 0);
370  glRotated(angle, 0, 0, 1);
371  glTranslated(-stringWidth / 2., 0, 0);
372  pfDrawString(text.c_str());
373  glPopMatrix();
374 }
375 
376 /****************************************************************************/
377