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

Generated by: LCOV version 2.0-1