SUMO - Simulation of Urban MObility

GLHelper.cpp

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