38 #define FONTSTASH_IMPLEMENTATION // Expands implementation 40 #pragma warning(disable: 4505) // do not warn about unused functions 43 #pragma GCC diagnostic push 44 #pragma GCC diagnostic ignored "-Wunused-function" 48 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation 53 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees 63 GLdouble* vertex_data[4],
64 GLfloat weight[4], GLdouble** dataOut) {
69 vertex = (GLdouble*)malloc(7 *
sizeof(GLdouble));
71 vertex[0] = coords[0];
72 vertex[1] = coords[1];
73 vertex[2] = coords[2];
87 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
89 for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
91 glVertex2d(p.
x(), p.
y());
95 glVertex2d(p.
x(), p.
y());
106 GLUtesselator* tobj = gluNewTess();
107 gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
108 gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
109 gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
110 gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &
combCallback);
111 gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
112 gluTessBeginPolygon(tobj, NULL);
113 gluTessBeginContour(tobj);
114 double* points =
new double[(v.size() + int(close)) * 3];
116 for (
int i = 0; i != (int)v.size(); ++i) {
117 points[3 * i] = v[i].x();
118 points[3 * i + 1] = v[i].y();
119 points[3 * i + 2] = 0;
120 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
123 const int i = (int)v.size();
124 points[3 * i] = v[0].x();
125 points[3 * i + 1] = v[0].y();
126 points[3 * i + 2] = 0;
127 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
129 gluTessEndContour(tobj);
130 gluTessEndPolygon(tobj);
138 double width,
double offset) {
140 glTranslated(beg.
x(), beg.
y(), 0);
141 glRotated(rot, 0, 0, 1);
143 glVertex2d(-width - offset, 0);
144 glVertex2d(-width - offset, -visLength);
145 glVertex2d(width - offset, -visLength);
146 glVertex2d(width - offset, 0);
154 double rot,
double visLength,
157 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
158 glRotated(rot, 0, 0, 1);
160 glVertex2d(-width, 0);
161 glVertex2d(-width, -visLength);
162 glVertex2d(width, -visLength);
163 glVertex2d(width, 0);
171 double delta = angle2 - angle1;
172 while (delta > 180) {
175 while (delta < -180) {
184 const std::vector<double>& rots,
185 const std::vector<double>& lengths,
186 double width,
int cornerDetail,
double offset) {
188 int e = (int) geom.size() - 1;
189 for (
int i = 0; i < e; i++) {
190 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
193 if (cornerDetail > 0) {
194 for (
int i = 1; i < e; i++) {
196 glTranslated(geom[i].x(), geom[i].y(), 0.1);
202 double angleBeg = -rots[i - 1];
203 double angleEnd = 180 - rots[i];
205 if (angleEnd - angleBeg > 360) {
208 if (angleEnd - angleBeg < -360) {
212 if (angleEnd > angleBeg) {
226 const std::vector<double>& rots,
227 const std::vector<double>& lengths,
228 const std::vector<RGBColor>& cols,
229 double width,
int cornerDetail,
double offset) {
230 int e = (int) geom.size() - 1;
231 for (
int i = 0; i < e; i++) {
233 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
235 if (cornerDetail > 0) {
236 for (
int i = 1; i < e; i++) {
239 glTranslated(geom[i].x(), geom[i].y(), 0);
251 const std::vector<double>& rots,
252 const std::vector<double>& lengths,
254 int minS = (int)
MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
255 for (
int i = 0; i < minS; i++) {
263 int e = (int) geom.size() - 1;
264 for (
int i = 0; i < e; i++) {
278 glTranslated(beg.
x(), beg.
y(), 0);
279 glRotated(rot, 0, 0, 1);
282 glVertex2d(0, -visLength);
290 double rot,
double visLength) {
292 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
293 glRotated(rot, 0, 0, 1);
296 glVertex2d(0, -visLength);
306 int e = (int) v.size() - 1;
307 for (
int i = 0; i < e; ++i) {
308 glVertex2d(v[i].x(), v[i].y());
309 glVertex2d(v[i + 1].x(), v[i + 1].y());
318 int e = (int) v.size() - 1;
319 for (
int i = 0; i < e; ++i) {
321 glVertex2d(v[i].x(), v[i].y());
322 glVertex2d(v[i + 1].x(), v[i + 1].y());
331 glVertex2d(beg.
x(), beg.
y());
332 glVertex2d(end.
x(), end.
y());
364 const double inc = (end - beg) / (
double)steps;
365 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
368 for (
int i = 0; i <= steps; ++i) {
370 glBegin(GL_TRIANGLES);
371 glVertex2d(p1.first * width, p1.second * width);
372 glVertex2d(p2.first * width, p2.second * width);
388 double beg,
double end) {
390 for (
int i = 0; i < 360; i += 10) {
391 double x = (double) sin(
DEG2RAD(i));
392 double y = (double) cos(
DEG2RAD(i));
396 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
397 std::pair<double, double> p1 =
399 for (
int i = (
int)(beg / 10); i < steps && (36.0 / (double) steps * (
double) i) * 10 < end; i++) {
400 const std::pair<double, double>& p2 =
402 glBegin(GL_TRIANGLES);
403 glVertex2d(p1.first * width, p1.second * width);
404 glVertex2d(p2.first * width, p2.second * width);
405 glVertex2d(p2.first * iwidth, p2.second * iwidth);
407 glVertex2d(p2.first * iwidth, p2.second * iwidth);
408 glVertex2d(p1.first * iwidth, p1.second * iwidth);
409 glVertex2d(p1.first * width, p1.second * width);
413 const std::pair<double, double>& p2 =
415 glBegin(GL_TRIANGLES);
416 glVertex2d(p1.first * width, p1.second * width);
417 glVertex2d(p2.first * width, p2.second * width);
418 glVertex2d(p2.first * iwidth, p2.second * iwidth);
420 glVertex2d(p2.first * iwidth, p2.second * iwidth);
421 glVertex2d(p1.first * iwidth, p1.second * iwidth);
422 glVertex2d(p1.first * width, p1.second * width);
429 double tLength,
double tWidth) {
431 if (length < tLength) {
432 tWidth *= length / tLength;
437 glTranslated(rl.
x(), rl.
y(), 0);
439 glBegin(GL_TRIANGLES);
440 glVertex2d(0, tLength);
441 glVertex2d(-tWidth, 0);
442 glVertex2d(+tWidth, 0);
457 glGetDoublev(GL_CURRENT_COLOR, current);
458 return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
459 static_cast<unsigned char>(current[1] * 255. + 0.5),
460 static_cast<unsigned char>(current[2] * 255. + 0.5),
461 static_cast<unsigned char>(current[3] * 255. + 0.5));
488 const double layer,
const double size,
489 const RGBColor& col,
const double angle,
const int align,
498 glAlphaFunc(GL_GREATER, 0.5);
499 glEnable(GL_ALPHA_TEST);
500 glTranslated(pos.
x(), pos.
y(), layer);
502 glRotated(-angle, 0, 0, 1);
512 const double layer,
const double size,
514 const double angle) {
518 double boxAngle = angle + 90;
519 if (boxAngle > 360) {
523 const double borderWidth = size / 20;
524 const double boxHeight = size * 0.8;
525 const double boxWidth = stringWidth + size / 2;
527 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
528 glTranslated(0, 0, layer);
531 left.
sub(boxWidth / 2, 0);
533 left.
add(borderWidth * 1.5, 0);
535 glTranslated(0, 0, 0.01);
536 drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
538 drawText(text, pos, layer + 0.02, size, txtColor, angle);
547 const double rot =
RAD2DEG(atan2((end.
x() - f.
x()), (f.
y() - end.
y())));
548 glTranslated(end.
x(), end.
y(), 0);
549 glRotated(rot, 0, 0, 1);
558 for (
int i = 0; i < (int)shape.size(); ++i) {
FONS_DEF void fonsSetAlign(FONScontext *s, int align)
static std::vector< std::pair< double, double > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
static void resetFont()
to be called when the font context is invalidated
FONS_DEF float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
void add(const Position &pos)
Adds the given position to this one.
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, double size, RGBColor color)
draw text and the end of shape
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb.
static bool initFont()
init myFont
T MIN4(T a, T b, T c, T d)
double x() const
Returns the x-position.
static void debugVertices(const PositionVector &shape, double size, double layer=256)
draw vertex numbers for the given shape (in a random color)
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
void glfonsDelete(FONScontext *ctx)
FONS_DEF void fonsSetFont(FONScontext *s, int font)
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
#define UNUSED_PARAMETER(x)
unsigned char blue() const
Returns the blue-amount of the color.
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
static double naviDegree(const double angle)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
A point in 2D or 3D with translation and scaling methods.
unsigned char alpha() const
Returns the alpha-amount of the color.
double y() const
Returns the y-position.
static int angleLookup(double angleDeg)
normalize angle for lookup in myCircleCoords
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
static struct FONScontext * myFont
Font context.
FONS_DEF void fonsSetColor(FONScontext *s, unsigned int color)
static void drawTextBox(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const double angle=0)
draw Text box with given parameters
void APIENTRY combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
FONS_DEF void fonsSetSize(FONScontext *s, float size)
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
unsigned char data_font_Roboto_Medium_ttf[]
static bool rightTurn(double angle1, double angle2)
whether the road makes a right turn (or goes straight)
#define CIRCLE_RESOLUTION
unsigned int data_font_Roboto_Medium_ttf_len
FONScontext * glfonsCreate(int width, int height, int flags)
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth)
Draws a triangle at the end of the given line.
unsigned char green() const
Returns the green-amount of the color.
FONS_DEF int fonsAddFontMem(FONScontext *s, const char *name, unsigned char *data, int ndata, int freeData)
struct FONScontext FONScontext
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
unsigned char red() const
Returns the red-amount of the color.
FONS_DEF float fonsTextBounds(FONScontext *s, float x, float y, const char *string, const char *end, float *bounds)
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
static RGBColor getColor()
gets the gl-color
void sub(double dx, double dy)
Substracts the given position from this one.