31 #define FONTSTASH_IMPLEMENTATION // Expands implementation
33 #pragma warning(disable: 4505) // do not warn about unused functions
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wunused-function"
41 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation
50 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
62 GLdouble* vertex_data[4],
63 GLfloat weight[4], GLdouble** dataOut) {
68 vertex = (GLdouble*)malloc(7 *
sizeof(GLdouble));
70 vertex[0] = coords[0];
71 vertex[1] = coords[1];
72 vertex[2] = coords[2];
86 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
88 for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
90 glVertex2d(p.
x(), p.
y());
94 glVertex2d(p.
x(), p.
y());
105 GLUtesselator* tobj = gluNewTess();
106 gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
107 gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
108 gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
109 gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &
combCallback);
110 gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
111 gluTessBeginPolygon(tobj,
nullptr);
112 gluTessBeginContour(tobj);
113 double* points =
new double[(v.size() + int(close)) * 3];
115 for (
int i = 0; i != (int)v.size(); ++i) {
116 points[3 * i] = v[i].x();
117 points[3 * i + 1] = v[i].y();
118 points[3 * i + 2] = 0;
119 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
122 const int i = (int)v.size();
123 points[3 * i] = v[0].x();
124 points[3 * i + 1] = v[0].y();
125 points[3 * i + 2] = 0;
126 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
128 gluTessEndContour(tobj);
129 gluTessEndPolygon(tobj);
137 double width,
double offset) {
139 glTranslated(beg.
x(), beg.
y(), 0);
140 glRotated(rot, 0, 0, 1);
142 glVertex2d(-width - offset, 0);
143 glVertex2d(-width - offset, -visLength);
144 glVertex2d(width - offset, -visLength);
145 glVertex2d(width - offset, 0);
153 double rot,
double visLength,
156 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
157 glRotated(rot, 0, 0, 1);
159 glVertex2d(-width, 0);
160 glVertex2d(-width, -visLength);
161 glVertex2d(width, -visLength);
162 glVertex2d(width, 0);
170 double delta = angle2 - angle1;
171 while (delta > 180) {
174 while (delta < -180) {
183 const std::vector<double>& rots,
184 const std::vector<double>& lengths,
185 double width,
int cornerDetail,
double offset) {
187 int e = (int) geom.size() - 1;
188 for (
int i = 0; i < e; i++) {
189 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
192 if (cornerDetail > 0) {
193 for (
int i = 1; i < e; i++) {
195 glTranslated(geom[i].x(), geom[i].y(), 0.1);
196 double angleBeg = -rots[i - 1];
197 double angleEnd = 180 - rots[i];
199 std::swap(angleBeg, angleEnd);
205 if (angleEnd - angleBeg > 360) {
208 if (angleEnd - angleBeg < -360) {
212 if (angleEnd > angleBeg) {
224 const std::vector<double>& rots,
225 const std::vector<double>& lengths,
226 const std::vector<RGBColor>& cols,
227 double width,
int cornerDetail,
double offset) {
228 int e = (int) geom.size() - 1;
229 for (
int i = 0; i < e; i++) {
231 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
233 if (cornerDetail > 0) {
234 for (
int i = 1; i < e; i++) {
237 glTranslated(geom[i].x(), geom[i].y(), 0);
249 const std::vector<double>& rots,
250 const std::vector<double>& lengths,
252 int minS = (int)
MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
253 for (
int i = 0; i < minS; i++) {
261 int e = (int) geom.size() - 1;
262 for (
int i = 0; i < e; i++) {
276 glTranslated(beg.
x(), beg.
y(), 0);
277 glRotated(rot, 0, 0, 1);
280 glVertex2d(0, -visLength);
288 double rot,
double visLength) {
290 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
291 glRotated(rot, 0, 0, 1);
294 glVertex2d(0, -visLength);
304 int e = (int) v.size() - 1;
305 for (
int i = 0; i < e; ++i) {
306 glVertex2d(v[i].x(), v[i].y());
307 glVertex2d(v[i + 1].x(), v[i + 1].y());
316 int e = (int) v.size() - 1;
317 for (
int i = 0; i < e; ++i) {
319 glVertex2d(v[i].x(), v[i].y());
320 glVertex2d(v[i + 1].x(), v[i + 1].y());
329 glVertex2d(beg.
x(), beg.
y());
330 glVertex2d(end.
x(), end.
y());
353 std::vector<Position>
356 std::vector<Position> result;
357 const double inc = 360 / (double)steps;
359 for (
int i = 0; i <= steps; ++i) {
361 result.push_back(
Position(vertex.first * width, vertex.second * width));
376 const double inc = (end - beg) / (
double)steps;
377 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
380 for (
int i = 0; i <= steps; ++i) {
382 glBegin(GL_TRIANGLES);
383 glVertex2d(p1.first * width, p1.second * width);
384 glVertex2d(p2.first * width, p2.second * width);
400 double beg,
double end) {
402 for (
int i = 0; i < 360; i += 10) {
403 double x = (double) sin(
DEG2RAD(i));
404 double y = (double) cos(
DEG2RAD(i));
408 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
409 std::pair<double, double> p1 =
411 for (
int i = (
int)(beg / 10); i < steps && (36.0 / (double) steps * (
double) i) * 10 < end; i++) {
412 const std::pair<double, double>& p2 =
414 glBegin(GL_TRIANGLES);
415 glVertex2d(p1.first * width, p1.second * width);
416 glVertex2d(p2.first * width, p2.second * width);
417 glVertex2d(p2.first * iwidth, p2.second * iwidth);
419 glVertex2d(p2.first * iwidth, p2.second * iwidth);
420 glVertex2d(p1.first * iwidth, p1.second * iwidth);
421 glVertex2d(p1.first * width, p1.second * width);
425 const std::pair<double, double>& p2 =
427 glBegin(GL_TRIANGLES);
428 glVertex2d(p1.first * width, p1.second * width);
429 glVertex2d(p2.first * width, p2.second * width);
430 glVertex2d(p2.first * iwidth, p2.second * iwidth);
432 glVertex2d(p2.first * iwidth, p2.second * iwidth);
433 glVertex2d(p1.first * iwidth, p1.second * iwidth);
434 glVertex2d(p1.first * width, p1.second * width);
441 double tLength,
double tWidth) {
443 if (length < tLength) {
444 tWidth *= length / tLength;
449 glTranslated(rl.
x(), rl.
y(), 0);
451 glBegin(GL_TRIANGLES);
452 glVertex2d(0, tLength);
453 glVertex2d(-tWidth, 0);
454 glVertex2d(+tWidth, 0);
471 contourback = contourback.
reverse();
472 for (
auto i : contourback) {
473 contourFront.push_back(i);
475 contourFront.push_back(shape.front());
482 glTranslated(0, 0, type + 2);
501 if (closedShape.front() != closedShape.back()) {
502 closedShape.push_back(closedShape.front());
509 glTranslated(0, 0, type + 0.1);
525 if (!s.
drawForSelecting && (frontLaneShape.size() > 0) && (backLaneShape.size() > 0)) {
529 contourFront.
move2side(offsetFrontLaneShape);
530 contourback.
move2side(offsetBackLaneShape);
531 contourback = contourback.
reverse();
532 for (
auto i : contourback) {
533 contourFront.push_back(i);
535 contourFront.push_back(frontLaneShape.front());
541 glTranslated(0, 0, type + 2);
560 shape.push_back(
Position(width / 2, height / 2));
561 shape.push_back(
Position(width / -2, height / 2));
562 shape.push_back(
Position(width / -2, height / -2));
563 shape.push_back(
Position(width / 2, height / -2));
564 shape.push_back(
Position(width / 2, height / 2));
570 glTranslated(center.
x(), center.
y(), type + 2);
574 glRotated(rotation, 0, 0, 1);
576 glTranslated(offsetX, offsetY, 0);
593 shape.move2side(width);
598 glTranslated(0, 0, type + 0.1);
604 shape.move2side(width * -2);
624 glGetDoublev(GL_CURRENT_COLOR, current);
625 return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
626 static_cast<unsigned char>(current[1] * 255. + 0.5),
627 static_cast<unsigned char>(current[2] * 255. + 0.5),
628 static_cast<unsigned char>(current[3] * 255. + 0.5));
653 const std::vector<RGBColor>&
669 const double layer,
const double size,
670 const RGBColor& col,
const double angle,
const int align,
679 glAlphaFunc(GL_GREATER, 0.5);
680 glEnable(GL_ALPHA_TEST);
683 glRasterPos3d(pos.
x(), pos.
y(), layer);
684 GLfloat color[] = {col.
red() / 255.f, col.
green() / 255.f, col.
blue() / 255.f, col.
alpha() / 255.f};
685 gl2psTextOptColor(text.c_str(),
"Roboto", 10, align == 0 ? GL2PS_TEXT_C : align, (GLfloat) - angle, color);
690 glTranslated(pos.
x(), pos.
y(), layer);
692 glRotated(-angle, 0, 0, 1);
703 const std::string& text,
const Position& pos,
706 const double layer) {
718 const double layer,
const double size,
721 const double relBorder,
722 const double relMargin) {
726 if (bgColor.
alpha() != 0) {
727 const double boxAngle = 90;
729 const double borderWidth = size * relBorder;
730 const double boxHeight = size * (0.32 + 0.6 * relMargin);
731 const double boxWidth = stringWidth + size * relMargin;
733 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
734 glTranslated(pos.
x(), pos.
y(), layer);
735 glRotated(-angle, 0, 0, 1);
739 left.
add(borderWidth * 1.5, 0);
741 glTranslated(0, 0, 0.01);
742 drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
745 drawText(text, pos, layer + 0.02, size, txtColor, angle);
754 const double rot =
RAD2DEG(atan2((end.
x() - f.
x()), (f.
y() - end.
y())));
755 glTranslated(end.
x(), end.
y(), 0);
756 glRotated(rot, 0, 0, 1);
764 const std::vector<double>& rots,
765 const std::vector<double>& lengths,
766 double length,
double spacing,
767 double halfWidth,
bool drawForSelecting) {
770 glTranslated(0, 0, 0.1);
771 int e = (int) geom.size() - 1;
772 for (
int i = 0; i < e; ++i) {
774 glTranslated(geom[i].x(), geom[i].y(), 0.0);
775 glRotated(rots[i], 0, 0, 1);
777 if (!drawForSelecting) {
778 for (
double t = 0; t < lengths[i]; t += spacing) {
780 glVertex2d(-halfWidth, -t);
781 glVertex2d(-halfWidth, -t - length);
782 glVertex2d(halfWidth, -t - length);
783 glVertex2d(halfWidth, -t);
789 glVertex2d(-halfWidth, 0);
790 glVertex2d(-halfWidth, -lengths.back());
791 glVertex2d(halfWidth, -lengths.back());
792 glVertex2d(halfWidth, 0);
805 for (
int i = 0; i < (int)shape.size(); ++i) {
816 glTranslated(0, 0, 1024);