|
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 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