LCOV - code coverage report
Current view: top level - src/utils/gui/div - GLHelper.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 50.7 % 477 242
Test Date: 2024-11-20 15:55:46 Functions: 54.9 % 51 28

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    GLHelper.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // Some methods which help to draw certain geometrical objects in openGL
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <utils/geom/GeomHelper.h>
      26              : #include <utils/common/StdDefs.h>
      27              : #include <utils/common/MsgHandler.h>
      28              : #include <utils/common/ToString.h>
      29              : #include <utils/options/OptionsCont.h>
      30              : #define FONTSTASH_IMPLEMENTATION // Expands implementation
      31              : #ifdef _MSC_VER
      32              : #pragma warning(disable: 4505 5219) // do not warn about unused functions and implicit float conversions
      33              : #endif
      34              : #if __GNUC__ > 3
      35              : #pragma GCC diagnostic push
      36              : #pragma GCC diagnostic ignored "-Wunused-function"
      37              : #endif
      38              : #include <foreign/fontstash/fontstash.h>
      39              : #include <utils/gui/globjects/GLIncludes.h>
      40              : #define GLFONTSTASH_IMPLEMENTATION // Expands implementation
      41              : #include <foreign/fontstash/glfontstash.h>
      42              : #include <utils/geom/Boundary.h>
      43              : #ifdef HAVE_GL2PS
      44              : #include <gl2ps.h>
      45              : #endif
      46              : #include "Roboto.h"
      47              : #include "GLHelper.h"
      48              : 
      49              : #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
      50              : //#define CHECK_PUSHPOP         // enable or disable check push and pop matrix/names
      51              : //#define CHECK_ELEMENTCOUNTER  // enable or disable element counter (for matrix and vertex)
      52              : 
      53              : #ifndef CALLBACK
      54              : #define CALLBACK
      55              : #endif
      56              : 
      57              : // ===========================================================================
      58              : // static member definitions
      59              : // ===========================================================================
      60              : 
      61              : int GLHelper::myMatrixCounter = 0;
      62              : int GLHelper::myVertexCounter = 0;
      63              : int GLHelper::myMatrixCounterDebug = 0;
      64              : int GLHelper::myNameCounter = 0;
      65              : std::vector<std::pair<double, double> > GLHelper::myCircleCoords;
      66              : std::vector<RGBColor> GLHelper::myDottedcontourColors;
      67              : FONScontext* GLHelper::myFont = nullptr;
      68              : double GLHelper::myFontSize = 50.0;
      69              : bool GLHelper::myGL2PSActive = false;
      70              : 
      71            0 : void CALLBACK combCallback(GLdouble coords[3],
      72              :                            GLdouble* vertex_data[4],
      73              :                            GLfloat weight[4], GLdouble** dataOut) {
      74              :     UNUSED_PARAMETER(weight);
      75              :     UNUSED_PARAMETER(*vertex_data);
      76              :     GLdouble* vertex;
      77              : 
      78            0 :     vertex = (GLdouble*)malloc(7 * sizeof(GLdouble));
      79              : 
      80            0 :     vertex[0] = coords[0];
      81            0 :     vertex[1] = coords[1];
      82            0 :     vertex[2] = coords[2];
      83            0 :     *dataOut = vertex;
      84            0 : }
      85              : 
      86              : // ===========================================================================
      87              : // method definitions
      88              : // ===========================================================================
      89              : 
      90              : const std::vector<std::pair<double, double> >&
      91    187009806 : GLHelper::getCircleCoords() {
      92              :     // fill in first call
      93    187009806 :     if (myCircleCoords.size() == 0) {
      94      4437664 :         for (int i = 0; i <= (int)(360 * CIRCLE_RESOLUTION); ++i) {
      95      4436432 :             const double x = (double) sin(DEG2RAD(i / CIRCLE_RESOLUTION));
      96      4436432 :             const double y = (double) cos(DEG2RAD(i / CIRCLE_RESOLUTION));
      97      4436432 :             myCircleCoords.push_back(std::pair<double, double>(x, y));
      98              :         }
      99              :     }
     100    187009806 :     return myCircleCoords;
     101              : }
     102              : 
     103              : 
     104              : int
     105     93504903 : GLHelper::angleLookup(double angleDeg) {
     106     93504903 :     const int numCoords = (int)getCircleCoords().size() - 1;
     107     93504903 :     int index = ((int)(floor(angleDeg * CIRCLE_RESOLUTION + 0.5))) % numCoords;
     108     93504903 :     if (index < 0) {
     109       619415 :         index += numCoords;
     110              :     }
     111              :     assert(index >= 0);
     112     93504903 :     return (int)index;
     113              : }
     114              : 
     115              : 
     116              : void
     117     83890541 : GLHelper::pushMatrix() {
     118     83890541 :     glPushMatrix();
     119              :     // update counters
     120              : #ifdef CHECK_ELEMENTCOUNTER
     121              :     myMatrixCounter++;
     122              : #endif
     123              : #ifdef CHECK_PUSHPOP
     124              :     myMatrixCounterDebug++;
     125              : #endif
     126     83890541 : }
     127              : 
     128              : 
     129              : void
     130     84386307 : GLHelper::popMatrix() {
     131     84386307 :     glPopMatrix();
     132              : #ifdef CHECK_PUSHPOP
     133              :     myMatrixCounterDebug--;
     134              : #endif
     135     84386307 : }
     136              : 
     137              : 
     138              : void
     139     59874043 : GLHelper::pushName(unsigned int name) {
     140     59874043 :     glPushName(name);
     141              : #ifdef CHECK_PUSHPOP
     142              :     myNameCounter++;
     143              : #endif
     144     59874043 : }
     145              : 
     146              : 
     147              : void
     148     59874043 : GLHelper::popName() {
     149     59874043 :     glPopName();
     150              : #ifdef CHECK_PUSHPOP
     151              :     myNameCounter--;
     152              : #endif
     153     59874043 : }
     154              : 
     155              : 
     156              : int
     157            0 : GLHelper::getMatrixCounter() {
     158            0 :     return myMatrixCounter;
     159              : }
     160              : 
     161              : 
     162              : void
     163       546620 : GLHelper::resetMatrixCounter() {
     164       546620 :     myMatrixCounter = 0;
     165       546620 : }
     166              : 
     167              : 
     168              : int
     169            0 : GLHelper::getVertexCounter() {
     170            0 :     return myVertexCounter;
     171              : }
     172              : 
     173              : 
     174              : void
     175       546620 : GLHelper::resetVertexCounter() {
     176       546620 :     myVertexCounter = 0;
     177       546620 : }
     178              : 
     179              : 
     180              : void
     181       546620 : GLHelper::checkCounterMatrix() {
     182              : #ifdef CHECK_PUSHPOP
     183              :     if (myMatrixCounterDebug != 0) {
     184              :         WRITE_WARNING("invalid matrix counter. Check that number of pushMatrix and popMatrix functions calls are the same");
     185              :     }
     186              :     myMatrixCounterDebug = 0;
     187              : #endif
     188       546620 : }
     189              : 
     190              : 
     191              : void
     192       546620 : GLHelper::checkCounterName() {
     193              : #ifdef CHECK_PUSHPOP
     194              :     if (myNameCounter != 0) {
     195              :         WRITE_WARNING("invalid Name counter. Check that number of pushName and popName functions calls are the same");
     196              :     }
     197              :     myNameCounter = 0;
     198              : #endif
     199       546620 : }
     200              : 
     201              : 
     202              : void
     203      1015435 : GLHelper::drawFilledPoly(const PositionVector& v, bool close) {
     204      1015435 :     if (v.size() == 0) {
     205              :         return;
     206              :     }
     207      1015435 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     208      1015435 :     glBegin(GL_POLYGON);
     209      7239077 :     for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
     210              :         const Position& p = *i;
     211      6223642 :         glVertex2d(p.x(), p.y());
     212              : #ifdef CHECK_ELEMENTCOUNTER
     213              :         myVertexCounter++;
     214              : #endif
     215              :     }
     216      1015435 :     if (close) {
     217              :         const Position& p = *(v.begin());
     218      1015435 :         glVertex2d(p.x(), p.y());
     219              : #ifdef CHECK_ELEMENTCOUNTER
     220              :         myVertexCounter++;
     221              : #endif
     222              :     }
     223      1015435 :     glEnd();
     224              : }
     225              : 
     226              : 
     227              : void
     228            0 : GLHelper::drawFilledPolyTesselated(const PositionVector& v, bool close) {
     229            0 :     if (v.size() == 0) {
     230              :         return;
     231              :     }
     232            0 :     GLUtesselator* tobj = gluNewTess();
     233              : #ifdef _MSC_VER
     234              : #pragma warning(push)
     235              : #pragma warning(disable: 4191)
     236              : #endif
     237              : #if defined(__GNUC__) && __GNUC__ >= 8
     238              : #pragma GCC diagnostic push
     239              : #pragma GCC diagnostic ignored "-Wcast-function-type"
     240              : #endif
     241            0 :     gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(CALLBACK*)()) &glVertex3dv);
     242            0 :     gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(CALLBACK*)()) &glBegin);
     243            0 :     gluTessCallback(tobj, GLU_TESS_END, (GLvoid(CALLBACK*)()) &glEnd);
     244            0 :     gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(CALLBACK*)()) &combCallback);
     245              : #if defined(__GNUC__) && __GNUC__ >= 8
     246              : #pragma GCC diagnostic pop
     247              : #endif
     248              : #ifdef _MSC_VER
     249              : #pragma warning(pop)
     250              : #endif
     251            0 :     gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
     252            0 :     gluTessBeginPolygon(tobj, nullptr);
     253            0 :     gluTessBeginContour(tobj);
     254            0 :     double* points = new double[(v.size() + int(close)) * 3];
     255              : 
     256            0 :     for (int i = 0; i != (int)v.size(); ++i) {
     257            0 :         points[3 * i] = v[i].x();
     258            0 :         points[3 * i + 1] = v[i].y();
     259            0 :         points[3 * i + 2] = 0;
     260            0 :         gluTessVertex(tobj, points + 3 * i, points + 3 * i);
     261              :     }
     262            0 :     if (close) {
     263              :         const int i = (int)v.size();
     264            0 :         points[3 * i] = v[0].x();
     265            0 :         points[3 * i + 1] = v[0].y();
     266            0 :         points[3 * i + 2] = 0;
     267            0 :         gluTessVertex(tobj, points + 3 * i, points + 3 * i);
     268              :     }
     269            0 :     gluTessEndContour(tobj);
     270            0 :     gluTessEndPolygon(tobj);
     271            0 :     gluDeleteTess(tobj);
     272            0 :     delete[] points;
     273              : }
     274              : 
     275              : 
     276              : void
     277            0 : GLHelper::drawRectangle(const Position& center, const double width, const double height) {
     278            0 :     const double halfWidth = width * 0.5;
     279            0 :     const double halfHeight = height * 0.5;
     280            0 :     GLHelper::pushMatrix();
     281            0 :     glTranslated(center.x(), center.y(), 0);
     282            0 :     glBegin(GL_QUADS);
     283            0 :     glVertex2d(-halfWidth, halfHeight);
     284            0 :     glVertex2d(-halfWidth, -halfHeight);
     285            0 :     glVertex2d(halfWidth, -halfHeight);
     286            0 :     glVertex2d(halfWidth, halfHeight);
     287            0 :     glEnd();
     288            0 :     GLHelper::popMatrix();
     289              : #ifdef CHECK_ELEMENTCOUNTER
     290              :     myVertexCounter += 4;
     291              : #endif
     292            0 : }
     293              : 
     294              : void
     295     18188275 : GLHelper::drawBoxLine(const Position& beg, double rot, double visLength,
     296              :                       double width, double offset) {
     297     18188275 :     GLHelper::pushMatrix();
     298     18188275 :     glTranslated(beg.x(), beg.y(), 0);
     299     18188275 :     glRotated(rot, 0, 0, 1);
     300     18188275 :     glBegin(GL_QUADS);
     301     18188275 :     glVertex2d(-width - offset, 0);
     302     18188275 :     glVertex2d(-width - offset, -visLength);
     303     18188275 :     glVertex2d(width - offset, -visLength);
     304     18188275 :     glVertex2d(width - offset, 0);
     305     18188275 :     glEnd();
     306     18188275 :     GLHelper::popMatrix();
     307              : #ifdef CHECK_ELEMENTCOUNTER
     308              :     myVertexCounter += 4;
     309              : #endif
     310     18188275 : }
     311              : 
     312              : 
     313              : void
     314            0 : GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
     315              :                       double rot, double visLength,
     316              :                       double width) {
     317            0 :     GLHelper::pushMatrix();
     318            0 :     glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
     319            0 :     glRotated(rot, 0, 0, 1);
     320            0 :     glBegin(GL_QUADS);
     321            0 :     glVertex2d(-width, 0);
     322            0 :     glVertex2d(-width, -visLength);
     323            0 :     glVertex2d(width, -visLength);
     324            0 :     glVertex2d(width, 0);
     325            0 :     glEnd();
     326            0 :     GLHelper::popMatrix();
     327              : #ifdef CHECK_ELEMENTCOUNTER
     328              :     myVertexCounter += 4;
     329              : #endif
     330            0 : }
     331              : 
     332              : 
     333              : bool
     334       116568 : GLHelper::rightTurn(double angle1, double angle2) {
     335       116568 :     double delta = angle2 - angle1;
     336       116677 :     while (delta > 180) {
     337          109 :         delta -= 360;
     338              :     }
     339       120130 :     while (delta < -180) {
     340         3562 :         delta += 360;
     341              :     }
     342       116568 :     return delta <= 0;
     343              : }
     344              : 
     345              : 
     346              : void
     347      7460146 : GLHelper::drawBoxLines(const PositionVector& geom,
     348              :                        const std::vector<double>& rots,
     349              :                        const std::vector<double>& lengths,
     350              :                        double width, int cornerDetail, double offset) {
     351              :     // draw the lane
     352      7460146 :     int e = (int) geom.size() - 1;
     353     25063880 :     for (int i = 0; i < e; i++) {
     354     17603734 :         drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
     355              :     }
     356              :     // draw the corner details
     357      7460146 :     if (cornerDetail > 0) {
     358       475877 :         for (int i = 1; i < e; i++) {
     359       116568 :             GLHelper::pushMatrix();
     360       116568 :             glTranslated(geom[i].x(), geom[i].y(), 0.1);
     361       116568 :             double angleBeg = -rots[i - 1];
     362       116568 :             double angleEnd = 180 - rots[i];
     363       116568 :             if (rightTurn(rots[i - 1], rots[i])) {
     364              :                 std::swap(angleBeg, angleEnd);
     365              :             }
     366              :             // only draw the missing piece
     367       116568 :             angleBeg -= 90;
     368       116568 :             angleEnd += 90;
     369              :             // avoid drawing more than 360 degrees
     370       116568 :             if (angleEnd - angleBeg > 360) {
     371         3562 :                 angleBeg += 360;
     372              :             }
     373       116568 :             if (angleEnd - angleBeg < -360) {
     374            0 :                 angleEnd += 360;
     375              :             }
     376              :             // draw the right way around
     377       116568 :             if (angleEnd > angleBeg) {
     378        57272 :                 angleEnd -= 360;
     379              :             }
     380       116568 :             drawFilledCircle(width + offset, cornerDetail, angleBeg, angleEnd);
     381       116568 :             GLHelper::popMatrix();
     382              :         }
     383              :     }
     384      7460146 : }
     385              : 
     386              : 
     387              : void
     388            0 : GLHelper::drawBoxLines(const PositionVector& geom,
     389              :                        const std::vector<double>& rots,
     390              :                        const std::vector<double>& lengths,
     391              :                        const std::vector<RGBColor>& cols,
     392              :                        double width, int cornerDetail, double offset) {
     393            0 :     int e = (int) geom.size() - 1;
     394            0 :     for (int i = 0; i < e; i++) {
     395            0 :         setColor(cols[i]);
     396            0 :         drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
     397              :     }
     398            0 :     if (cornerDetail > 0) {
     399            0 :         for (int i = 1; i < e; i++) {
     400            0 :             GLHelper::pushMatrix();
     401            0 :             setColor(cols[i]);
     402            0 :             glTranslated(geom[i].x(), geom[i].y(), 0);
     403            0 :             drawFilledCircle(width, cornerDetail);
     404            0 :             GLHelper::popMatrix();
     405              :         }
     406              :     }
     407            0 : }
     408              : 
     409              : 
     410              : void
     411            0 : GLHelper::drawBoxLines(const PositionVector& geom1,
     412              :                        const PositionVector& geom2,
     413              :                        const std::vector<double>& rots,
     414              :                        const std::vector<double>& lengths,
     415              :                        double width) {
     416            0 :     int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
     417            0 :     for (int i = 0; i < minS; i++) {
     418            0 :         GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
     419              :     }
     420            0 : }
     421              : 
     422              : 
     423              : void
     424        23136 : GLHelper::drawBoxLines(const PositionVector& geom, double width) {
     425        23136 :     int e = (int) geom.size() - 1;
     426       102348 :     for (int i = 0; i < e; i++) {
     427        79212 :         const Position& f = geom[i];
     428        79212 :         const Position& s = geom[i + 1];
     429        79212 :         drawBoxLine(f,
     430        79212 :                     RAD2DEG(atan2((s.x() - f.x()), (f.y() - s.y()))),
     431              :                     f.distanceTo(s),
     432              :                     width);
     433              :     }
     434        23136 : }
     435              : 
     436              : 
     437              : void
     438          970 : GLHelper::drawLine(const Position& beg, double rot, double visLength) {
     439          970 :     GLHelper::pushMatrix();
     440          970 :     glTranslated(beg.x(), beg.y(), 0);
     441          970 :     glRotated(rot, 0, 0, 1);
     442          970 :     glBegin(GL_LINES);
     443          970 :     glVertex2d(0, 0);
     444          970 :     glVertex2d(0, -visLength);
     445          970 :     glEnd();
     446          970 :     GLHelper::popMatrix();
     447              : #ifdef CHECK_ELEMENTCOUNTER
     448              :     myVertexCounter += 2;
     449              : #endif
     450          970 : }
     451              : 
     452              : 
     453              : void
     454            0 : GLHelper::drawLine(const Position& beg1, const Position& beg2,
     455              :                    double rot, double visLength) {
     456            0 :     GLHelper::pushMatrix();
     457            0 :     glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
     458            0 :     glRotated(rot, 0, 0, 1);
     459            0 :     glBegin(GL_LINES);
     460            0 :     glVertex2d(0, 0);
     461            0 :     glVertex2d(0, -visLength);
     462            0 :     glEnd();
     463            0 :     GLHelper::popMatrix();
     464              : #ifdef CHECK_ELEMENTCOUNTER
     465              :     myVertexCounter += 2;
     466              : #endif
     467            0 : }
     468              : 
     469              : 
     470              : 
     471              : void
     472      8730406 : GLHelper::drawLine(const PositionVector& v) {
     473      8730406 :     glBegin(GL_LINES);
     474      8730406 :     int e = (int) v.size() - 1;
     475     22927359 :     for (int i = 0; i < e; ++i) {
     476     14196953 :         glVertex2d(v[i].x(), v[i].y());
     477     14196953 :         glVertex2d(v[i + 1].x(), v[i + 1].y());
     478              : #ifdef CHECK_ELEMENTCOUNTER
     479              :         myVertexCounter += 2;
     480              : #endif
     481              :     }
     482      8730406 :     glEnd();
     483      8730406 : }
     484              : 
     485              : 
     486              : void
     487            0 : GLHelper::drawLine(const PositionVector& v, const std::vector<RGBColor>& cols) {
     488            0 :     glBegin(GL_LINES);
     489            0 :     int e = (int) v.size() - 1;
     490            0 :     for (int i = 0; i < e; ++i) {
     491            0 :         setColor(cols[i]);
     492            0 :         glVertex2d(v[i].x(), v[i].y());
     493            0 :         glVertex2d(v[i + 1].x(), v[i + 1].y());
     494              : #ifdef CHECK_ELEMENTCOUNTER
     495              :         myVertexCounter += 2;
     496              : #endif
     497              :     }
     498            0 :     glEnd();
     499            0 : }
     500              : 
     501              : 
     502              : void
     503            0 : GLHelper::drawLine(const Position& beg, const Position& end) {
     504            0 :     glBegin(GL_LINES);
     505            0 :     glVertex2d(beg.x(), beg.y());
     506            0 :     glVertex2d(end.x(), end.y());
     507            0 :     glEnd();
     508              : #ifdef CHECK_ELEMENTCOUNTER
     509              :     myVertexCounter += 2;
     510              : #endif
     511            0 : }
     512              : 
     513              : 
     514              : void
     515            0 : GLHelper::drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius,
     516              :                                     double beg, double end) {
     517              :     // get current resolution level
     518            0 :     switch (d) {
     519            0 :         case GUIVisualizationSettings::Detail::CircleResolution32:
     520            0 :             drawFilledCircle(radius, 32, beg, end);
     521            0 :             break;
     522            0 :         case GUIVisualizationSettings::Detail::CircleResolution16:
     523            0 :             drawFilledCircle(radius, 16, beg, end);
     524            0 :             break;
     525            0 :         case GUIVisualizationSettings::Detail::CircleResolution8:
     526            0 :             drawFilledCircle(radius, 8, beg, end);
     527            0 :             break;
     528            0 :         case GUIVisualizationSettings::Detail::CircleResolution4:
     529            0 :             drawFilledCircleDetailled(d, radius);
     530            0 :             break;
     531              :         default:
     532              :             // nothing to draw
     533              :             break;
     534              :     }
     535            0 : }
     536              : 
     537              : 
     538              : void
     539            0 : GLHelper::drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius) {
     540              :     // get current resolution level
     541            0 :     switch (d) {
     542            0 :         case GUIVisualizationSettings::Detail::CircleResolution32:
     543            0 :             drawFilledCircle(radius, 32);
     544            0 :             break;
     545            0 :         case GUIVisualizationSettings::Detail::CircleResolution16:
     546            0 :             drawFilledCircle(radius, 16);
     547            0 :             break;
     548            0 :         case GUIVisualizationSettings::Detail::CircleResolution8:
     549            0 :             drawFilledCircle(radius, 8);
     550            0 :             break;
     551            0 :         default:
     552              :             // draw only a square
     553            0 :             GLHelper::pushMatrix();
     554            0 :             glBegin(GL_QUADS);
     555            0 :             glVertex2d(-radius, radius);
     556            0 :             glVertex2d(-radius, -radius);
     557            0 :             glVertex2d(radius, -radius);
     558            0 :             glVertex2d(radius, radius);
     559            0 :             glEnd();
     560            0 :             GLHelper::popMatrix();
     561              : #ifdef CHECK_ELEMENTCOUNTER
     562              :             myVertexCounter += 4;
     563              : #endif
     564            0 :             break;
     565              :     }
     566            0 : }
     567              : 
     568              : void
     569     11458698 : GLHelper::drawFilledCircle(double const radius, int const steps) {
     570     11458698 :     drawFilledCircle(radius, steps, 0, 360);
     571     11458698 : }
     572              : 
     573              : 
     574              : void
     575     11575281 : GLHelper::drawFilledCircle(double radius, int steps, double beg, double end) {
     576     11575281 :     const double inc = (end - beg) / (double)steps;
     577     11575281 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     578     11575281 :     std::pair<double, double> p1 = getCircleCoords().at(angleLookup(beg));
     579              : 
     580     93504903 :     for (int i = 0; i <= steps; ++i) {
     581     81929622 :         const std::pair<double, double>& p2 = getCircleCoords().at(angleLookup(beg + i * inc));
     582     81929622 :         glBegin(GL_TRIANGLES);
     583     81929622 :         glVertex2d(p1.first * radius, p1.second * radius);
     584     81929622 :         glVertex2d(p2.first * radius, p2.second * radius);
     585     81929622 :         glVertex2d(0, 0);
     586     81929622 :         glEnd();
     587              :         p1 = p2;
     588              : #ifdef CHECK_ELEMENTCOUNTER
     589              :         myVertexCounter += 3;
     590              : #endif
     591              :     }
     592     11575281 : }
     593              : 
     594              : 
     595              : void
     596            0 : GLHelper::drawOutlineCircle(double radius, double iRadius, int steps) {
     597            0 :     drawOutlineCircle(radius, iRadius, steps, 0, 360);
     598            0 : }
     599              : 
     600              : 
     601              : void
     602            0 : GLHelper::drawOutlineCircle(double radius, double iRadius, int steps,
     603              :                             double beg, double end) {
     604            0 :     const double inc = (end - beg) / (double)steps;
     605            0 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     606            0 :     std::pair<double, double> p1 = getCircleCoords().at(angleLookup(beg));
     607              : 
     608            0 :     for (int i = 0; i <= steps; ++i) {
     609            0 :         const std::pair<double, double>& p2 = getCircleCoords().at(angleLookup(beg + i * inc));
     610            0 :         glBegin(GL_TRIANGLES);
     611            0 :         glVertex2d(p1.first * radius, p1.second * radius);
     612            0 :         glVertex2d(p2.first * radius, p2.second * radius);
     613            0 :         glVertex2d(p2.first * iRadius, p2.second * iRadius);
     614              : 
     615            0 :         glVertex2d(p2.first * iRadius, p2.second * iRadius);
     616            0 :         glVertex2d(p1.first * iRadius, p1.second * iRadius);
     617            0 :         glVertex2d(p1.first * radius, p1.second * radius);
     618              : 
     619            0 :         glEnd();
     620              :         p1 = p2;
     621              : #ifdef CHECK_ELEMENTCOUNTER
     622              :         myVertexCounter += 6;
     623              : #endif
     624              :     }
     625            0 : }
     626              : 
     627              : 
     628              : void
     629       399580 : GLHelper::drawTriangleAtEnd(const Position& p1, const Position& p2, double tLength,
     630              :                             double tWidth, const double extraOffset) {
     631       399580 :     const double length = p1.distanceTo(p2);
     632       399580 :     if (length < tLength) {
     633            0 :         tWidth *= length / tLength;
     634              :         tLength = length;
     635              :     }
     636       399580 :     Position rl(PositionVector::positionAtOffset(p1, p2, length - tLength));
     637       399580 :     GLHelper::pushMatrix();
     638       399580 :     glTranslated(rl.x(), rl.y(), 0);
     639       399580 :     glRotated(-GeomHelper::naviDegree(p1.angleTo2D(p2)), 0, 0, 1);
     640       399580 :     glTranslated(0, extraOffset, 0);
     641       399580 :     glBegin(GL_TRIANGLES);
     642       399580 :     glVertex2d(0, tLength);
     643       399580 :     glVertex2d(-tWidth, 0);
     644       399580 :     glVertex2d(+tWidth, 0);
     645       399580 :     glEnd();
     646       399580 :     GLHelper::popMatrix();
     647              : #ifdef CHECK_ELEMENTCOUNTER
     648              :     myVertexCounter += 3;
     649              : #endif
     650       399580 : }
     651              : 
     652              : 
     653              : void
     654     41142465 : GLHelper::setColor(const RGBColor& c) {
     655     41142465 :     glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
     656     41142465 : }
     657              : 
     658              : 
     659              : RGBColor
     660      1920583 : GLHelper::getColor() {
     661              :     GLdouble current[4];
     662      1920583 :     glGetDoublev(GL_CURRENT_COLOR, current);
     663      3841166 :     return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
     664      1920583 :                     static_cast<unsigned char>(current[1] * 255. + 0.5),
     665      1920583 :                     static_cast<unsigned char>(current[2] * 255. + 0.5),
     666      1920583 :                     static_cast<unsigned char>(current[3] * 255. + 0.5));
     667              : }
     668              : 
     669              : 
     670              : void
     671        22107 : GLHelper::resetFont() {
     672        22107 :     glfonsDelete(myFont);
     673        22107 :     myFont = nullptr;
     674        22107 : }
     675              : 
     676              : 
     677              : void
     678            0 : GLHelper::setGL2PS(bool active) {
     679            0 :     myGL2PSActive = active;
     680            0 : }
     681              : 
     682              : 
     683              : void
     684        16313 : GLHelper::drawSpaceOccupancies(const double exaggeration, const Position& pos, const double rotation,
     685              :                                const double width, const double length, const bool vehicle) {
     686              :     // declare colors
     687        16313 :     const RGBColor red(255, 0, 0, 255);
     688        16313 :     const RGBColor green(0, 255, 0, 255);
     689              :     // declare geometry
     690        16313 :     PositionVector geom;
     691        16313 :     const double w = width / 2. - 0.1 * exaggeration;
     692              :     const double h = length;
     693              :     // set geometry
     694        16313 :     geom.push_back(Position(-w, +0, 0.));
     695        16313 :     geom.push_back(Position(+w, +0, 0.));
     696        16313 :     geom.push_back(Position(+w, +h, 0.));
     697        16313 :     geom.push_back(Position(-w, +h, 0.));
     698        16313 :     geom.push_back(Position(-w, +0, 0.));
     699              :     /*
     700              :     geom.push_back(Position(pos.x(), pos.y(), pos.z()));
     701              :     geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y(), pos.z()));
     702              :     geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y() - (*l).second.myLength, pos.z()));
     703              :     geom.push_back(Position(pos.x(), pos.y() - (*l).second.myLength, pos.z()));
     704              :     geom.push_back(Position(pos.x(), pos.y(), pos.z()));
     705              :     */
     706              :     // push matrix
     707        16313 :     GLHelper::pushMatrix();
     708              :     // translate
     709        16313 :     glTranslated(pos.x(), pos.y(), pos.z());
     710              :     // rotate
     711        16313 :     glRotated(rotation, 0, 0, 1);
     712              :     // set color
     713        23164 :     GLHelper::setColor(vehicle ? green : red);
     714              :     // draw box lines
     715        16313 :     GLHelper::drawBoxLines(geom, 0.1 * exaggeration);
     716              :     // pop matrix
     717        16313 :     GLHelper::popMatrix();
     718        16313 : }
     719              : 
     720              : 
     721              : bool
     722      1112254 : GLHelper::initFont() {
     723      1112254 :     if (myFont == nullptr) {
     724         6568 :         myFont = glfonsCreate(2048, 2048, FONS_ZERO_BOTTOMLEFT);
     725         6568 :         if (myFont != nullptr) {
     726         6568 :             const int fontNormal = fonsAddFontMem(myFont, "medium", data_font_Roboto_Medium_ttf, data_font_Roboto_Medium_ttf_len, 0);
     727         6568 :             fonsSetFont(myFont, fontNormal);
     728         6568 :             fonsSetSize(myFont, (float)myFontSize);
     729              :         }
     730              :     }
     731      1112254 :     return myFont != nullptr;
     732              : }
     733              : 
     734              : 
     735              : const std::vector<RGBColor>&
     736            0 : GLHelper::getDottedcontourColors(const int size) {
     737              :     // check if more colors has to be added
     738            0 :     while ((int)myDottedcontourColors.size() < size) {
     739            0 :         if (myDottedcontourColors.empty() || myDottedcontourColors.back() == RGBColor::WHITE) {
     740            0 :             myDottedcontourColors.push_back(RGBColor::BLACK);
     741              :         } else {
     742            0 :             myDottedcontourColors.push_back(RGBColor::WHITE);
     743              :         }
     744              :     }
     745            0 :     return myDottedcontourColors;
     746              : }
     747              : 
     748              : 
     749              : double
     750            0 : GLHelper::getTextWidth(const std::string& text, double size) {
     751            0 :     return size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), nullptr, nullptr);
     752              : }
     753              : 
     754              : 
     755              : void
     756      1112254 : GLHelper::drawText(const std::string& text, const Position& pos, const double layer, const double size,
     757              :                    const RGBColor& col, const double angle, const int align, double width) {
     758      1112254 :     if (width <= 0) {
     759              :         width = size;
     760              :     }
     761      1112254 :     if (!initFont()) {
     762              :         return;
     763              :     }
     764      1112254 :     GLHelper::pushMatrix();
     765      1112254 :     glAlphaFunc(GL_GREATER, 0.5);
     766      1112254 :     glEnable(GL_ALPHA_TEST);
     767              : #ifdef HAVE_GL2PS
     768      1112254 :     if (myGL2PSActive) {
     769            0 :         glRasterPos3d(pos.x(), pos.y(), layer);
     770            0 :         GLfloat color[] = {col.red() / 255.f, col.green() / 255.f, col.blue() / 255.f, col.alpha() / 255.f};
     771            0 :         gl2psTextOptColor(text.c_str(), "Roboto", 10, align == 0 ? GL2PS_TEXT_C : align, (GLfloat) - angle, color);
     772            0 :         GLHelper::popMatrix();
     773              :         return;
     774              :     }
     775              : #endif
     776      1112254 :     glTranslated(pos.x(), pos.y(), layer);
     777      1112254 :     glScaled(width / myFontSize, size / myFontSize, 1.);
     778      1112254 :     glRotated(-angle, 0, 0, 1);
     779      1130664 :     fonsSetAlign(myFont, align == 0 ? FONS_ALIGN_CENTER | FONS_ALIGN_MIDDLE : align);
     780      1112254 :     fonsSetColor(myFont, glfonsRGBA(col.red(), col.green(), col.blue(), col.alpha()));
     781      1112254 :     fonsDrawText(myFont, 0., 0., text.c_str(), nullptr);
     782      1112254 :     GLHelper::popMatrix();
     783              : }
     784              : 
     785              : 
     786              : void
     787            0 : GLHelper::drawTextSettings(
     788              :     const GUIVisualizationTextSettings& settings,
     789              :     const std::string& text, const Position& pos,
     790              :     const double scale,
     791              :     const double angle,
     792              :     const double layer,
     793              :     const int align) {
     794            0 :     drawTextBox(text, pos, layer,
     795              :                 settings.scaledSize(scale),
     796            0 :                 settings.color,
     797            0 :                 settings.bgColor,
     798              :                 RGBColor::INVISIBLE,
     799              :                 angle, 0, 0.2, align);
     800            0 : }
     801              : 
     802              : 
     803              : void
     804            0 : GLHelper::drawTextBox(const std::string& text, const Position& pos,
     805              :                       const double layer, const double size,
     806              :                       const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
     807              :                       const double angle,
     808              :                       const double relBorder,
     809              :                       const double relMargin,
     810              :                       const int align) {
     811            0 :     if (!initFont()) {
     812              :         return;
     813              :     };
     814            0 :     if (bgColor.alpha() != 0) {
     815              :         const double boxAngle = 90;
     816            0 :         const double stringWidth = size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), nullptr, nullptr);
     817            0 :         const double borderWidth = size * relBorder;
     818            0 :         const double boxHeight = size * (0.32 + 0.6 * relMargin);
     819            0 :         const double boxWidth = stringWidth + size * relMargin;
     820            0 :         GLHelper::pushMatrix();
     821            0 :         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     822            0 :         glTranslated(pos.x(), pos.y(), layer);
     823            0 :         glRotated(-angle, 0, 0, 1);
     824            0 :         Position left(-boxWidth * 0.5, 0);
     825            0 :         setColor(borderColor);
     826            0 :         drawBoxLine(left, boxAngle, boxWidth, boxHeight);
     827            0 :         left.add(borderWidth * 1.5, 0);
     828            0 :         setColor(bgColor);
     829            0 :         glTranslated(0, 0, 0.01);
     830            0 :         drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
     831            0 :         GLHelper::popMatrix();
     832              :     }
     833            0 :     drawText(text, pos, layer + 0.02, size, txtColor, angle, align);
     834              : }
     835              : 
     836              : 
     837              : void
     838            0 : GLHelper::drawTextAtEnd(const std::string& text, const PositionVector& shape, double x,
     839              :                         const GUIVisualizationTextSettings& settings, const double scale) {
     840            0 :     GLHelper::pushMatrix();
     841              :     const Position& end = shape.back();
     842            0 :     const Position& f = shape[-2];
     843            0 :     const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
     844            0 :     glTranslated(end.x(), end.y(), 0);
     845            0 :     glRotated(rot, 0, 0, 1);
     846            0 :     drawTextBox(text, Position(x, 0.26), 0,
     847              :                 settings.scaledSize(scale, 0.01),
     848            0 :                 settings.color,
     849            0 :                 settings.bgColor,
     850              :                 RGBColor::INVISIBLE,
     851              :                 180, 0, 0.2);
     852            0 :     GLHelper::popMatrix();
     853            0 : }
     854              : 
     855              : 
     856              : void
     857        79176 : GLHelper::drawCrossTies(const PositionVector& geom, const std::vector<double>& rots,
     858              :                         const std::vector<double>& lengths, double length, double spacing,
     859              :                         double halfWidth, double offset, bool lessDetail) {
     860        79176 :     GLHelper::pushMatrix();
     861              :     // draw on top of of the white area between the rails
     862        79176 :     glTranslated(0, 0, 0.1);
     863        79176 :     int e = (int) geom.size() - 1;
     864       158623 :     for (int i = 0; i < e; ++i) {
     865        79447 :         GLHelper::pushMatrix();
     866        79447 :         glTranslated(geom[i].x(), geom[i].y(), 0.0);
     867        79447 :         glRotated(rots[i], 0, 0, 1);
     868              :         // draw crossing depending of detail
     869        79447 :         if (!lessDetail) {
     870      1122365 :             for (double t = 0; t < lengths[i]; t += spacing) {
     871      1042918 :                 glBegin(GL_QUADS);
     872      1042918 :                 glVertex2d(-halfWidth - offset, -t);
     873      1042918 :                 glVertex2d(-halfWidth - offset, -t - length);
     874      1042918 :                 glVertex2d(halfWidth - offset, -t - length);
     875      1042918 :                 glVertex2d(halfWidth - offset, -t);
     876      1042918 :                 glEnd();
     877              : #ifdef CHECK_ELEMENTCOUNTER
     878              :                 myVertexCounter += 4;
     879              : #endif
     880              :             }
     881              :         } else {
     882              :             // only draw a single rectangle if it's being drawn only for selecting
     883            0 :             glBegin(GL_QUADS);
     884            0 :             glVertex2d(-halfWidth - offset, 0);
     885            0 :             glVertex2d(-halfWidth - offset, -lengths.back());
     886            0 :             glVertex2d(halfWidth - offset, -lengths.back());
     887            0 :             glVertex2d(halfWidth - offset, 0);
     888            0 :             glEnd();
     889              : #ifdef CHECK_ELEMENTCOUNTER
     890              :             myVertexCounter += 4;
     891              : #endif
     892              :         }
     893              :         // pop three draw matrix
     894        79447 :         GLHelper::popMatrix();
     895              :     }
     896        79176 :     GLHelper::popMatrix();
     897        79176 : }
     898              : 
     899              : void
     900        56242 : GLHelper::drawInverseMarkings(const PositionVector& geom,
     901              :                               const std::vector<double>& rots,
     902              :                               const std::vector<double>& lengths,
     903              :                               double maxLength, double spacing,
     904              :                               double halfWidth, bool cl, bool cr, bool lefthand, double scale) {
     905              : 
     906        56242 :     double mw = (halfWidth + SUMO_const_laneMarkWidth * (cl ? 0.6 : 0.2)) * scale;
     907        56242 :     double mw2 = (halfWidth - SUMO_const_laneMarkWidth * (cr ? 0.6 : 0.2)) * scale;
     908        56242 :     if (cl || cr) {
     909        55773 :         if (lefthand) {
     910           12 :             mw *= -1;
     911           12 :             mw2 *= -1;
     912              :         }
     913        55773 :         int e = (int) geom.size() - 1;
     914              :         double offset = 0;
     915       135276 :         for (int i = 0; i < e; ++i) {
     916        79503 :             GLHelper::pushMatrix();
     917        79503 :             glTranslated(geom[i].x(), geom[i].y(), 2.1);
     918        79503 :             glRotated(rots[i], 0, 0, 1);
     919              :             double t;
     920       994153 :             for (t = offset; t < lengths[i]; t += spacing) {
     921       914650 :                 const double length = MIN2((double)maxLength, lengths[i] - t);
     922       914650 :                 glBegin(GL_QUADS);
     923       914650 :                 glVertex2d(-mw, -t);
     924       914650 :                 glVertex2d(-mw, -t - length);
     925       914650 :                 glVertex2d(-mw2, -t - length);
     926       914650 :                 glVertex2d(-mw2, -t);
     927       914650 :                 glEnd();
     928              : #ifdef CHECK_ELEMENTCOUNTER
     929              :                 myVertexCounter += 4;
     930              : #endif
     931       914650 :                 if (!cl || !cr) {
     932              :                     // draw inverse marking between asymmetrical lane markings
     933          551 :                     const double length2 = MIN2((double)6, lengths[i] - t);
     934          551 :                     glBegin(GL_QUADS);
     935          551 :                     glVertex2d(-halfWidth + 0.02, -t - length2);
     936          551 :                     glVertex2d(-halfWidth + 0.02, -t - length);
     937          551 :                     glVertex2d(-halfWidth - 0.02, -t - length);
     938          551 :                     glVertex2d(-halfWidth - 0.02, -t - length2);
     939          551 :                     glEnd();
     940              : #ifdef CHECK_ELEMENTCOUNTER
     941              :                     myVertexCounter += 4;
     942              : #endif
     943              :                 }
     944              :             }
     945        79503 :             offset = t - lengths[i] - spacing;
     946        79503 :             GLHelper::popMatrix();
     947              :         }
     948              :     }
     949        56242 : }
     950              : 
     951              : 
     952              : void
     953            0 : GLHelper::debugVertices(const PositionVector& shape, const GUIVisualizationTextSettings& settings, double scale, double layer) {
     954            0 :     for (int i = 0; i < (int)shape.size(); ++i) {
     955            0 :         drawTextBox(toString(i), shape[i], layer,
     956              :                     settings.scaledSize(scale),
     957            0 :                     settings.color,
     958            0 :                     settings.bgColor,
     959              :                     RGBColor::INVISIBLE,
     960              :                     0, 0, 0.2);
     961              :     }
     962            0 : }
     963              : 
     964              : 
     965              : void
     966            0 : GLHelper::drawBoundary(const GUIVisualizationSettings& s, const Boundary& b) {
     967            0 :     if (s.drawBoundaries) {
     968            0 :         GLHelper::pushMatrix();
     969            0 :         GLHelper::setColor(RGBColor::MAGENTA);
     970              :         // draw on top
     971            0 :         glTranslated(0, 0, 1024);
     972            0 :         drawLine(Position(b.xmin(), b.ymax()), Position(b.xmax(), b.ymax()));
     973            0 :         drawLine(Position(b.xmax(), b.ymax()), Position(b.xmax(), b.ymin()));
     974            0 :         drawLine(Position(b.xmax(), b.ymin()), Position(b.xmin(), b.ymin()));
     975            0 :         drawLine(Position(b.xmin(), b.ymin()), Position(b.xmin(), b.ymax()));
     976            0 :         GLHelper::popMatrix();
     977              :     }
     978            0 : }
     979              : 
     980              : 
     981              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1