SUMO - Simulation of Urban MObility
|
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 for (PositionVector::ContType ::const_iterator i = v.begin(); i != v.end(); i++) { 00066 const Position& p = *i; 00067 glVertex2d(p.x(), p.y()); 00068 } 00069 if (close) { 00070 const Position& p = *(v.begin()); 00071 glVertex2d(p.x(), p.y()); 00072 } 00073 glEnd(); 00074 } 00075 00076 00077 void 00078 GLHelper::drawBoxLine(const Position& beg, SUMOReal rot, SUMOReal visLength, 00079 SUMOReal width) { 00080 glPushMatrix(); 00081 glTranslated(beg.x(), beg.y(), 0); 00082 glRotated(rot, 0, 0, 1); 00083 glBegin(GL_QUADS); 00084 glVertex2d(-width, 0); 00085 glVertex2d(-width, -visLength); 00086 glVertex2d(width, -visLength); 00087 glVertex2d(width, 0); 00088 glEnd(); 00089 glPopMatrix(); 00090 } 00091 00092 00093 void 00094 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2, 00095 SUMOReal rot, SUMOReal visLength, 00096 SUMOReal width) { 00097 glPushMatrix(); 00098 glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0); 00099 glRotated(rot, 0, 0, 1); 00100 glBegin(GL_QUADS); 00101 glVertex2d(-width, 0); 00102 glVertex2d(-width, -visLength); 00103 glVertex2d(width, -visLength); 00104 glVertex2d(width, 0); 00105 glEnd(); 00106 glPopMatrix(); 00107 } 00108 00109 00110 void 00111 GLHelper::drawBoxLines(const PositionVector& geom, 00112 const std::vector<SUMOReal> &rots, 00113 const std::vector<SUMOReal> &lengths, 00114 SUMOReal width) { 00115 int e = (int) geom.size() - 1; 00116 for (int i = 0; i < e; i++) { 00117 drawBoxLine(geom[i], rots[i], lengths[i], width); 00118 } 00119 } 00120 00121 00122 void 00123 GLHelper::drawBoxLines(const PositionVector& geom1, 00124 const PositionVector& geom2, 00125 const std::vector<SUMOReal> &rots, 00126 const std::vector<SUMOReal> &lengths, 00127 SUMOReal width) { 00128 int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size()); 00129 for (int i = 0; i < minS; i++) { 00130 GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width); 00131 } 00132 } 00133 00134 00135 void 00136 GLHelper::drawBoxLines(const PositionVector& geom, SUMOReal width) { 00137 int e = (int) geom.size() - 1; 00138 for (int i = 0; i < e; i++) { 00139 const Position& f = geom[i]; 00140 const Position& s = geom[i + 1]; 00141 drawBoxLine(f, 00142 (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI, 00143 f.distanceTo(s), 00144 width); 00145 } 00146 } 00147 00148 00149 void 00150 GLHelper::drawLine(const Position& beg, SUMOReal rot, SUMOReal visLength) { 00151 glPushMatrix(); 00152 glTranslated(beg.x(), beg.y(), 0); 00153 glRotated(rot, 0, 0, 1); 00154 glBegin(GL_LINES); 00155 glVertex2d(0, 0); 00156 glVertex2d(0, -visLength); 00157 glEnd(); 00158 glPopMatrix(); 00159 } 00160 00161 00162 void 00163 GLHelper::drawLine(const Position& beg1, const Position& beg2, 00164 SUMOReal rot, SUMOReal visLength) { 00165 glPushMatrix(); 00166 glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0); 00167 glRotated(rot, 0, 0, 1); 00168 glBegin(GL_LINES); 00169 glVertex2d(0, 0); 00170 glVertex2d(0, -visLength); 00171 glEnd(); 00172 glPopMatrix(); 00173 } 00174 00175 00176 00177 void 00178 GLHelper::drawLine(const PositionVector& v) { 00179 glBegin(GL_LINES); 00180 int e = (int) v.size() - 1; 00181 for (int i = 0; i < e; ++i) { 00182 glVertex2d(v[i].x(), v[i].y()); 00183 glVertex2d(v[i + 1].x(), v[i + 1].y()); 00184 } 00185 glEnd(); 00186 } 00187 00188 00189 00190 void 00191 GLHelper::drawLine(const Position& beg, const Position& end) { 00192 glBegin(GL_LINES); 00193 glVertex2d(beg.x(), beg.y()); 00194 glVertex2d(end.x(), end.y()); 00195 glEnd(); 00196 } 00197 00198 00199 00200 void 00201 GLHelper::drawFilledCircle(SUMOReal width, int steps) { 00202 drawFilledCircle(width, steps, 0, 360); 00203 } 00204 00205 00206 void 00207 GLHelper::drawFilledCircle(SUMOReal width, int steps, SUMOReal beg, SUMOReal end) { 00208 if (myCircleCoords.size() == 0) { 00209 for (int i = 0; i < 360; i += 10) { 00210 SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI); 00211 SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI); 00212 myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y)); 00213 } 00214 } 00215 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00216 std::pair<SUMOReal, SUMOReal> p1 = 00217 beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36]; 00218 for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) { 00219 const std::pair<SUMOReal, SUMOReal> &p2 = 00220 myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)]; 00221 glBegin(GL_TRIANGLES); 00222 glVertex2d(p1.first * width, p1.second * width); 00223 glVertex2d(p2.first * width, p2.second * width); 00224 glVertex2d(0, 0); 00225 glEnd(); 00226 p1 = p2; 00227 } 00228 const std::pair<SUMOReal, SUMOReal> &p2 = 00229 end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36]; 00230 glBegin(GL_TRIANGLES); 00231 glVertex2d(p1.first * width, p1.second * width); 00232 glVertex2d(p2.first * width, p2.second * width); 00233 glVertex2d(0, 0); 00234 glEnd(); 00235 } 00236 00237 00238 void 00239 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps) { 00240 drawOutlineCircle(width, iwidth, steps, 0, 360); 00241 } 00242 00243 00244 void 00245 GLHelper::drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps, 00246 SUMOReal beg, SUMOReal end) { 00247 if (myCircleCoords.size() == 0) { 00248 for (int i = 0; i < 360; i += 10) { 00249 SUMOReal x = (SUMOReal) sin((SUMOReal) i / 180.0 * PI); 00250 SUMOReal y = (SUMOReal) cos((SUMOReal) i / 180.0 * PI); 00251 myCircleCoords.push_back(std::pair<SUMOReal, SUMOReal>(x, y)); 00252 } 00253 } 00254 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00255 std::pair<SUMOReal, SUMOReal> p1 = 00256 beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36]; 00257 for (int i = (int)(beg / 10); i < steps && (36.0 / (SUMOReal) steps * (SUMOReal) i) * 10 < end; i++) { 00258 const std::pair<SUMOReal, SUMOReal> &p2 = 00259 myCircleCoords[(size_t)(36.0 / (SUMOReal) steps * (SUMOReal) i)]; 00260 glBegin(GL_TRIANGLES); 00261 glVertex2d(p1.first * width, p1.second * width); 00262 glVertex2d(p2.first * width, p2.second * width); 00263 glVertex2d(p2.first * iwidth, p2.second * iwidth); 00264 00265 glVertex2d(p2.first * iwidth, p2.second * iwidth); 00266 glVertex2d(p1.first * iwidth, p1.second * iwidth); 00267 glVertex2d(p1.first * width, p1.second * width); 00268 glEnd(); 00269 p1 = p2; 00270 } 00271 const std::pair<SUMOReal, SUMOReal> &p2 = 00272 end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36]; 00273 glBegin(GL_TRIANGLES); 00274 glVertex2d(p1.first * width, p1.second * width); 00275 glVertex2d(p2.first * width, p2.second * width); 00276 glVertex2d(p2.first * iwidth, p2.second * iwidth); 00277 00278 glVertex2d(p2.first * iwidth, p2.second * iwidth); 00279 glVertex2d(p1.first * iwidth, p1.second * iwidth); 00280 glVertex2d(p1.first * width, p1.second * width); 00281 glEnd(); 00282 } 00283 00284 00285 void 00286 GLHelper::drawTriangleAtEnd(const Line& l, SUMOReal tLength, 00287 SUMOReal tWidth) { 00288 if (l.length() < tLength) { 00289 tWidth = tWidth * l.length() / tLength; 00290 tLength = l.length(); 00291 } 00292 Line rl(l.getPositionAtDistance(l.length() - tLength), l.p2()); 00293 glPushMatrix(); 00294 glTranslated(rl.p1().x(), rl.p1().y(), 0); 00295 glRotated(-l.atan2DegreeAngle(), 0, 0, 1); 00296 glBegin(GL_TRIANGLES); 00297 glVertex2d(0, -tLength); 00298 glVertex2d(-tWidth, 0); 00299 glVertex2d(+tWidth, 0); 00300 glEnd(); 00301 glPopMatrix(); 00302 } 00303 00304 00305 void 00306 GLHelper::setColor(const RGBColor& c) { 00307 glColor3d(c.red(), c.green(), c.blue()); 00308 } 00309 00310 00311 RGBColor 00312 GLHelper::getColor() { 00313 GLdouble current[4]; 00314 glGetDoublev(GL_CURRENT_COLOR, current); 00315 return RGBColor(current[0], current[1], current[2]); 00316 } 00317 00318 00319 void 00320 GLHelper::drawText(const std::string& text, const Position& pos, 00321 const SUMOReal layer, const SUMOReal size, 00322 const RGBColor& col, const SUMOReal angle) { 00323 glPushMatrix(); 00324 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00325 setColor(col); 00326 glTranslated(pos.x(), pos.y(), layer); 00327 pfSetPosition(0, 0); 00328 pfSetScale(size); 00329 SUMOReal w = pfdkGetStringWidth(text.c_str()); 00330 glRotated(180, 1, 0, 0); 00331 glRotated(angle, 0, 0, 1); 00332 glTranslated(-w / 2., 0.4, 0); 00333 pfDrawString(text.c_str()); 00334 glPopMatrix(); 00335 } 00336 00337 void 00338 GLHelper::drawTextBox(const std::string& text, const Position& pos, 00339 const SUMOReal layer, const SUMOReal size, 00340 const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor, 00341 const SUMOReal angle) { 00342 SUMOReal boxAngle = angle + 90; 00343 if (boxAngle > 360) { 00344 boxAngle -= 360; 00345 } 00346 pfSetScale(size); 00347 const SUMOReal stringWidth = pfdkGetStringWidth(text.c_str()); 00348 const SUMOReal borderWidth = size / 20; 00349 const SUMOReal boxHeight = size * 0.8; 00350 const SUMOReal boxWidth = stringWidth + size / 2; 00351 glPushMatrix(); 00352 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00353 glTranslated(0, 0, layer); 00354 setColor(borderColor); 00355 Position left = pos; 00356 left.sub(boxWidth / 2, -boxHeight / 2.7); 00357 drawBoxLine(left, boxAngle, boxWidth, boxHeight); 00358 left.add(borderWidth * 1.5, 0); 00359 setColor(bgColor); 00360 glTranslated(0, 0, 0.01); 00361 drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth); 00362 // actually we should be able to use drawText here. however, there's 00363 // something about the constant 0.4 offset which causes trouble 00364 //drawText(text, pos, layer+0.02, size, txtColor, angle); 00365 setColor(txtColor); 00366 glTranslated(pos.x(), pos.y(), 0.01); 00367 pfSetPosition(0, 0); 00368 pfSetScale(size); 00369 glRotated(180, 1, 0, 0); 00370 glRotated(angle, 0, 0, 1); 00371 glTranslated(-stringWidth / 2., 0, 0); 00372 pfDrawString(text.c_str()); 00373 glPopMatrix(); 00374 } 00375 00376 /****************************************************************************/ 00377