SUMO - Simulation of Urban MObility

GLHelper.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Some methods which help to draw certain geometrical objects in openGL
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #ifdef _WIN32
00034 #include <windows.h>
00035 #endif
00036 
00037 #include <GL/gl.h>
00038 
00039 #include "GLHelper.h"
00040 #include <utils/geom/GeomHelper.h>
00041 #include <utils/common/StdDefs.h>
00042 #include <foreign/polyfonts/polyfonts.h>
00043 
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047 
00048 
00049 // ===========================================================================
00050 // static member definitions
00051 // ===========================================================================
00052 std::vector<std::pair<SUMOReal, SUMOReal> > GLHelper::myCircleCoords;
00053 
00054 
00055 // ===========================================================================
00056 // method definitions
00057 // ===========================================================================
00058 void
00059 GLHelper::drawFilledPoly(const PositionVector& v, bool close) {
00060     if (v.size() == 0) {
00061         return;
00062     }
00063     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00064     glBegin(GL_POLYGON);
00065     const PositionVector::ContType& l = v.getCont();
00066     for (PositionVector::ContType ::const_iterator i = l.begin(); i != l.end(); i++) {
00067         const Position& p = *i;
00068         glVertex2d(p.x(), p.y());
00069     }
00070     if (close) {
00071         const Position& p = *(l.begin());
00072         glVertex2d(p.x(), p.y());
00073     }
00074     glEnd();
00075 }
00076 
00077 
00078 void
00079 GLHelper::drawBoxLine(const Position& beg, SUMOReal rot, SUMOReal visLength,
00080                       SUMOReal width) {
00081     glPushMatrix();
00082     glTranslated(beg.x(), beg.y(), 0);
00083     glRotated(rot, 0, 0, 1);
00084     glBegin(GL_QUADS);
00085     glVertex2d(-width, 0);
00086     glVertex2d(-width, -visLength);
00087     glVertex2d(width, -visLength);
00088     glVertex2d(width, 0);
00089     glEnd();
00090     glPopMatrix();
00091 }
00092 
00093 
00094 void
00095 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
00096                       SUMOReal rot, SUMOReal visLength,
00097                       SUMOReal width) {
00098     glPushMatrix();
00099     glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
00100     glRotated(rot, 0, 0, 1);
00101     glBegin(GL_QUADS);
00102     glVertex2d(-width, 0);
00103     glVertex2d(-width, -visLength);
00104     glVertex2d(width, -visLength);
00105     glVertex2d(width, 0);
00106     glEnd();
00107     glPopMatrix();
00108 }
00109 
00110 
00111 void
00112 GLHelper::drawBoxLines(const PositionVector& geom,
00113                        const std::vector<SUMOReal> &rots,
00114                        const std::vector<SUMOReal> &lengths,
00115                        SUMOReal width) {
00116     int e = (int) geom.size() - 1;
00117     for (int i = 0; i < e; i++) {
00118         drawBoxLine(geom[i], rots[i], lengths[i], width);
00119     }
00120 }
00121 
00122 
00123 void
00124 GLHelper::drawBoxLines(const PositionVector& geom1,
00125                        const PositionVector& geom2,
00126                        const std::vector<SUMOReal> &rots,
00127                        const std::vector<SUMOReal> &lengths,
00128                        SUMOReal width) {
00129     int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
00130     for (int i = 0; i < minS; i++) {
00131         GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
00132     }
00133 }
00134 
00135 
00136 void
00137 GLHelper::drawBoxLines(const PositionVector& geom, SUMOReal width) {
00138     int e = (int) geom.size() - 1;
00139     for (int i = 0; i < e; i++) {
00140         const Position& f = geom[i];
00141         const Position& s = geom[i + 1];
00142         drawBoxLine(f,
00143                     (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI,
00144                     f.distanceTo(s),
00145                     width);
00146     }
00147 }
00148 
00149 
00150 void
00151 GLHelper::drawLine(const Position& beg, SUMOReal rot, SUMOReal visLength) {
00152     glPushMatrix();
00153     glTranslated(beg.x(), beg.y(), 0);
00154     glRotated(rot, 0, 0, 1);
00155     glBegin(GL_LINES);
00156     glVertex2d(0, 0);
00157     glVertex2d(0, -visLength);
00158     glEnd();
00159     glPopMatrix();
00160 }
00161 
00162 
00163 void
00164 GLHelper::drawLine(const Position& beg1, const Position& beg2,
00165                    SUMOReal rot, SUMOReal visLength) {
00166     glPushMatrix();
00167     glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
00168     glRotated(rot, 0, 0, 1);
00169     glBegin(GL_LINES);
00170     glVertex2d(0, 0);
00171     glVertex2d(0, -visLength);
00172     glEnd();
00173     glPopMatrix();
00174 }
00175 
00176 
00177 
00178 void
00179 GLHelper::drawLine(const PositionVector& v) {
00180     glBegin(GL_LINES);
00181     int e = (int) v.size() - 1;
00182     for (int i = 0; i < e; ++i) {
00183         glVertex2d(v[i].x(), v[i].y());
00184         glVertex2d(v[i + 1].x(), v[i + 1].y());
00185     }
00186     glEnd();
00187 }
00188 
00189 
00190 
00191 void
00192 GLHelper::drawLine(const Position& beg, const Position& end) {
00193     glBegin(GL_LINES);
00194     glVertex2d(beg.x(), beg.y());
00195     glVertex2d(end.x(), end.y());
00196     glEnd();
00197 }
00198 
00199 
00200 
00201 void
00202 GLHelper::drawFilledCircle(SUMOReal width, int steps) {
00203     drawFilledCircle(width, steps, 0, 360);
00204 }
00205 
00206 
00207 void
00208 GLHelper::drawFilledCircle(SUMOReal width, int steps, SUMOReal beg, SUMOReal end) {
00209     if (myCircleCoords.size() == 0) {
00210         for (int i = 0; i < 360; i += 10) {
00211             SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI);
00212             SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI);
00213             myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
00214         }
00215     }
00216     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00217     std::pair<SUMOReal, SUMOReal> p1 =
00218         beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
00219     for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
00220         const std::pair<SUMOReal, SUMOReal> &p2 =
00221             myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
00222         glBegin(GL_TRIANGLES);
00223         glVertex2d(p1.first * width, p1.second * width);
00224         glVertex2d(p2.first * width, p2.second * width);
00225         glVertex2d(0, 0);
00226         glEnd();
00227         p1 = p2;
00228     }
00229     const std::pair<SUMOReal, SUMOReal> &p2 =
00230         end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
00231     glBegin(GL_TRIANGLES);
00232     glVertex2d(p1.first * width, p1.second * width);
00233     glVertex2d(p2.first * width, p2.second * width);
00234     glVertex2d(0, 0);
00235     glEnd();
00236 }
00237 
00238 
00239 void
00240 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps) {
00241     drawOutlineCircle(width, iwidth, steps, 0, 360);
00242 }
00243 
00244 
00245 void
00246 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps,
00247                             SUMOReal beg, SUMOReal end) {
00248     if (myCircleCoords.size() == 0) {
00249         for (int i = 0; i < 360; i += 10) {
00250             SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI);
00251             SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI);
00252             myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y));
00253         }
00254     }
00255     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00256     std::pair<SUMOReal, SUMOReal> p1 =
00257         beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
00258     for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) {
00259         const std::pair<SUMOReal, SUMOReal> &p2 =
00260             myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)];
00261         glBegin(GL_TRIANGLES);
00262         glVertex2d(p1.first * width, p1.second * width);
00263         glVertex2d(p2.first * width, p2.second * width);
00264         glVertex2d(p2.first * iwidth, p2.second * iwidth);
00265 
00266         glVertex2d(p2.first * iwidth, p2.second * iwidth);
00267         glVertex2d(p1.first * iwidth, p1.second * iwidth);
00268         glVertex2d(p1.first * width, p1.second * width);
00269         glEnd();
00270         p1 = p2;
00271     }
00272     const std::pair<SUMOReal, SUMOReal> &p2 =
00273         end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
00274     glBegin(GL_TRIANGLES);
00275     glVertex2d(p1.first * width, p1.second * width);
00276     glVertex2d(p2.first * width, p2.second * width);
00277     glVertex2d(p2.first * iwidth, p2.second * iwidth);
00278 
00279     glVertex2d(p2.first * iwidth, p2.second * iwidth);
00280     glVertex2d(p1.first * iwidth, p1.second * iwidth);
00281     glVertex2d(p1.first * width, p1.second * width);
00282     glEnd();
00283 }
00284 
00285 
00286 void
00287 GLHelper::drawTriangleAtEnd(const Line& l, SUMOReal tLength,
00288                             SUMOReal tWidth) {
00289     if (l.length() < tLength) {
00290         tWidth = tWidth * l.length() / tLength;
00291         tLength = l.length();
00292     }
00293     Line rl(l.getPositionAtDistance(l.length() - tLength), l.p2());
00294     glPushMatrix();
00295     glTranslated(rl.p1().x(), rl.p1().y(), 0);
00296     glRotated(-l.atan2DegreeAngle(), 0, 0, 1);
00297     glBegin(GL_TRIANGLES);
00298     glVertex2d(0, -tLength);
00299     glVertex2d(-tWidth, 0);
00300     glVertex2d(+tWidth, 0);
00301     glEnd();
00302     glPopMatrix();
00303 }
00304 
00305 
00306 void
00307 GLHelper::setColor(const RGBColor& c) {
00308     glColor3d(c.red(), c.green(), c.blue());
00309 }
00310 
00311 
00312 RGBColor
00313 GLHelper::getColor() {
00314     GLdouble current[4];
00315     glGetDoublev(GL_CURRENT_COLOR, current);
00316     return RGBColor(current[0], current[1], current[2]);
00317 }
00318 
00319 
00320 void
00321 GLHelper::drawText(const std::string& text, const Position& pos,
00322                    const SUMOReal layer, const SUMOReal size,
00323                    const RGBColor& col, const SUMOReal angle) {
00324     glPushMatrix();
00325     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00326     setColor(col);
00327     glTranslated(pos.x(), pos.y(), layer);
00328     pfSetPosition(0, 0);
00329     pfSetScale(size);
00330     SUMOReal w = pfdkGetStringWidth(text.c_str());
00331     glRotated(180, 1, 0, 0);
00332     glRotated(angle, 0, 0, 1);
00333     glTranslated(-w / 2., 0.4, 0);
00334     pfDrawString(text.c_str());
00335     glPopMatrix();
00336 }
00337 
00338 void
00339 GLHelper::drawTextBox(const std::string& text, const Position& pos,
00340                       const SUMOReal layer, const SUMOReal size,
00341                       const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
00342                       const SUMOReal angle) {
00343     SUMOReal boxAngle = angle + 90;
00344     if (boxAngle > 360) {
00345         boxAngle -= 360;
00346     }
00347     pfSetScale(size);
00348     const SUMOReal stringWidth = pfdkGetStringWidth(text.c_str());
00349     const SUMOReal borderWidth = size / 20;
00350     const SUMOReal boxHeight = size * 0.8;
00351     const SUMOReal boxWidth = stringWidth + size / 2;
00352     glPushMatrix();
00353     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00354     glTranslated(0, 0, layer);
00355     setColor(borderColor);
00356     Position left = pos;
00357     left.sub(boxWidth / 2, -boxHeight / 2.7);
00358     drawBoxLine(left, boxAngle, boxWidth, boxHeight);
00359     left.add(borderWidth * 1.5, 0);
00360     setColor(bgColor);
00361     glTranslated(0, 0, 0.01);
00362     drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
00363     // actually we should be able to use drawText here. however, there's
00364     // something about the constant 0.4 offset which causes trouble
00365     //drawText(text, pos, layer+0.02, size, txtColor, angle);
00366     setColor(txtColor);
00367     glTranslated(pos.x(), pos.y(), 0.01);
00368     pfSetPosition(0, 0);
00369     pfSetScale(size);
00370     glRotated(180, 1, 0, 0);
00371     glRotated(angle, 0, 0, 1);
00372     glTranslated(-stringWidth / 2., 0, 0);
00373     pfDrawString(text.c_str());
00374     glPopMatrix();
00375 }
00376 
00377 /****************************************************************************/
00378 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines