diff --git a/drape/drape.pro b/drape/drape.pro index 53603cfc78..0678215e26 100644 --- a/drape/drape.pro +++ b/drape/drape.pro @@ -32,6 +32,7 @@ OTHER_FILES += \ shaders/path_symbol_vertex_shader.vsh \ shaders/position_accuracy3d_shader.vsh \ shaders/route_arrow_fragment_shader.fsh \ + shaders/route_dash_fragment_shader.fsh \ shaders/route_fragment_shader.fsh \ shaders/route_vertex_shader.vsh \ shaders/ruler_vertex_shader.vsh \ diff --git a/drape/shaders/route_dash_fragment_shader.fsh b/drape/shaders/route_dash_fragment_shader.fsh new file mode 100644 index 0000000000..0bdcc0af60 --- /dev/null +++ b/drape/shaders/route_dash_fragment_shader.fsh @@ -0,0 +1,39 @@ +varying vec3 v_length; + +#ifdef SAMSUNG_GOOGLE_NEXUS +uniform sampler2D u_colorTex; +#endif + +uniform vec4 u_color; +uniform vec2 u_pattern; + +const float kAntialiasingThreshold = 0.92; + +float GetAlphaFromPattern(float curLen, float dashLen, float gapLen) +{ + float len = dashLen + gapLen; + float offset = fract(curLen / len) * len; + return step(offset, dashLen); +} + +void main(void) +{ +#ifdef SAMSUNG_GOOGLE_NEXUS + // Because of a bug in OpenGL driver on Samsung Google Nexus this workaround is here. + const float kFakeColorScalar = 0.0; + lowp vec4 fakeColor = texture2D(u_colorTex, vec2(0.0, 0.0)) * kFakeColorScalar; +#endif + + vec4 color = u_color; + if (v_length.x < v_length.z) + color.a = 0.0; + else + color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y))) * + GetAlphaFromPattern(v_length.x, u_pattern.x, u_pattern.y); + +#ifdef SAMSUNG_GOOGLE_NEXUS + gl_FragColor = color + fakeColor; +#else + gl_FragColor = color; +#endif +} diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt index 54b94162c4..ab22b90d05 100644 --- a/drape/shaders/shader_index.txt +++ b/drape/shaders/shader_index.txt @@ -15,6 +15,7 @@ ACCURACY_PROGRAM position_accuracy3d_shader.vsh texturing_fragment_shader.fsh MY_POSITION_PROGRAM my_position_shader.vsh texturing_fragment_shader.fsh BOOKMARK_PROGRAM user_mark.vsh texturing_fragment_shader.fsh ROUTE_PROGRAM route_vertex_shader.vsh route_fragment_shader.fsh +ROUTE_DASH_PROGRAM route_vertex_shader.vsh route_dash_fragment_shader.fsh ROUTE_ARROW_PROGRAM route_vertex_shader.vsh route_arrow_fragment_shader.fsh TRACK_POINT_PROGRAM trackpoint_vertex_shader.vsh trackpoint_fragment_shader.fsh DEBUG_RECT_PROGRAM debug_rect_vertex_shader.vsh debug_rect_fragment_shader.fsh diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 9ee46fe45b..cf0c5818b2 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -217,7 +217,8 @@ void BackendRenderer::AcceptMessage(ref_ptr message) case Message::AddRoute: { ref_ptr msg = message; - m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(), msg->GetColor(), m_texMng); + m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(), + msg->GetColor(), msg->GetPattern(), m_texMng); break; } case Message::CacheRouteSign: diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 3a5e767d0f..ecd729ae7a 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -344,10 +344,10 @@ bool DrapeEngine::GetMyPosition(m2::PointD & myPosition) } void DrapeEngine::AddRoute(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color) + df::ColorConstant color, df::RoutePattern pattern) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(routePolyline, turns, color), + make_unique_dp(routePolyline, turns, color, pattern), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index dad1982e66..8799059452 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -3,8 +3,9 @@ #include "drape_frontend/backend_renderer.hpp" #include "drape_frontend/color_constants.hpp" #include "drape_frontend/frontend_renderer.hpp" -#include "drape_frontend/threads_commutator.hpp" +#include "drape_frontend/route_shape.hpp" #include "drape_frontend/selection_shape.hpp" +#include "drape_frontend/threads_commutator.hpp" #include "drape/pointers.hpp" #include "drape/texture_manager.hpp" @@ -121,7 +122,7 @@ public: SelectionShape::ESelectedObject GetSelectedObject(); void AddRoute(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color); + df::ColorConstant color, df::RoutePattern pattern = df::RoutePattern()); void RemoveRoute(bool deactivateFollowing); void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, double rotationAngle, double angleFOV); void DeactivateRouteFollowing(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 783ee969f3..1f1ffa9286 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -590,7 +590,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) { auto recacheRouteMsg = make_unique_dp(routeData->m_sourcePolyline, routeData->m_sourceTurns, - routeData->m_color); + routeData->m_color, + routeData->m_pattern); m_routeRenderer->Clear(true /* keepDistanceFromBegin */); m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, move(recacheRouteMsg), MessagePriority::Normal); diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 508e34119d..4122e85397 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -544,10 +544,12 @@ private: class AddRouteMessage : public Message { public: - AddRouteMessage(m2::PolylineD const & routePolyline, vector const & turns, df::ColorConstant color) + AddRouteMessage(m2::PolylineD const & routePolyline, vector const & turns, + df::ColorConstant color, df::RoutePattern const & pattern) : m_routePolyline(routePolyline) , m_color(color) , m_turns(turns) + , m_pattern(pattern) {} Type GetType() const override { return Message::AddRoute; } @@ -555,11 +557,13 @@ public: m2::PolylineD const & GetRoutePolyline() { return m_routePolyline; } df::ColorConstant GetColor() const { return m_color; } vector const & GetTurns() const { return m_turns; } + df::RoutePattern const & GetPattern() const { return m_pattern; } private: m2::PolylineD m_routePolyline; df::ColorConstant m_color; vector m_turns; + df::RoutePattern m_pattern; }; class CacheRouteSignMessage : public Message diff --git a/drape_frontend/route_builder.cpp b/drape_frontend/route_builder.cpp index 1051b4ddda..cb49392083 100644 --- a/drape_frontend/route_builder.cpp +++ b/drape_frontend/route_builder.cpp @@ -12,7 +12,8 @@ RouteBuilder::RouteBuilder(TFlushRouteFn const & flushRouteFn, {} void RouteBuilder::Build(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, ref_ptr textures) + df::ColorConstant color, df::RoutePattern const & pattern, + ref_ptr textures) { CommonViewParams params; params.m_minVisibleScale = 1; @@ -23,6 +24,7 @@ void RouteBuilder::Build(m2::PolylineD const & routePolyline, vector con routeData->m_color = color; routeData->m_sourcePolyline = routePolyline; routeData->m_sourceTurns = turns; + routeData->m_pattern = pattern; RouteShape(params).Draw(textures, *routeData.get()); // Flush route geometry. diff --git a/drape_frontend/route_builder.hpp b/drape_frontend/route_builder.hpp index e6a34dab44..8bcf046af0 100644 --- a/drape_frontend/route_builder.hpp +++ b/drape_frontend/route_builder.hpp @@ -23,7 +23,8 @@ public: TFlushRouteSignFn const & flushRouteSignFn); void Build(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, ref_ptr textures); + df::ColorConstant color, df::RoutePattern const & pattern, + ref_ptr textures); void BuildSign(m2::PointD const & pos, bool isStart, bool isValid, ref_ptr textures); diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 9336876dac..446d89b27a 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -183,10 +183,18 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptrm_color)); uniforms.SetFloatValue("u_color", color.r, color.g, color.b, alpha); - uniforms.SetFloatValue("u_routeParams", halfWidth, halfWidth * screen.GetScale(), m_distanceFromBegin); + double const screenScale = screen.GetScale(); + uniforms.SetFloatValue("u_routeParams", halfWidth, halfWidth * screenScale, m_distanceFromBegin); + + if (m_routeData->m_pattern.m_isDashed) + { + uniforms.SetFloatValue("u_pattern", halfWidth * m_routeData->m_pattern.m_dashLength * screenScale, + halfWidth * m_routeData->m_pattern.m_gapLength * screenScale); + } // set up shaders and apply uniforms - ref_ptr prg = mng->GetProgram(gpu::ROUTE_PROGRAM); + ref_ptr prg = mng->GetProgram(m_routeData->m_pattern.m_isDashed ? + gpu::ROUTE_DASH_PROGRAM : gpu::ROUTE_PROGRAM); prg->Bind(); dp::ApplyState(state, prg); dp::ApplyUniforms(uniforms, prg); diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index 77f8b598cb..8d0155631e 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -18,6 +18,21 @@ namespace df double const kArrowSize = 0.001; +struct RoutePattern +{ + bool m_isDashed = false; + double m_dashLength = 0.0; + double m_gapLength = 0.0; + + RoutePattern() = default; + + RoutePattern(double dashLength, double gapLength) + : m_isDashed(true) + , m_dashLength(dashLength) + , m_gapLength(gapLength) + {} +}; + struct RouteJoinBounds { double m_start = 0; @@ -50,6 +65,7 @@ struct RouteData double m_length; RouteRenderProperty m_route; vector> m_arrows; + RoutePattern m_pattern; }; struct RouteSignData diff --git a/map/framework.cpp b/map/framework.cpp index 2fd2cacd9a..f69de12942 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2345,12 +2345,19 @@ void Framework::InsertRoute(Route const & route) route.GetTurnsDistances(turns); df::ColorConstant routeColor = df::Route; + df::RoutePattern pattern; if (m_currentRouterType == RouterType::Pedestrian) + { routeColor = df::RoutePedestrian; + pattern = df::RoutePattern(4.0, 2.0); + } else if (m_currentRouterType == RouterType::Bicycle) + { routeColor = df::RouteBicycle; + pattern = df::RoutePattern(8.0, 2.0); + } - m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor); + m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor, pattern); } void Framework::CheckLocationForRouting(GpsInfo const & info)