diff --git a/drape/color.hpp b/drape/color.hpp index bd51571259..f000f2becd 100644 --- a/drape/color.hpp +++ b/drape/color.hpp @@ -28,9 +28,9 @@ struct Color bool operator< (Color const & other) const { return m_rgba < other.m_rgba; } Color operator*(float s) const { - return Color(my::clamp(static_cast(GetRed() * s), 0, 255), - my::clamp(static_cast(GetGreen() * s), 0, 255), - my::clamp(static_cast(GetBlue() * s), 0, 255), + return Color(static_cast(my::clamp(GetRedF() * s, 0.0f, 1.0f) * 255.0f), + static_cast(my::clamp(GetGreenF() * s, 0.0f, 1.0f) * 255.0f), + static_cast(my::clamp(GetBlueF() * s, 0.0f, 1.0f) * 255.0f), GetAlfa()); } diff --git a/drape/shaders/route_dash_fragment_shader.fsh b/drape/shaders/route_dash_fragment_shader.fsh index 0bdcc0af60..25a8768f8f 100644 --- a/drape/shaders/route_dash_fragment_shader.fsh +++ b/drape/shaders/route_dash_fragment_shader.fsh @@ -1,4 +1,5 @@ varying vec3 v_length; +varying vec4 v_color; #ifdef SAMSUNG_GOOGLE_NEXUS uniform sampler2D u_colorTex; diff --git a/drape/shaders/route_fragment_shader.fsh b/drape/shaders/route_fragment_shader.fsh index 73f0300906..4b6d10b2b6 100644 --- a/drape/shaders/route_fragment_shader.fsh +++ b/drape/shaders/route_fragment_shader.fsh @@ -1,13 +1,18 @@ varying vec3 v_length; +varying vec4 v_color; #ifdef SAMSUNG_GOOGLE_NEXUS uniform sampler2D u_colorTex; #endif uniform vec4 u_color; +uniform vec4 u_routeParams; const float kAntialiasingThreshold = 0.92; +const float kOutlineThreshold1 = 0.4; +const float kOutlineThreshold2 = 0.3; + void main(void) { #ifdef SAMSUNG_GOOGLE_NEXUS @@ -16,11 +21,21 @@ void main(void) 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 + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); + if (v_length.x >= v_length.z) + { + if (u_routeParams.w > 0.0) + { + color = mix(u_color, vec4(v_color.rgb, 1.0), v_color.a); + color = mix(color, u_color, step(kOutlineThreshold1, abs(v_length.y))); + color = mix(color, u_color, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_length.y))); + } + else + { + color = u_color; + } color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y))); + } #ifdef SAMSUNG_GOOGLE_NEXUS gl_FragColor = color + fakeColor; diff --git a/drape/shaders/route_vertex_shader.vsh b/drape/shaders/route_vertex_shader.vsh index 0c8cd4f0e7..46949f532e 100644 --- a/drape/shaders/route_vertex_shader.vsh +++ b/drape/shaders/route_vertex_shader.vsh @@ -1,14 +1,16 @@ attribute vec3 a_position; attribute vec2 a_normal; attribute vec3 a_length; +attribute vec4 a_color; uniform mat4 modelView; uniform mat4 projection; uniform mat4 pivotTransform; -uniform vec3 u_routeParams; +uniform vec4 u_routeParams; varying vec3 v_length; +varying vec4 v_color; void main(void) { @@ -29,6 +31,7 @@ void main(void) } v_length = vec3(len, u_routeParams.z); + v_color = a_color; vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * projection; float w = pos.w; pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; diff --git a/drape/utils/vertex_decl.cpp b/drape/utils/vertex_decl.cpp index 462888f83f..a80a9a9149 100644 --- a/drape/utils/vertex_decl.cpp +++ b/drape/utils/vertex_decl.cpp @@ -153,12 +153,14 @@ dp::BindingInfo RouteBindingInit() { static_assert(sizeof(RouteVertex) == sizeof(RouteVertex::TPosition) + sizeof(RouteVertex::TNormal) + - sizeof(RouteVertex::TLength), ""); + sizeof(RouteVertex::TLength) + + sizeof(RouteVertex::TColor), ""); - dp::BindingFiller filler(3); + dp::BindingFiller filler(4); filler.FillDecl("a_position"); filler.FillDecl("a_normal"); filler.FillDecl("a_length"); + filler.FillDecl("a_color"); return filler.m_info; } @@ -356,12 +358,15 @@ RouteVertex::RouteVertex() : m_position(0.0, 0.0, 0.0) , m_normal(0.0, 0.0) , m_length(0.0, 0.0, 0.0) + , m_color(0.0, 0.0, 0.0, 0.0) {} -RouteVertex::RouteVertex(TPosition const & position, TNormal const & normal, TLength const & length) +RouteVertex::RouteVertex(TPosition const & position, TNormal const & normal, + TLength const & length, TColor const & color) : m_position(position) , m_normal(normal) , m_length(length) + , m_color(color) {} dp::BindingInfo const & RouteVertex::GetBindingInfo() diff --git a/drape/utils/vertex_decl.hpp b/drape/utils/vertex_decl.hpp index 3d47c1303a..b0ff4955ba 100644 --- a/drape/utils/vertex_decl.hpp +++ b/drape/utils/vertex_decl.hpp @@ -143,14 +143,17 @@ struct DashedLineVertex : BaseVertex struct RouteVertex : BaseVertex { - typedef glsl::vec3 TLength; + using TLength = glsl::vec3; + using TColor = glsl::vec4; RouteVertex(); - RouteVertex(TPosition const & position, TNormal const & normal, TLength const & length); + RouteVertex(TPosition const & position, TNormal const & normal, + TLength const & length, TColor const & color); TPosition m_position; TNormal m_normal; TLength m_length; + TColor m_color; static dp::BindingInfo const & GetBindingInfo(); }; diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index b535393edd..733d52c07d 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -258,8 +258,8 @@ void BackendRenderer::AcceptMessage(ref_ptr message) case Message::AddRoute: { ref_ptr msg = message; - m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(), - msg->GetColor(), msg->GetPattern(), m_texMng, msg->GetRecacheId()); + m_routeBuilder->Build(msg->GetRoutePolyline(), msg->GetTurns(), msg->GetColor(), + msg->GetTraffic(), msg->GetPattern(), m_texMng, msg->GetRecacheId()); break; } diff --git a/drape_frontend/color_constants.cpp b/drape_frontend/color_constants.cpp index c2a0ee7e9a..643a8c910b 100644 --- a/drape_frontend/color_constants.cpp +++ b/drape_frontend/color_constants.cpp @@ -25,10 +25,10 @@ unordered_map> kColorConstants = { TrackPlaneSpeed, dp::Color(10, 196, 255, 255) }, { TrackUnknownDistance, dp::Color(97, 97, 97, 255) }, { TrafficG0, dp::Color(180, 25, 25, 255) }, - { TrafficG1, dp::Color(250, 190, 45, 127) }, - { TrafficG2, dp::Color(250, 190, 45, 127) }, - { TrafficG3, dp::Color(230, 60, 55, 255) }, - { TrafficG4, dp::Color(230, 60, 55, 255) }, + { TrafficG1, dp::Color(230, 60, 55, 255) }, + { TrafficG2, dp::Color(230, 60, 55, 255) }, + { TrafficG3, dp::Color(250, 190, 45, 127) }, + { TrafficG4, dp::Color(250, 190, 45, 127) }, { TrafficG5, dp::Color(55, 165, 55, 255) }, { TrafficTempBlock, dp::Color(75, 75, 75, 255) }, { TrafficUnknown, dp::Color(0, 0, 0, 0) }, @@ -51,12 +51,12 @@ unordered_map> kColorConstants = { TrackCarSpeed, dp::Color(255, 202, 40, 255) }, { TrackPlaneSpeed, dp::Color(255, 245, 160, 255) }, { TrackUnknownDistance, dp::Color(150, 150, 150, 255) }, - { TrafficG0, dp::Color(25, 75, 25, 255) }, - { TrafficG1, dp::Color(115, 80, 0, 127) }, - { TrafficG2, dp::Color(115, 80, 0, 127) }, - { TrafficG3, dp::Color(105, 20, 0, 255) }, - { TrafficG4, dp::Color(105, 20, 0, 255) }, - { TrafficG5, dp::Color(70, 15, 0, 255) }, + { TrafficG0, dp::Color(70, 15, 0, 255) }, + { TrafficG1, dp::Color(105, 20, 0, 255) }, + { TrafficG2, dp::Color(105, 20, 0, 255) }, + { TrafficG3, dp::Color(115, 80, 0, 127) }, + { TrafficG4, dp::Color(115, 80, 0, 127) }, + { TrafficG5, dp::Color(25, 75, 25, 255) }, { TrafficTempBlock, dp::Color(40, 40, 40, 255) }, { TrafficUnknown, dp::Color(0, 0, 0, 0) }, { TrafficArrowLight, dp::Color(170, 170, 170, 255) }, diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index d81085387e..2c1f601a8d 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -390,10 +390,11 @@ bool DrapeEngine::GetMyPosition(m2::PointD & myPosition) } void DrapeEngine::AddRoute(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern pattern) + df::ColorConstant color, vector const & traffic, + df::RoutePattern pattern) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(routePolyline, turns, color, pattern), + make_unique_dp(routePolyline, turns, color, traffic, pattern), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index ec90aea5f5..a4bce5e70a 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -134,7 +134,8 @@ public: SelectionShape::ESelectedObject GetSelectedObject(); void AddRoute(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern pattern = df::RoutePattern()); + df::ColorConstant color, vector const & traffic, + df::RoutePattern pattern = df::RoutePattern()); void RemoveRoute(bool deactivateFollowing); void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, bool enableAutoZoom); void DeactivateRouteFollowing(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 79a641508b..3d282d63f2 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -834,11 +834,9 @@ void FrontendRenderer::UpdateGLResources() auto const & routeData = m_routeRenderer->GetRouteData(); if (routeData != nullptr) { - auto recacheRouteMsg = make_unique_dp(routeData->m_sourcePolyline, - routeData->m_sourceTurns, - routeData->m_color, - routeData->m_pattern, - m_lastRecacheRouteId); + auto recacheRouteMsg = make_unique_dp(routeData->m_sourcePolyline, routeData->m_sourceTurns, + routeData->m_color, routeData->m_traffic, + routeData->m_pattern, m_lastRecacheRouteId); m_routeRenderer->ClearGLDependentResources(); m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, move(recacheRouteMsg), MessagePriority::Normal); @@ -1134,12 +1132,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (m_framebuffer->IsSupported()) { - if (m_trafficRenderer->HasRenderData()) - { - GLFunctions::glClearDepth(); - GLFunctions::glEnable(gl_const::GLDepthTest); - m_trafficRenderer->RenderTraffic(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); - } + RenderTrafficAndRouteLayer(modelView); m_framebuffer->Enable(); GLFunctions::glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -1153,12 +1146,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) { GLFunctions::glClearDepth(); Render3dLayer(modelView); - - if (m_trafficRenderer->HasRenderData()) - { - GLFunctions::glClearDepth(); - m_trafficRenderer->RenderTraffic(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); - } + RenderTrafficAndRouteLayer(modelView); } GLFunctions::glDisable(gl_const::GLDepthTest); @@ -1175,8 +1163,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (m_selectionShape != nullptr && m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK) m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); - m_routeRenderer->RenderRoute(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - RenderUserMarksLayer(modelView); m_routeRenderer->RenderRouteSigns(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); @@ -1228,6 +1214,22 @@ void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) RenderSingleGroup(modelView, make_ref(group)); } +void FrontendRenderer::RenderTrafficAndRouteLayer(ScreenBase const & modelView) +{ + if (m_trafficRenderer->HasRenderData()) + { + float const opacity = (m_routeRenderer->GetRouteData() != nullptr) ? 0.5f : 1.0f; + GLFunctions::glClearDepth(); + GLFunctions::glEnable(gl_const::GLDepthTest); + m_trafficRenderer->RenderTraffic(modelView, m_currentZoomLevel, opacity, + make_ref(m_gpuProgramManager), m_generalUniforms); + } + + GLFunctions::glDisable(gl_const::GLDepthTest); + m_routeRenderer->RenderRoute(modelView, m_trafficRenderer->HasRenderData(), + make_ref(m_gpuProgramManager), m_generalUniforms); +} + void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView) { double const kExtension = 1.1; diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index aef7936f35..a5ff64bd73 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -174,6 +174,7 @@ private: void Render3dLayer(ScreenBase const & modelView); void RenderOverlayLayer(ScreenBase const & modelView); void RenderUserMarksLayer(ScreenBase const & modelView); + void RenderTrafficAndRouteLayer(ScreenBase const & modelView); ////// ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged); void PrepareScene(ScreenBase const & modelView); diff --git a/drape_frontend/line_shape_helper.cpp b/drape_frontend/line_shape_helper.cpp index 160dcdf3a7..f400cb5784 100644 --- a/drape_frontend/line_shape_helper.cpp +++ b/drape_frontend/line_shape_helper.cpp @@ -87,10 +87,14 @@ void CalculateTangentAndNormals(glsl::vec2 const & pt0, glsl::vec2 const & pt1, rightNormal = -leftNormal; } -void ConstructLineSegments(vector const & path, vector & segments) +void ConstructLineSegments(vector const & path, vector const & segmentsColors, + vector & segments) { ASSERT_LESS(1, path.size(), ()); + if (!segmentsColors.empty()) + ASSERT_EQUAL(segmentsColors.size() + 1, path.size(), ()); + m2::PointD prevPoint = path[0]; for (size_t i = 1; i < path.size(); ++i) { @@ -109,6 +113,8 @@ void ConstructLineSegments(vector const & path, vector segment.m_leftNormals[StartPoint] = segment.m_leftNormals[EndPoint] = segment.m_leftBaseNormal; segment.m_rightNormals[StartPoint] = segment.m_rightNormals[EndPoint] = segment.m_rightBaseNormal; + if (!segmentsColors.empty()) + segment.m_color = segmentsColors[i - 1]; prevPoint = path[i]; } diff --git a/drape_frontend/line_shape_helper.hpp b/drape_frontend/line_shape_helper.hpp index 1b78e6a68b..ba64cdf122 100644 --- a/drape_frontend/line_shape_helper.hpp +++ b/drape_frontend/line_shape_helper.hpp @@ -36,6 +36,7 @@ struct LineSegment glsl::vec2 m_rightWidthScalar[PointsCount]; bool m_hasLeftJoin[PointsCount]; bool m_generateJoin; + glsl::vec4 m_color; LineSegment(glsl::vec2 const & p1, glsl::vec2 const & p2) { @@ -44,6 +45,7 @@ struct LineSegment m_leftWidthScalar[StartPoint] = m_leftWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); m_rightWidthScalar[StartPoint] = m_rightWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); m_hasLeftJoin[StartPoint] = m_hasLeftJoin[EndPoint] = true; + m_color = glsl::vec4(0.0f, 0.0f, 0.0f, 0.0f); m_generateJoin = true; } }; @@ -52,7 +54,8 @@ void CalculateTangentAndNormals(glsl::vec2 const & pt0, glsl::vec2 const & pt1, glsl::vec2 & tangent, glsl::vec2 & leftNormal, glsl::vec2 & rightNormal); -void ConstructLineSegments(vector const & path, vector & segments); +void ConstructLineSegments(vector const & path, vector const & segmentsColors, + vector & segments); void UpdateNormals(LineSegment * segment, LineSegment * prevSegment, LineSegment * nextSegment); diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index c460b16c6e..849dd70f7a 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -603,16 +603,19 @@ class AddRouteMessage : public Message { public: AddRouteMessage(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern const & pattern) - : AddRouteMessage(routePolyline, turns, color, pattern, -1 /* invalid recache id */) + df::ColorConstant color, vector const & traffic, + df::RoutePattern const & pattern) + : AddRouteMessage(routePolyline, turns, color, traffic, pattern, -1 /* invalid recache id */) {} AddRouteMessage(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern const & pattern, int recacheId) + df::ColorConstant color, vector const & traffic, + df::RoutePattern const & pattern, int recacheId) : m_routePolyline(routePolyline) , m_color(color) , m_turns(turns) , m_pattern(pattern) + , m_traffic(traffic) , m_recacheId(recacheId) {} @@ -622,6 +625,7 @@ public: df::ColorConstant GetColor() const { return m_color; } vector const & GetTurns() const { return m_turns; } df::RoutePattern const & GetPattern() const { return m_pattern; } + vector const & GetTraffic() const { return m_traffic; } int GetRecacheId() const { return m_recacheId; } private: @@ -629,6 +633,7 @@ private: df::ColorConstant m_color; vector m_turns; df::RoutePattern m_pattern; + vector m_traffic; int const m_recacheId; }; diff --git a/drape_frontend/route_builder.cpp b/drape_frontend/route_builder.cpp index e167ea8003..9d13b149f5 100644 --- a/drape_frontend/route_builder.cpp +++ b/drape_frontend/route_builder.cpp @@ -14,14 +14,16 @@ RouteBuilder::RouteBuilder(TFlushRouteFn const & flushRouteFn, {} void RouteBuilder::Build(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern const & pattern, - ref_ptr textures, int recacheId) + df::ColorConstant color, vector const & traffic, + df::RoutePattern const & pattern, ref_ptr textures, + int recacheId) { drape_ptr routeData = make_unique_dp(); routeData->m_routeIndex = m_routeIndex++; routeData->m_color = color; routeData->m_sourcePolyline = routePolyline; routeData->m_sourceTurns = turns; + routeData->m_traffic = traffic; routeData->m_pattern = pattern; routeData->m_pivot = routePolyline.GetLimitRect().Center(); routeData->m_recacheId = recacheId; diff --git a/drape_frontend/route_builder.hpp b/drape_frontend/route_builder.hpp index 9c74653ce1..f229cfd888 100644 --- a/drape_frontend/route_builder.hpp +++ b/drape_frontend/route_builder.hpp @@ -6,6 +6,8 @@ #include "drape/pointers.hpp" #include "drape/texture_manager.hpp" +#include "traffic/speed_groups.hpp" + #include "geometry/polyline2d.hpp" #include "std/function.hpp" @@ -26,8 +28,9 @@ public: TFlushRouteArrowsFn const & flushRouteArrowsFn); void Build(m2::PolylineD const & routePolyline, vector const & turns, - df::ColorConstant color, df::RoutePattern const & pattern, - ref_ptr textures, int recacheId); + df::ColorConstant color, vector const & traffic, + df::RoutePattern const & pattern, ref_ptr textures, + int recacheId); void BuildArrows(int routeIndex, vector const & borders, ref_ptr textures, int recacheId); diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index f763db4e08..d03aa59d4b 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -35,6 +35,8 @@ uint8_t const kAlphaValue[] = 204, 204, 204, 204, 190, 180, 170, 160, 140, 120 }; +uint8_t const kAlphaValueForTraffic = 204; + int const kArrowAppearingZoomLevel = 14; int const kInvalidGroup = -1; @@ -228,7 +230,8 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCall } } -void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr mng, +void RouteRenderer::RenderRoute(ScreenBase const & screen, bool trafficShown, + ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { if (!m_routeData || m_routeData->m_route.m_buckets.empty()) @@ -244,9 +247,11 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptrm_color)); - uniforms.SetFloatValue("u_color", color.r, color.g, color.b, m_currentAlpha); + uniforms.SetFloatValue("u_color", color.r, color.g, color.b, + trafficShown ? kAlphaValueForTraffic : m_currentAlpha); double const screenScale = screen.GetScale(); - uniforms.SetFloatValue("u_routeParams", m_currentHalfWidth, m_currentHalfWidth * screenScale, m_distanceFromBegin); + uniforms.SetFloatValue("u_routeParams", m_currentHalfWidth, m_currentHalfWidth * screenScale, + m_distanceFromBegin, trafficShown ? 1.0f : 0.0f); if (m_routeData->m_pattern.m_isDashed) { diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index dc965c7402..c8d2e283e1 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -19,7 +19,8 @@ public: void UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCallback const & callback); - void RenderRoute(ScreenBase const & screen, ref_ptr mng, + void RenderRoute(ScreenBase const & screen, bool trafficShown, + ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); void RenderRouteSigns(ScreenBase const & screen, ref_ptr mng, diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index dc62216342..6a3f4464e4 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -2,6 +2,7 @@ #include "drape_frontend/line_shape_helper.hpp" #include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/tile_utils.hpp" +#include "drape_frontend/traffic_generator.hpp" #include "drape/attribute_provider.hpp" #include "drape/batcher.hpp" @@ -10,6 +11,8 @@ #include "drape/shader_def.hpp" #include "drape/texture_manager.hpp" +#include "indexer/map_style_reader.hpp" + #include "base/logging.hpp" namespace df @@ -81,15 +84,16 @@ void GenerateJoinsTriangles(glsl::vec3 const & pivot, vector const & float const kEps = 1e-5; size_t const trianglesCount = normals.size() / 3; float const side = isLeft ? kLeftSide : kRightSide; + glsl::vec4 const color(0.0f, 0.0f, 0.0f, 0.0f); for (int j = 0; j < trianglesCount; j++) { glsl::vec3 const len1 = glsl::vec3(length.x, length.y, glsl::length(normals[3 * j]) < kEps ? kCenter : side); glsl::vec3 const len2 = glsl::vec3(length.x, length.y, glsl::length(normals[3 * j + 1]) < kEps ? kCenter : side); glsl::vec3 const len3 = glsl::vec3(length.x, length.y, glsl::length(normals[3 * j + 2]) < kEps ? kCenter : side); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j], len1)); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 1], len2)); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 2], len3)); + joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j], len1, color)); + joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 1], len2, color)); + joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 2], len3, color)); } } @@ -123,6 +127,7 @@ void GenerateArrowsTriangles(glsl::vec4 const & pivot, vector const } // namespace void RouteShape::PrepareGeometry(vector const & path, m2::PointD const & pivot, + vector const & segmentsColors, TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, double & outputLength) { @@ -131,7 +136,7 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con // Construct segments. vector segments; segments.reserve(path.size() - 1); - ConstructLineSegments(path, segments); + ConstructLineSegments(path, segmentsColors, segments); // Build geometry. float length = 0; @@ -162,15 +167,15 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con float const projRightStart = -segments[i].m_rightWidthScalar[StartPoint].y; float const projRightEnd = segments[i].m_rightWidthScalar[EndPoint].y; - geometry.push_back(RV(startPivot, glsl::vec2(0, 0), glsl::vec3(length, 0, kCenter))); - geometry.push_back(RV(startPivot, leftNormalStart, glsl::vec3(length, projLeftStart, kLeftSide))); - geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter))); - geometry.push_back(RV(endPivot, leftNormalEnd, glsl::vec3(endLength, projLeftEnd, kLeftSide))); + geometry.push_back(RV(startPivot, glsl::vec2(0, 0), glsl::vec3(length, 0, kCenter), segments[i].m_color)); + geometry.push_back(RV(startPivot, leftNormalStart, glsl::vec3(length, projLeftStart, kLeftSide), segments[i].m_color)); + geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter), segments[i].m_color)); + geometry.push_back(RV(endPivot, leftNormalEnd, glsl::vec3(endLength, projLeftEnd, kLeftSide), segments[i].m_color)); - geometry.push_back(RV(startPivot, rightNormalStart, glsl::vec3(length, projRightStart, kRightSide))); - geometry.push_back(RV(startPivot, glsl::vec2(0, 0), glsl::vec3(length, 0, kCenter))); - geometry.push_back(RV(endPivot, rightNormalEnd, glsl::vec3(endLength, projRightEnd, kRightSide))); - geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter))); + geometry.push_back(RV(startPivot, rightNormalStart, glsl::vec3(length, projRightStart, kRightSide), segments[i].m_color)); + geometry.push_back(RV(startPivot, glsl::vec2(0, 0), glsl::vec3(length, 0, kCenter), segments[i].m_color)); + geometry.push_back(RV(endPivot, rightNormalEnd, glsl::vec3(endLength, projRightEnd, kRightSide), segments[i].m_color)); + geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter), segments[i].m_color)); // Generate joins. if (segments[i].m_generateJoin && i < segments.size() - 1) @@ -230,7 +235,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::Point // Construct segments. vector segments; segments.reserve(path.size() - 1); - ConstructLineSegments(path, segments); + ConstructLineSegments(path, vector(), segments); m2::RectF tr = texRect; tr.setMinX(texRect.minX() * (1.0 - kArrowTailSize) + texRect.maxX() * kArrowTailSize); @@ -401,9 +406,20 @@ void RouteShape::CacheRouteArrows(ref_ptr mng, m2::PolylineD void RouteShape::CacheRoute(ref_ptr textures, RouteData & routeData) { + vector segmentsColors; + segmentsColors.reserve(routeData.m_traffic.size()); + auto const & style = GetStyleReader().GetCurrentStyle(); + for (auto const & speedGroup : routeData.m_traffic) + { + dp::Color const color = df::GetColorConstant(style, TrafficGenerator::GetColorBySpeedGroup(speedGroup)); + float const alpha = (speedGroup == traffic::SpeedGroup::G5 || + speedGroup == traffic::SpeedGroup::Unknown) ? 0.0f : 1.0f; + segmentsColors.push_back(glsl::vec4(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), alpha)); + } + TGeometryBuffer geometry; TGeometryBuffer joinsGeometry; - PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), routeData.m_pivot, + PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), routeData.m_pivot, segmentsColors, geometry, joinsGeometry, routeData.m_length); dp::GLState state = dp::GLState(gpu::ROUTE_PROGRAM, dp::GLState::GeometryLayer); diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index a8afbc0fc4..29b2116692 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -9,6 +9,8 @@ #include "drape/utils/vertex_decl.hpp" #include "drape/pointers.hpp" +#include "traffic/speed_groups.hpp" + #include "geometry/polyline2d.hpp" #include "std/vector.hpp" @@ -64,6 +66,7 @@ struct RouteData vector m_sourceTurns; m2::PointD m_pivot; df::ColorConstant m_color; + vector m_traffic; double m_length; RouteRenderProperty m_route; RoutePattern m_pattern; @@ -101,6 +104,7 @@ public: private: static void PrepareGeometry(vector const & path, m2::PointD const & pivot, + vector const & segmentsColors, TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, double & outputLength); static void PrepareArrowGeometry(vector const & path, m2::PointD const & pivot, diff --git a/drape_frontend/traffic_generator.cpp b/drape_frontend/traffic_generator.cpp index 63e10daabb..65ac83a5a9 100644 --- a/drape_frontend/traffic_generator.cpp +++ b/drape_frontend/traffic_generator.cpp @@ -1,6 +1,5 @@ #include "drape_frontend/traffic_generator.hpp" -#include "drape_frontend/color_constants.hpp" #include "drape_frontend/line_shape_helper.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/shape_view_params.hpp" @@ -444,7 +443,8 @@ void TrafficGenerator::GenerateLineSegment(dp::TextureManager::ColorRegion const } } -void TrafficGenerator::FillColorsCache(ref_ptr textures) +// static +df::ColorConstant TrafficGenerator::GetColorBySpeedGroup(traffic::SpeedGroup const & speedGroup) { size_t constexpr kSpeedGroupsCount = static_cast(traffic::SpeedGroup::Count); static array const colorMap @@ -459,13 +459,22 @@ void TrafficGenerator::FillColorsCache(ref_ptr textures) df::TrafficUnknown, }}; + size_t const index = static_cast(speedGroup); + ASSERT_LESS(index, kSpeedGroupsCount, ()); + return colorMap[index]; +} + +void TrafficGenerator::FillColorsCache(ref_ptr textures) +{ + size_t constexpr kSpeedGroupsCount = static_cast(traffic::SpeedGroup::Count); if (!m_colorsCacheValid) { auto const & style = GetStyleReader().GetCurrentStyle(); - for (size_t i = 0; i < colorMap.size(); i++) + for (size_t i = 0; i < kSpeedGroupsCount; i++) { dp::TextureManager::ColorRegion colorRegion; - textures->GetColorRegion(df::GetColorConstant(style, colorMap[i]), colorRegion); + auto const colorConstant = GetColorBySpeedGroup(static_cast(i)); + textures->GetColorRegion(df::GetColorConstant(style, colorConstant), colorRegion); m_colorsCache[i] = colorRegion; } m_colorsCacheValid = true; diff --git a/drape_frontend/traffic_generator.hpp b/drape_frontend/traffic_generator.hpp index f8a4ccd5d4..69c22c4e9a 100644 --- a/drape_frontend/traffic_generator.hpp +++ b/drape_frontend/traffic_generator.hpp @@ -1,6 +1,7 @@ #pragma once #include "drape_frontend/batchers_pool.hpp" +#include "drape_frontend/color_constants.hpp" #include "drape_frontend/tile_key.hpp" #include "drape/color.hpp" @@ -184,6 +185,8 @@ public: bool IsColorsCacheRefreshed() const { return m_colorsCacheRefreshed; } TrafficTexCoords ProcessCacheRefreshing(); + static df::ColorConstant GetColorBySpeedGroup(traffic::SpeedGroup const & speedGroup); + private: struct TrafficBatcherKey { diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp index eeab9b6698..573a3f885a 100644 --- a/drape_frontend/traffic_renderer.cpp +++ b/drape_frontend/traffic_renderer.cpp @@ -160,7 +160,7 @@ void TrafficRenderer::UpdateTraffic(TrafficSegmentsColoring const & trafficColor } } -void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, +void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, float opacity, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { @@ -189,7 +189,7 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, dp::UniformValuesStorage uniforms = commonUniforms; math::Matrix const mv = renderData.m_tileKey.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - uniforms.SetFloatValue("u_opacity", 1.0f); + uniforms.SetFloatValue("u_opacity", opacity); dp::ApplyUniforms(uniforms, program); renderData.m_bucket->Render(true /* draw as line */); @@ -241,7 +241,7 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, dp::UniformValuesStorage uniforms = commonUniforms; math::Matrix const mv = renderData.m_tileKey.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - uniforms.SetFloatValue("u_opacity", 1.0f); + uniforms.SetFloatValue("u_opacity", opacity); uniforms.SetFloatValue("u_outline", outline); uniforms.SetFloatValue("u_lightArrowColor", lightArrowColor.GetRedF(), lightArrowColor.GetGreenF(), lightArrowColor.GetBlueF()); diff --git a/drape_frontend/traffic_renderer.hpp b/drape_frontend/traffic_renderer.hpp index 674f9fb885..6532112766 100644 --- a/drape_frontend/traffic_renderer.hpp +++ b/drape_frontend/traffic_renderer.hpp @@ -27,7 +27,7 @@ public: void UpdateTraffic(TrafficSegmentsColoring const & trafficColoring); - void RenderTraffic(ScreenBase const & screen, int zoomLevel, + void RenderTraffic(ScreenBase const & screen, int zoomLevel, float opacity, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); diff --git a/map/framework.cpp b/map/framework.cpp index 85446f0d11..d441e3a876 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2532,7 +2532,17 @@ void Framework::InsertRoute(Route const & route) pattern = df::RoutePattern(8.0, 2.0); } - m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor, pattern); + // TODO(@bykoianko): set traffic by route. + // TEMPORARY { + vector traffic; + traffic.resize(route.GetPoly().GetSize() - 1, traffic::SpeedGroup::Unknown); + for (size_t i = 0; i < traffic.size(); i++) + { + traffic[i] = static_cast(rand() % static_cast(traffic::SpeedGroup::Count)); + } + // } TEMPORARY + + m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor, traffic, pattern); } void Framework::CheckLocationForRouting(GpsInfo const & info)