/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GLHelper.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Sept 200218///19// Some methods which help to draw certain geometrical objects in openGL20/****************************************************************************/21#pragma once22#include <config.h>2324#include <vector>25#include <utility>26#include <utils/common/RGBColor.h>27#include <utils/geom/PositionVector.h>28#include <utils/gui/settings/GUIVisualizationSettings.h>293031// ===========================================================================32// class declarations33// ===========================================================================34struct GUIVisualizationTextSettings;353637// ===========================================================================38// class definitions39// ===========================================================================40/**41* @class GLHelper42* @brief Some methods which help to draw certain geometrical objects in openGL43*44* This class offers some static methods for drawing primitives in openGL.45*/46class GLHelper {4748public:49/// @brief Storage for precomputed sin/cos-values describing a circle50static const std::vector<std::pair<double, double> >& getCircleCoords();5152/// @brief normalize angle for lookup in myCircleCoords53static int angleLookup(double angleDeg);5455/// @brief push matrix56static void pushMatrix();5758/// @brief pop matrix59static void popMatrix();6061/// @brief push Name62static void pushName(unsigned int name);6364/// @brief pop Name65static void popName();6667/// @brief get matrix counter68static int getMatrixCounter();6970/// @brief reset matrix counter71static void resetMatrixCounter();7273/// @brief get vertex counter74static int getVertexCounter();7576/// @brief reset vertex counter77static void resetVertexCounter();7879/// @brief check counter matrix (for debug purposes)80static void checkCounterMatrix();8182/// @brief check counter name (for debug purposes)83static void checkCounterName();8485/** @brief Draws a filled polygon described by the list of points86* @note this only works well for convex polygons87*88* @param[in] v The polygon to draw89* @param[in] close Whether the first point shall be appended90*/91static void drawFilledPoly(const PositionVector& v, bool close);929394/** @brief Draws a filled polygon described by the list of points95* @note this works for convex and concave polygons but is slower than96* drawFilledPoly97*98* @param[in] v The polygon to draw99* @param[in] close Whether the first point shall be appended100*/101static void drawFilledPolyTesselated(const PositionVector& v, bool close);102103/** @brief Draws a rectangle line104*105* The line is drawn as a GL_QUADS.106*107* @param[in] center rectangle center108* @param[in] width The width of the rectangle109* @param[in] height The height of the rectangle110*/111static void drawRectangle(const Position& center, const double width, const double height);112113/** @brief Draws a thick line114*115* The line is drawn as a GL_QUADS.116*117* @param[in] beg The begin position of the line118* @param[in] rot The direction the line shall be drawn to (in radiants)119* @param[in] visLength The length of the line120* @param[in] width The width of the line121* @param[in] offset The orthogonal offset122*/123static void drawBoxLine(const Position& beg, double rot,124double visLength, double width, double offset = 0);125126127/** @brief Draws a thick line using the mean of both given points as begin position128*129* The line is drawn as a GL_QUADS.130*131* @param[in] beg1 One of the begin positions of the line to use the mean of132* @param[in] beg2 One of the begin positions of the line to use the mean of133* @param[in] rot The direction the line shall be drawn to (in radiants)134* @param[in] visLength The length of the line135* @param[in] width The width of the line136*/137static void drawBoxLine(const Position& beg1, const Position& beg2,138double rot, double visLength, double width);139140141/** @brief Draws thick lines142*143* Each line is drawn using drawBoxLine.144*145* @param[in] geom The list of begin positions of the lines146* @param[in] rots The directions the lines shall be drawn to (in radiants)147* @param[in] lengths The lengths of the lines148* @param[in] width The width of the lines149* @param[in] cornerDetail Detail level for filling the corners between angled segments150* @param[in] the orthogonal offset151* @see drawBoxLine152*/153static void drawBoxLines(const PositionVector& geom,154const std::vector<double>& rots, const std::vector<double>& lengths,155double width, int cornerDetail = 0, double offset = 0);156157/** @brief Draws thick lines with varying color158*159* Each line is drawn using drawBoxLine.160*161* @param[in] geom The list of begin positions of the lines162* @param[in] rots The directions the lines shall be drawn to (in radiants)163* @param[in] lengths The lengths of the lines164* @param[in] cols The colors of the lines165* @param[in] width The width of the lines166* @param[in] cornerDetail Detail level for filling the corners between angled segments167* @param[in] the orthogonal offset168* @see drawBoxLine169*/170static void drawBoxLines(const PositionVector& geom,171const std::vector<double>& rots, const std::vector<double>& lengths,172const std::vector<RGBColor>& cols,173double width, int cornerDetail = 0, double offset = 0);174175176/** @brief Draws thick lines using the mean of the points given in the point lists as begin positions177*178* Each line is drawn using drawBoxLine.179*180* @param[in] geom1 One of the lists to obtain the lines' begin positions to use the mean of181* @param[in] geom2 One of the lists to obtain the lines' begin positions to use the mean of182* @param[in] rots The directions the lines shall be drawn to (in radiants)183* @param[in] lengths The lengths of the lines184* @param[in] width The width of the lines185* @see drawBoxLine186*/187static void drawBoxLines(const PositionVector& geom1,188const PositionVector& geom2,189const std::vector<double>& rots, const std::vector<double>& lengths,190double width);191192193/** @brief Draws thick lines194*195* Widths and length are computed internally by this method, each line is then196* drawn using drawBoxLine.197*198* @param[in] geom The list of begin positions of the lines199* @param[in] width The width of the lines200* @see drawBoxLine201*/202static void drawBoxLines(const PositionVector& geom, double width);203204205/** @brief Draws a thin line206*207* The line is drawn as a GL_LINES.208*209* @param[in] beg The begin position of the line210* @param[in] rot The direction the line shall be drawn to (in radiants)211* @param[in] visLength The length of the line212*/213static void drawLine(const Position& beg, double rot,214double visLength);215216217/** @brief Draws a thin line using the mean of both given points as begin position218*219* The line is drawn as a GL_LINES.220*221* @param[in] beg1 One of the begin positions of the line to use the mean of222* @param[in] beg2 One of the begin positions of the line to use the mean of223* @param[in] rot The direction the line shall be drawn to (in radiants)224* @param[in] visLength The length of the line225*/226static void drawLine(const Position& beg1, const Position& beg2,227double rot, double visLength);228229230/** @brief Draws a thin line along the given position vector231*232* The line is drawn as a GL_LINES.233*234* @param[in] v The positions vector to use235*/236static void drawLine(const PositionVector& v);237238239/** @brief Draws a thin line along the given position vector with variable color240*241* The line is drawn as a GL_LINES.242*243* @param[in] v The positions vector to use244* @param[in] cols vector with the color of every line245* @note cols must have the same size as v246*/247static void drawLine(const PositionVector& v, const std::vector<RGBColor>& cols);248249250/** @brief Draws a thin line between the two points251*252* The line is drawn as a GL_LINES.253*254* @param[in] beg Begin of the line255* @param[in] end End of the line256*/257static void drawLine(const Position& beg, const Position& end);258259/** @brief Draws a filled circle around (0,0) depending of level of detail260*261* The circle is drawn by calling drawFilledCircle(width, steps, 0, 360).262*263* @param[in] radius The radius of the circle264*/265static void drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius);266267/** @brief Draws a filled circle around (0,0) depending of level of detail268*269* The circle is drawn by calling drawFilledCircle(width, steps, 0, 360).270* @param[in] beg The begin angle in degrees271* @param[in] end The end angle in degrees272*273* @param[in] radius The radius of the circle274*/275static void drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius,276double beg, double end);277278/** @brief Draws a filled circle around (0,0)279*280* The circle is drawn by calling drawFilledCircle(width, steps, 0, 360).281*282* @param[in] radius The radius of the circle283* @param[in] steps The number of steps to divide the circle into284*/285static void drawFilledCircle(const double widradiusth, const int steps = 8);286287/** @brief Draws a filled circle around (0,0)288*289* The circle is drawn use GL_TRIANGLES.290*291* @param[in] radius The radius of the circle292* @param[in] steps The number of steps to divide the circle into293* @param[in] beg The begin angle in degrees294* @param[in] end The end angle in degrees295*/296static void drawFilledCircle(double radius, int steps,297double beg, double end);298299300/** @brief Draws an unfilled circle around (0,0)301*302* The circle is drawn by calling drawOutlineCircle(width, iwidth, steps, 0, 360).303*304* @param[in] radius The (outer) radius of the circle305* @param[in] iRadius The inner radius of the circle306* @param[in] steps The number of steps to divide the circle into307*/308static void drawOutlineCircle(double radius, double iRadius,309int steps = 8);310311312/** @brief Draws an unfilled circle around (0,0)313*314* The circle is drawn use GL_TRIANGLES.315*316* @param[in] radius The (outer) radius of the circle317* @param[in] iRadius The inner radius of the circle318* @param[in] steps The number of steps to divide the circle into319* @param[in] beg The begin angle in degrees320* @param[in] end The end angle in degrees321*/322static void drawOutlineCircle(double radius, double iRadius,323int steps, double beg, double end);324325326/** @brief Draws a triangle at the end of the given line327*328* @param[in] p1 The start of the line at which end the triangle shall be drawn329* @param[in] p2 The end of the line at which end the triangle shall be drawn330* @param[in] tLength The length of the triangle331* @param[in] tWidth The width of the triangle332* @param[in] extraOffset extra offset at end333*/334static void drawTriangleAtEnd(const Position& p1, const Position& p2, double tLength,335double tWidth, const double extraOffset = 0);336337/// @brief Sets the gl-color to this value338static void setColor(const RGBColor& c);339340/// @brief gets the gl-color341static RGBColor getColor();342343/// @brief get required width of text344static double getTextWidth(const std::string& text, double size);345346/* @brief draw Text with given parameters347* when width is not given (negative) the font is scaled proportionally in348* height and width according to size.349*350* align: see foreign/fontstash/fontstash.h for flags351*/352static void drawText(const std::string& text, const Position& pos,353const double layer, const double size,354const RGBColor& col = RGBColor::BLACK,355const double angle = 0,356const int align = 0,357double width = -1);358359static void drawTextSettings(360const GUIVisualizationTextSettings& settings,361const std::string& text, const Position& pos,362const double scale,363const double angle = 0,364const double layer = 2048, // GLO_MAX365const int align = 0); // centered366367/// @brief draw Text box with given parameters368static void drawTextBox(const std::string& text, const Position& pos,369const double layer, const double size,370const RGBColor& txtColor = RGBColor::BLACK,371const RGBColor& bgColor = RGBColor::WHITE,372const RGBColor& borderColor = RGBColor::BLACK,373const double angle = 0,374const double relBorder = 0.05,375const double relMargin = 0.5,376const int align = 0);377378/// @brief draw text and the end of shape379static void drawTextAtEnd(const std::string& text, const PositionVector& shape, double x,380const GUIVisualizationTextSettings& settings, const double scale);381382/// @brief draw crossties for railroads or pedestrian crossings383static void drawCrossTies(const PositionVector& geom,384const std::vector<double>& rots,385const std::vector<double>& lengths,386double length, double spacing, double halfWidth,387double offset, bool lessDetail);388389/// @bried draw the space between markings (in road color)390static void drawInverseMarkings(const PositionVector& geom,391const std::vector<double>& rots,392const std::vector<double>& lengths,393double maxLength, double spacing,394double halfWidth, bool cl, bool cr, bool lefthand, double scale);395396/// @brief draw vertex numbers for the given shape (in a random color)397static void debugVertices(const PositionVector& shape, const GUIVisualizationTextSettings& settings, double scale, double layer = 1024);398399/// @brief Draw a boundary (used for debugging)400static void drawBoundary(const GUIVisualizationSettings& s, const Boundary& b);401402/// @brief to be called when the font context is invalidated403static void resetFont();404405/// @brief set GL2PS406static void setGL2PS(bool active = true);407408/// @brief draw409static void drawSpaceOccupancies(const double exaggeration, const Position& pos, const double rotation,410const double width, const double length, const bool vehicle);411412private:413/// @brief whether the road makes a right turn (or goes straight)414static bool rightTurn(double angle1, double angle2);415416/// @brief init myFont417static bool initFont();418419/// @brief get dotted contour colors (black and white). Vector will be automatically increased if current size is minor than size420static const std::vector<RGBColor>& getDottedcontourColors(const int size);421422/// @brief matrix counter (for debug purposes)423static int myMatrixCounter;424425/// @brief matrix counter (for debug purposes)426static int myVertexCounter;427428/// @brief matrix counter (for debug purposes)429static int myMatrixCounterDebug;430431/// @brief name counter432static int myNameCounter;433434/// @brief Storage for precomputed sin/cos-values describing a circle435static std::vector<std::pair<double, double> > myCircleCoords;436437/// @brief Font context438static struct FONScontext* myFont;439static double myFontSize;440441/// @brief whether we are currently rendering for gl2ps442static bool myGL2PSActive;443444/// @brief static vector with a list of alternated black/white colors (used for contours)445static std::vector<RGBColor> myDottedcontourColors;446};447448449