#include "GLDraw.h" namespace Upp { void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, double width, Color color) { if(IsNull(color) || width <= 0) return; static GLCode program(R"( attribute vec4 pos; uniform vec2 offset; uniform vec2 scale; uniform vec2 scale2; uniform vec2 width; void main() { vec2 p = scale * scale2 * pos.xy + offset; // avoiding precision problems vec2 v = scale2 * pos.zw; gl_Position = vec4(p + scale * width * normalize(vec2(-v.y, v.x)), 0, 1); } )", R"( uniform vec4 color; void main() { gl_FragColor = color; } )"); static int ioffset = program["offset"]; static int iscale = program["scale"]; static int iscale2 = program["scale2"]; static int iwidth = program["width"]; static int icolor = program["color"]; program(ioffset, Pointf(dd.vs) * at + dd.off) (iscale, dd.vs) (iscale2, scale) (iwidth, Sizef(width / 2, width / 2)) (icolor, color, dd.alpha) ; if(dd.alpha == 1) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); mesh.Draw(program); } else { glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glEnable(GL_STENCIL_TEST); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glStencilFunc(GL_NEVER, 1, 1); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); mesh.Draw(program); GLDrawStencil(color, dd.alpha); } } void DashPolyline(Vector>& polyline, const Vector& line, const Vector& pattern, double distance) { RTIMING("DashPolyline"); struct LineStore : LinearPathConsumer { Vector>& polyline; void Move(const Pointf& p) override { polyline.Add().Add(p); } void Line(const Pointf& p) override { polyline.Top().Add(p); } LineStore(Vector>& polyline) : polyline(polyline) {} }; LineStore st(polyline); Dasher dasher; dasher.target = &st; dasher.Init(pattern, distance); for(int i = 0; i < line.GetCount(); i++) if(i) dasher.Line(line[i]); else dasher.Move(line[i]); dasher.End(); } };