|
SUMO - Simulation of Urban MObility
|
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