diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp index 153884b260..61ee05131a 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp @@ -109,7 +109,7 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkCategory_nativeGetTrack( dp::Color nColor = nTrack->GetColor(0); - jint androidColor = shift(nColor.GetAlfa(), 24) + + jint androidColor = shift(nColor.GetAlpha(), 24) + shift(nColor.GetRed(), 16) + shift(nColor.GetGreen(), 8) + nColor.GetBlue(); diff --git a/drape/color.cpp b/drape/color.cpp index e0b3ea0eba..d110b216fa 100644 --- a/drape/color.cpp +++ b/drape/color.cpp @@ -18,9 +18,9 @@ Color::Color() { } -Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alfa) +Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { - m_rgba = red << 24 | green << 16 | blue << 8 | alfa; + m_rgba = red << 24 | green << 16 | blue << 8 | alpha; } uint8_t Color::GetRed() const @@ -38,7 +38,7 @@ uint8_t Color::GetBlue() const return EXTRACT_BYTE(m_rgba, 1); } -uint8_t Color::GetAlfa() const +uint8_t Color::GetAlpha() const { return EXTRACT_BYTE(m_rgba, 0); } @@ -58,9 +58,9 @@ float Color::GetBlueF() const return CHANNEL_TO_FLOAT(GetBlue()); } -float Color::GetAlfaF() const +float Color::GetAlphaF() const { - return CHANNEL_TO_FLOAT(GetAlfa()); + return CHANNEL_TO_FLOAT(GetAlpha()); } uint8_t ExtractRed(uint32_t argb) @@ -78,7 +78,7 @@ uint8_t ExtractBlue(uint32_t argb) return argb & 0xFF; } -uint8_t ExtractAlfa(uint32_t argb) +uint8_t ExtractAlpha(uint32_t argb) { return (argb >> 24) & 0xFF; } @@ -88,7 +88,7 @@ Color Extract(uint32_t argb) return Color(ExtractRed(argb), ExtractGreen(argb), ExtractBlue(argb), - ExtractAlfa(argb)); + ExtractAlpha(argb)); } Color Extract(uint32_t xrgb, uint8_t a) diff --git a/drape/color.hpp b/drape/color.hpp index b198796a76..df31e9d9bd 100644 --- a/drape/color.hpp +++ b/drape/color.hpp @@ -12,17 +12,17 @@ namespace dp struct Color { Color(); - Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alfa); + Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); uint8_t GetRed() const; uint8_t GetGreen() const; uint8_t GetBlue() const; - uint8_t GetAlfa() const; + uint8_t GetAlpha() const; float GetRedF() const; float GetGreenF() const; float GetBlueF() const; - float GetAlfaF() const; + float GetAlphaF() const; bool operator==(Color const & other) const { return m_rgba == other.m_rgba; } bool operator< (Color const & other) const { return m_rgba < other.m_rgba; } @@ -31,7 +31,7 @@ struct Color 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()); + GetAlpha()); } static Color Black() { return Color(0, 0, 0, 255); } @@ -48,7 +48,7 @@ private: inline uint8_t ExtractRed(uint32_t argb); inline uint8_t ExtractGreen(uint32_t argb); inline uint8_t ExtractBlue(uint32_t argb); -inline uint8_t ExtractAlfa(uint32_t argb); +inline uint8_t ExtractAlpha(uint32_t argb); Color Extract(uint32_t argb); Color Extract(uint32_t xrgb, uint8_t a); @@ -58,7 +58,7 @@ inline string DebugPrint(Color const & c) out << "R = " << c.GetRed() << "G = " << c.GetGreen() << "B = " << c.GetBlue() - << "A = " << c.GetAlfa(); + << "A = " << c.GetAlpha(); return out.str(); } diff --git a/drape/debug_rect_renderer.cpp b/drape/debug_rect_renderer.cpp index 38ab953198..19cf8c7410 100644 --- a/drape/debug_rect_renderer.cpp +++ b/drape/debug_rect_renderer.cpp @@ -112,7 +112,7 @@ void DebugRectRenderer::DrawRect(ScreenBase const & screen, m2::RectF const & re int8_t const location = m_program->GetUniformLocation("u_color"); if (location >= 0) GLFunctions::glUniformValuef(location, color.GetRedF(), color.GetGreenF(), - color.GetBlueF(), color.GetAlfaF()); + color.GetBlueF(), color.GetAlphaF()); GLFunctions::glDrawArrays(gl_const::GLLineStrip, 0, static_cast(vertices.size())); @@ -157,7 +157,7 @@ void DebugRectRenderer::DrawArrow(ScreenBase const & screen, int8_t const location = m_program->GetUniformLocation("u_color"); if (location >= 0) GLFunctions::glUniformValuef(location, data.m_arrowColor.GetRedF(), data.m_arrowColor.GetGreenF(), - data.m_arrowColor.GetBlueF(), data.m_arrowColor.GetAlfaF()); + data.m_arrowColor.GetBlueF(), data.m_arrowColor.GetAlphaF()); GLFunctions::glDrawArrays(gl_const::GLLineStrip, 0, static_cast(vertices.size())); diff --git a/drape/glsl_types.hpp b/drape/glsl_types.hpp index 588b609128..5229358bd4 100644 --- a/drape/glsl_types.hpp +++ b/drape/glsl_types.hpp @@ -68,7 +68,7 @@ inline vec4 ToVec4(dp::Color const & color) return glsl::vec4(double(color.GetRed()) / 255, double(color.GetGreen()) / 255, double(color.GetBlue()) / 255, - double(color.GetAlfa()) / 255); + double(color.GetAlpha()) / 255); } template::value || is_floating_point::value>::type> diff --git a/drape/texture_of_colors.cpp b/drape/texture_of_colors.cpp index 4ae4a2f097..6164159cc1 100644 --- a/drape/texture_of_colors.cpp +++ b/drape/texture_of_colors.cpp @@ -142,7 +142,7 @@ void ColorPalette::UploadResources(ref_ptr texture) uint8_t const red = c.m_color.GetRed(); uint8_t const green = c.m_color.GetGreen(); uint8_t const blue = c.m_color.GetBlue(); - uint8_t const alpha = c.m_color.GetAlfa(); + uint8_t const alpha = c.m_color.GetAlpha(); for (size_t row = 0; row < kResourceSize; row++) { diff --git a/drape/utils/vertex_decl.cpp b/drape/utils/vertex_decl.cpp index 6edd5386ff..d2700eca5b 100644 --- a/drape/utils/vertex_decl.cpp +++ b/drape/utils/vertex_decl.cpp @@ -2,10 +2,8 @@ namespace gpu { - namespace { - enum VertexType { Area, @@ -19,6 +17,7 @@ enum VertexType Line, DashedLine, Route, + RouteMarker, ColoredSymbol, TypeCount }; @@ -180,6 +179,20 @@ dp::BindingInfo RouteBindingInit() return filler.m_info; } +dp::BindingInfo RouteMarkerBindingInit() +{ + static_assert(sizeof(RouteMarkerVertex) == sizeof(RouteMarkerVertex::TPosition) + + sizeof(RouteMarkerVertex::TNormal) + + sizeof(RouteMarkerVertex::TColor), ""); + + dp::BindingFiller filler(3); + filler.FillDecl("a_position"); + filler.FillDecl("a_normal"); + filler.FillDecl("a_color"); + + return filler.m_info; +} + dp::BindingInfo ColoredSymbolBindingInit() { static_assert(sizeof(ColoredSymbolVertex) == sizeof(ColoredSymbolVertex::TPosition) + @@ -208,6 +221,7 @@ TInitFunction g_initFunctions[TypeCount] = &LineBindingInit, &DashedLineBindingInit, &RouteBindingInit, + &RouteMarkerBindingInit, &ColoredSymbolBindingInit }; @@ -222,20 +236,17 @@ dp::BindingInfo const & GetBinding(VertexType type) return node.m_info; } - -} // namespace +} // namespace AreaVertex::AreaVertex() : m_position(0.0, 0.0, 0.0) , m_colorTexCoord(0.0, 0.0) -{ -} +{} AreaVertex::AreaVertex(TPosition const & position, TTexCoord const & colorTexCoord) : m_position(position) , m_colorTexCoord(colorTexCoord) -{ -} +{} dp::BindingInfo const & AreaVertex::GetBindingInfo() { @@ -246,16 +257,14 @@ Area3dVertex::Area3dVertex() : m_position(0.0, 0.0, 0.0) , m_normal(0.0, 0.0, 0.0) , m_colorTexCoord(0.0, 0.0) -{ -} +{} Area3dVertex::Area3dVertex(TPosition const & position, TPosition const & normal, TTexCoord const & colorTexCoord) : m_position(position) , m_normal(normal) , m_colorTexCoord(colorTexCoord) -{ -} +{} dp::BindingInfo const & Area3dVertex::GetBindingInfo() { @@ -266,16 +275,14 @@ HatchingAreaVertex::HatchingAreaVertex() : m_position(0.0, 0.0, 0.0) , m_colorTexCoord(0.0, 0.0) , m_maskTexCoord(0.0, 0.0) -{ -} +{} HatchingAreaVertex::HatchingAreaVertex(TPosition const & position, TTexCoord const & colorTexCoord, TMaskTexCoord const & maskTexCoord) : m_position(position) , m_colorTexCoord(colorTexCoord) , m_maskTexCoord(maskTexCoord) -{ -} +{} dp::BindingInfo const & HatchingAreaVertex::GetBindingInfo() { @@ -286,16 +293,14 @@ SolidTexturingVertex::SolidTexturingVertex() : m_position(0.0, 0.0, 0.0, 0.0) , m_normal(0.0, 0.0) , m_colorTexCoord(0.0, 0.0) -{ -} +{} SolidTexturingVertex::SolidTexturingVertex(TPosition3d const & position, TNormal const & normal, TTexCoord const & colorTexCoord) : m_position(position) , m_normal(normal) , m_colorTexCoord(colorTexCoord) -{ -} +{} dp::BindingInfo const & SolidTexturingVertex::GetBindingInfo() { @@ -307,8 +312,7 @@ MaskedTexturingVertex::MaskedTexturingVertex() , m_normal(0.0, 0.0) , m_colorTexCoord(0.0, 0.0) , m_maskTexCoord(0.0, 0.0) -{ -} +{} MaskedTexturingVertex::MaskedTexturingVertex(TPosition3d const & position, TNormal const & normal, TTexCoord const & colorTexCoord, TTexCoord const & maskTexCoord) @@ -316,8 +320,7 @@ MaskedTexturingVertex::MaskedTexturingVertex(TPosition3d const & position, TNorm , m_normal(normal) , m_colorTexCoord(colorTexCoord) , m_maskTexCoord(maskTexCoord) -{ -} +{} dp::BindingInfo const & MaskedTexturingVertex::GetBindingInfo() { @@ -328,8 +331,7 @@ TextOutlinedStaticVertex::TextOutlinedStaticVertex() : m_colorTexCoord(0.0, 0.0) , m_outlineTexCoord(0.0, 0.0) , m_maskTexCoord(0.0, 0.0) -{ -} +{} TextOutlinedStaticVertex::TextOutlinedStaticVertex(TTexCoord const & colorTexCoord, TTexCoord const & outlineTexCoord, @@ -337,8 +339,7 @@ TextOutlinedStaticVertex::TextOutlinedStaticVertex(TTexCoord const & colorTexCoo : m_colorTexCoord(colorTexCoord) , m_outlineTexCoord(outlineTexCoord) , m_maskTexCoord(maskTexCoord) -{ -} +{} dp::BindingInfo const & TextOutlinedStaticVertex::GetBindingInfo() { @@ -348,14 +349,12 @@ dp::BindingInfo const & TextOutlinedStaticVertex::GetBindingInfo() TextDynamicVertex::TextDynamicVertex() : m_position(0.0, 0.0, 0.0, 0.0) , m_normal(0.0, 0.0) -{ -} +{} TextDynamicVertex::TextDynamicVertex(const TPosition3d & position, TNormal const & normal) : m_position(position), m_normal(normal) -{ -} +{} dp::BindingInfo const & TextDynamicVertex::GetBindingInfo() { @@ -371,15 +370,13 @@ LineVertex::LineVertex() : m_position(0.0, 0.0, 0.0) , m_normal(0.0, 0.0, 0.0) , m_colorTexCoord(0.0, 0.0) -{ -} +{} LineVertex::LineVertex(TPosition const & position, TNormal const & normal, TTexCoord const & color) : m_position(position) , m_normal(normal) , m_colorTexCoord(color) -{ -} +{} dp::BindingInfo const & LineVertex::GetBindingInfo() { @@ -388,8 +385,7 @@ dp::BindingInfo const & LineVertex::GetBindingInfo() DashedLineVertex::DashedLineVertex() : m_maskTexCoord(0.0, 0.0, 0.0, 0.0) -{ -} +{} DashedLineVertex::DashedLineVertex(TPosition const & position, TNormal const & normal, TTexCoord const & color, TMaskTexCoord const & mask) @@ -397,8 +393,7 @@ DashedLineVertex::DashedLineVertex(TPosition const & position, TNormal const & n , m_normal(normal) , m_colorTexCoord(color) , m_maskTexCoord(mask) -{ -} +{} dp::BindingInfo const & DashedLineVertex::GetBindingInfo() { @@ -425,17 +420,33 @@ dp::BindingInfo const & RouteVertex::GetBindingInfo() return GetBinding(Route); } +RouteMarkerVertex::RouteMarkerVertex() + : m_position(0.0, 0.0, 0.0, 0.0) + , m_normal(0.0, 0.0, 0.0) + , m_color(0.0, 0.0, 0.0, 0.0) +{} + +RouteMarkerVertex::RouteMarkerVertex(TPosition const & position, TNormal const & normal, + TColor const & color) + : m_position(position) + , m_normal(normal) + , m_color(color) +{} + +dp::BindingInfo const & RouteMarkerVertex::GetBindingInfo() +{ + return GetBinding(RouteMarker); +} + TextStaticVertex::TextStaticVertex() : m_colorTexCoord(0.0, 0.0) , m_maskTexCoord(0.0, 0.0) -{ -} +{} TextStaticVertex::TextStaticVertex(TTexCoord const & colorTexCoord, TTexCoord const & maskTexCoord) : m_colorTexCoord(colorTexCoord) , m_maskTexCoord(maskTexCoord) -{ -} +{} dp::BindingInfo const & TextStaticVertex::GetBindingInfo() { @@ -446,21 +457,18 @@ ColoredSymbolVertex::ColoredSymbolVertex() : m_position(0.0, 0.0, 0.0) , m_normal(0.0, 0.0, 0.0, 0.0) , m_colorTexCoord(0.0, 0.0, 0.0, 0.0) -{ -} +{} ColoredSymbolVertex::ColoredSymbolVertex(TPosition const & position, TNormal const & normal, TTexCoord const & colorTexCoord) : m_position(position) , m_normal(normal) , m_colorTexCoord(colorTexCoord) -{ -} +{} dp::BindingInfo const & ColoredSymbolVertex::GetBindingInfo() { return GetBinding(ColoredSymbol); } - -} //namespace gpu +} // namespace gpu diff --git a/drape/utils/vertex_decl.hpp b/drape/utils/vertex_decl.hpp index dc93a6a7fb..55b72e1722 100644 --- a/drape/utils/vertex_decl.hpp +++ b/drape/utils/vertex_decl.hpp @@ -173,6 +173,23 @@ struct RouteVertex : BaseVertex static dp::BindingInfo const & GetBindingInfo(); }; +struct RouteMarkerVertex : BaseVertex +{ + using TPosition = glsl::vec4; + using TNormal = glsl::vec3; + using TColor = glsl::vec4; + + RouteMarkerVertex(); + RouteMarkerVertex(TPosition const & position, TNormal const & normal, + TColor const & color); + + TPosition m_position; + TNormal m_normal; + TColor m_color; + + static dp::BindingInfo const & GetBindingInfo(); +}; + struct ColoredSymbolVertex : BaseVertex { using TNormal = glsl::vec4; diff --git a/drape_frontend/CMakeLists.txt b/drape_frontend/CMakeLists.txt index a3c00e0a12..051ce02c74 100644 --- a/drape_frontend/CMakeLists.txt +++ b/drape_frontend/CMakeLists.txt @@ -256,6 +256,8 @@ set( shaders/route_arrow.fsh.glsl shaders/route_arrow.vsh.glsl shaders/route_dash.fsh.glsl + shaders/route_marker.fsh.glsl + shaders/route_marker.vsh.glsl shaders/ruler.vsh.glsl shaders/screen_quad.vsh.glsl shaders/shader_index.txt diff --git a/drape_frontend/arrow3d.cpp b/drape_frontend/arrow3d.cpp index 1741a8da6c..fc185aa20f 100644 --- a/drape_frontend/arrow3d.cpp +++ b/drape_frontend/arrow3d.cpp @@ -158,7 +158,7 @@ void Arrow3d::Render(ScreenBase const & screen, ref_ptr m dp::Color const outlineColor = df::GetColorConstant(df::kArrow3DOutlineColor); ref_ptr outlineProgram = mng->GetProgram(gpu::ARROW_3D_OUTLINE_PROGRAM); RenderArrow(screen, outlineProgram, - dp::Color(outlineColor.GetRed(), outlineColor.GetGreen(), outlineColor.GetBlue(), color.GetAlfa()), + dp::Color(outlineColor.GetRed(), outlineColor.GetGreen(), outlineColor.GetBlue(), color.GetAlpha()), 0.0f /* dz */, kOutlineScale /* scaleFactor */, false /* hasNormals */); } diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index f5f505fe5e..9ee1668df6 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -55,6 +55,11 @@ BackendRenderer::BackendRenderer(Params && params) m_commutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(std::move(subrouteArrowsData)), MessagePriority::Normal); + }, [this](drape_ptr && subrouteMarkersData) + { + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(std::move(subrouteMarkersData)), + MessagePriority::Normal); }); StartThread(); diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 346ac69d1c..babebf4040 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -248,6 +248,8 @@ OTHER_FILES += \ shaders/route_arrow.fsh.glsl \ shaders/route_arrow.vsh.glsl \ shaders/route_dash.fsh.glsl \ + shaders/route_marker.fsh.glsl \ + shaders/route_marker.vsh.glsl \ shaders/ruler.vsh.glsl \ shaders/screen_quad.vsh.glsl \ shaders/shader_index.txt \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 7eda3979f5..711ece2a67 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -432,7 +432,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::FlushSubroute: { ref_ptr msg = message; - auto subrouteData = msg->AcceptSubrouteData(); + auto subrouteData = msg->AcceptRenderData(); if (subrouteData->m_recacheId < 0) subrouteData->m_recacheId = m_lastRecacheRouteId; @@ -461,7 +461,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::FlushSubrouteArrows: { ref_ptr msg = message; - drape_ptr routeArrowsData = msg->AcceptSubrouteArrowsData(); + drape_ptr routeArrowsData = msg->AcceptRenderData(); if (CheckRouteRecaching(make_ref(routeArrowsData))) { m_routeRenderer->AddSubrouteArrowsData(std::move(routeArrowsData), @@ -470,6 +470,21 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } + case Message::FlushSubrouteMarkers: + { + ref_ptr msg = message; + drape_ptr markersData = msg->AcceptRenderData(); + if (markersData->m_recacheId < 0) + markersData->m_recacheId = m_lastRecacheRouteId; + + if (CheckRouteRecaching(make_ref(markersData))) + { + m_routeRenderer->AddSubrouteMarkersData(std::move(markersData), + make_ref(m_gpuProgramManager)); + } + break; + } + case Message::RemoveSubroute: { ref_ptr msg = message; @@ -752,7 +767,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) if (!m_trafficEnabled) break; ref_ptr msg = message; - m_trafficRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptTrafficData()); + m_trafficRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptRenderData()); break; } diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index c5a8ca5f32..012e681996 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -40,6 +40,7 @@ public: CacheSubrouteArrows, FlushSubroute, FlushSubrouteArrows, + FlushSubrouteMarkers, FollowRoute, DeactivateRouteFollowing, SetSubrouteVisibility, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 29259d4303..88b049288a 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -39,7 +39,6 @@ namespace df { - class BaseBlockingMessage : public Message { public: @@ -123,7 +122,8 @@ private: class FlushRenderBucketMessage : public BaseTileMessage { public: - FlushRenderBucketMessage(TileKey const & key, dp::GLState const & state, drape_ptr && buffer) + FlushRenderBucketMessage(TileKey const & key, dp::GLState const & state, + drape_ptr && buffer) : BaseTileMessage(key) , m_state(state) , m_buffer(move(buffer)) @@ -140,20 +140,24 @@ private: drape_ptr m_buffer; }; -class FlushOverlaysMessage : public Message +template +class FlushRenderDataMessage : public Message { public: - FlushOverlaysMessage(TOverlaysRenderData && data) : m_data(move(data)) {} + explicit FlushRenderDataMessage(RenderDataType && data) : m_data(std::move(data)) {} - Type GetType() const override { return Message::FlushOverlays; } + Type GetType() const override { return MessageType; } bool IsGLContextDependent() const override { return true; } - TOverlaysRenderData && AcceptRenderData() { return move(m_data); } + RenderDataType && AcceptRenderData() { return std::move(m_data); } private: - TOverlaysRenderData m_data; + RenderDataType m_data; }; +using FlushOverlaysMessage = FlushRenderDataMessage; + class InvalidateRectMessage : public Message { public: @@ -278,21 +282,8 @@ private: drape_ptr m_ids; }; -class FlushUserMarksMessage : public Message -{ -public: - FlushUserMarksMessage(TUserMarksRenderData && renderData) - : m_renderData(std::move(renderData)) - {} - - Type GetType() const override { return Message::FlushUserMarks; } - bool IsGLContextDependent() const override { return true; } - - TUserMarksRenderData && AcceptRenderData() { return std::move(m_renderData); } - -private: - TUserMarksRenderData m_renderData; -}; +using FlushUserMarksMessage = FlushRenderDataMessage; class InvalidateUserMarksMessage : public Message { @@ -610,37 +601,12 @@ private: bool m_deactivateFollowing; }; -class FlushSubrouteMessage : public Message -{ -public: - explicit FlushSubrouteMessage(drape_ptr && subrouteData) - : m_subrouteData(std::move(subrouteData)) - {} - - Type GetType() const override { return Message::FlushSubroute; } - - bool IsGLContextDependent() const override { return true; } - drape_ptr && AcceptSubrouteData() { return std::move(m_subrouteData); } - -private: - drape_ptr m_subrouteData; -}; - -class FlushSubrouteArrowsMessage : public Message -{ -public: - explicit FlushSubrouteArrowsMessage(drape_ptr && subrouteArrowsData) - : m_subrouteArrowsData(std::move(subrouteArrowsData)) - {} - - Type GetType() const override { return Message::FlushSubrouteArrows; } - - bool IsGLContextDependent() const override { return true; } - drape_ptr && AcceptSubrouteArrowsData() { return std::move(m_subrouteArrowsData); } - -private: - drape_ptr m_subrouteArrowsData; -}; +using FlushSubrouteMessage = FlushRenderDataMessage, + Message::FlushSubroute>; +using FlushSubrouteArrowsMessage = FlushRenderDataMessage, + Message::FlushSubrouteArrows>; +using FlushSubrouteMarkersMessage = FlushRenderDataMessage, + Message::FlushSubrouteMarkers>; class AddRoutePreviewSegmentMessage : public Message { @@ -865,24 +831,20 @@ private: Destination m_destination; }; -class FlushCirclesPackMessage : public Message +using BaseFlushCirclesPackMessage = FlushRenderDataMessage, + Message::FlushCirclesPack>; +class FlushCirclesPackMessage : public BaseFlushCirclesPackMessage { public: - FlushCirclesPackMessage(drape_ptr && renderData, CacheCirclesPackMessage::Destination dest) - : m_renderData(std::move(renderData)) + : BaseFlushCirclesPackMessage(std::move(renderData)) , m_destination(dest) {} - Type GetType() const override { return Message::FlushCirclesPack; } - bool IsGLContextDependent() const override { return true; } - - drape_ptr && AcceptRenderData() { return std::move(m_renderData); } CacheCirclesPackMessage::Destination GetDestination() const { return m_destination; } private: - drape_ptr m_renderData; CacheCirclesPackMessage::Destination m_destination; }; @@ -1021,21 +983,8 @@ private: TrafficSegmentsColoring m_segmentsColoring; }; -class FlushTrafficDataMessage : public Message -{ -public: - explicit FlushTrafficDataMessage(TrafficRenderData && trafficData) - : m_trafficData(move(trafficData)) - {} - - Type GetType() const override { return Message::FlushTrafficData; } - bool IsGLContextDependent() const override { return true; } - - TrafficRenderData && AcceptTrafficData() { return move(m_trafficData); } - -private: - TrafficRenderData m_trafficData; -}; +using FlushTrafficDataMessage = FlushRenderDataMessage; class ClearTrafficDataMessage : public Message { diff --git a/drape_frontend/route_builder.cpp b/drape_frontend/route_builder.cpp index cfe67cd3d6..3bf75e567d 100644 --- a/drape_frontend/route_builder.cpp +++ b/drape_frontend/route_builder.cpp @@ -33,10 +33,11 @@ std::vector> SplitSubroute(df::SubrouteConstPtr subrou namespace df { -RouteBuilder::RouteBuilder(TFlushRouteFn const & flushRouteFn, - TFlushRouteArrowsFn const & flushRouteArrowsFn) - : m_flushRouteFn(flushRouteFn) - , m_flushRouteArrowsFn(flushRouteArrowsFn) +RouteBuilder::RouteBuilder(FlushFn && flushFn, FlushArrowsFn && flushArrowsFn, + FlushMarkersFn && flushMarkersFn) + : m_flushFn(std::move(flushFn)) + , m_flushArrowsFn(std::move(flushArrowsFn)) + , m_flushMarkersFn(std::move(flushMarkersFn)) {} void RouteBuilder::Build(dp::DrapeID subrouteId, SubrouteConstPtr subroute, @@ -56,15 +57,20 @@ void RouteBuilder::Build(dp::DrapeID subrouteId, SubrouteConstPtr subroute, indices.second, recacheId, textures)); } + auto markersData = RouteShape::CacheMarkers(subrouteId, subroute, recacheId, textures); + // Flush route geometry. GLFunctions::glFlush(); - if (m_flushRouteFn != nullptr) + if (m_flushFn != nullptr) { for (auto & data : subrouteData) - m_flushRouteFn(std::move(data)); + m_flushFn(std::move(data)); subrouteData.clear(); } + + if (m_flushMarkersFn != nullptr && markersData != nullptr) + m_flushMarkersFn(std::move(markersData)); } void RouteBuilder::ClearRouteCache() @@ -89,7 +95,7 @@ void RouteBuilder::BuildArrows(dp::DrapeID subrouteId, std::vector // Flush route arrows geometry. GLFunctions::glFlush(); - if (m_flushRouteArrowsFn != nullptr) - m_flushRouteArrowsFn(std::move(routeArrowsData)); + if (m_flushArrowsFn != nullptr) + m_flushArrowsFn(std::move(routeArrowsData)); } } // namespace df diff --git a/drape_frontend/route_builder.hpp b/drape_frontend/route_builder.hpp index f22f399928..a659239350 100644 --- a/drape_frontend/route_builder.hpp +++ b/drape_frontend/route_builder.hpp @@ -19,11 +19,12 @@ namespace df class RouteBuilder { public: - using TFlushRouteFn = std::function &&)>; - using TFlushRouteArrowsFn = std::function &&)>; + using FlushFn = std::function &&)>; + using FlushArrowsFn = std::function &&)>; + using FlushMarkersFn = std::function &&)>; - RouteBuilder(TFlushRouteFn const & flushRouteFn, - TFlushRouteArrowsFn const & flushRouteArrowsFn); + RouteBuilder(FlushFn && flushFn, FlushArrowsFn && flushArrowsFn, + FlushMarkersFn && flushMarkersFn); void Build(dp::DrapeID subrouteId, SubrouteConstPtr subroute, ref_ptr textures, int recacheId); @@ -34,8 +35,9 @@ public: void ClearRouteCache(); private: - TFlushRouteFn m_flushRouteFn; - TFlushRouteArrowsFn m_flushRouteArrowsFn; + FlushFn m_flushFn; + FlushArrowsFn m_flushArrowsFn; + FlushMarkersFn m_flushMarkersFn; struct RouteCacheData { diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index e97cf9fe1f..179af5d09c 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -396,12 +396,16 @@ void RouteRenderer::RenderSubroute(SubrouteInfo const & subrouteInfo, size_t sub if (m_hiddenSubroutes.find(subrouteInfo.m_subrouteId) != m_hiddenSubroutes.end()) return; + auto const & subrouteData = subrouteInfo.m_subrouteData[subrouteDataIndex]; + auto const screenHalfWidth = static_cast(subrouteInfo.m_currentHalfWidth * screen.GetScale()); auto dist = static_cast(kInvalidDistance); if (m_followingEnabled) - dist = static_cast(m_distanceFromBegin - subrouteInfo.m_subroute->m_baseDistance); + { + auto const distanceOffset = subrouteInfo.m_subroute->m_baseDistance + subrouteData->m_distanceOffset; + dist = static_cast(m_distanceFromBegin - distanceOffset); + } - auto const & subrouteData = subrouteInfo.m_subrouteData[subrouteDataIndex]; dp::GLState const & state = subrouteData->m_renderProperty.m_state; size_t const styleIndex = subrouteData->m_startPointIndex; ASSERT_LESS(styleIndex, subrouteInfo.m_subroute->m_style.size(), ()); @@ -484,6 +488,44 @@ void RouteRenderer::RenderSubrouteArrows(SubrouteInfo const & subrouteInfo, bucket->Render(state.GetDrawAsLine()); } +void RouteRenderer::RenderSubrouteMarkers(SubrouteInfo const & subrouteInfo, ScreenBase const & screen, + ref_ptr mng, + dp::UniformValuesStorage const & commonUniforms) +{ + if (subrouteInfo.m_markersData == nullptr || + subrouteInfo.m_markersData->m_renderProperty.m_buckets.empty() || + m_hiddenSubroutes.find(subrouteInfo.m_subrouteId) != m_hiddenSubroutes.end()) + { + return; + } + + auto dist = static_cast(kInvalidDistance); + if (m_followingEnabled) + dist = static_cast(m_distanceFromBegin - subrouteInfo.m_subroute->m_baseDistance); + + dp::GLState const & state = subrouteInfo.m_markersData->m_renderProperty.m_state; + + // Set up shaders and apply common uniforms. + dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix mv = screen.GetModelView(subrouteInfo.m_markersData->m_pivot, + kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + uniforms.SetFloatValue("u_routeParams", subrouteInfo.m_currentHalfWidth, dist); + uniforms.SetFloatValue("u_opacity", 1.0f); + + glsl::vec4 const maskColor = glsl::ToVec4(GetMaskColor(subrouteInfo.m_subroute->m_routeType, + subrouteInfo.m_subroute->m_baseDistance, + false /* arrows */)); + uniforms.SetFloatValue("u_maskColor", maskColor.r, maskColor.g, maskColor.b, maskColor.a); + + ref_ptr prg = mng->GetProgram(gpu::ROUTE_MARKER_PROGRAM); + prg->Bind(); + dp::ApplyState(state, prg); + dp::ApplyUniforms(uniforms, prg); + for (auto const & bucket : subrouteInfo.m_markersData->m_renderProperty.m_buckets) + bucket->Render(state.GetDrawAsLine()); +} + void RouteRenderer::RenderPreviewData(ScreenBase const & screen, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { @@ -521,6 +563,9 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, bool trafficShown, for (size_t i = 0; i < subroute.m_subrouteData.size(); ++i) RenderSubroute(subroute, i, screen, trafficShown, mng, commonUniforms); + // Render markers. + RenderSubrouteMarkers(subroute, screen, mng, commonUniforms); + // Render arrows. RenderSubrouteArrows(subroute, screen, mng, commonUniforms); } @@ -543,6 +588,7 @@ void RouteRenderer::AddSubrouteData(drape_ptr && subrouteData, { // Remove obsolete subroute data. it->m_subrouteData.clear(); + it->m_markersData.reset(); it->m_arrowsData.reset(); it->m_arrowBorders.clear(); @@ -589,6 +635,17 @@ void RouteRenderer::AddSubrouteArrowsData(drape_ptr && route } } +void RouteRenderer::AddSubrouteMarkersData(drape_ptr && subrouteMarkersData, + ref_ptr mng) +{ + auto const it = FindSubroute(m_subroutes, subrouteMarkersData->m_subrouteId); + if (it != m_subroutes.end()) + { + it->m_markersData = std::move(subrouteMarkersData); + BuildBuckets(it->m_markersData->m_renderProperty, mng); + } +} + RouteRenderer::Subroutes const & RouteRenderer::GetSubroutes() const { return m_subroutes; @@ -642,6 +699,7 @@ void RouteRenderer::ClearGLDependentResources() for (auto & subroute : m_subroutes) { subroute.m_subrouteData.clear(); + subroute.m_markersData.reset(); subroute.m_arrowsData.reset(); subroute.m_arrowBorders.clear(); } diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index 5a1adf6638..718cb2ace3 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -45,6 +45,8 @@ public: drape_ptr m_arrowsData; std::vector m_arrowBorders; float m_currentHalfWidth = 0.0f; + + drape_ptr m_markersData; }; using Subroutes = std::vector; @@ -63,6 +65,9 @@ public: void AddSubrouteArrowsData(drape_ptr && subrouteArrowsData, ref_ptr mng); + void AddSubrouteMarkersData(drape_ptr && subrouteMarkersData, + ref_ptr mng); + void AddPreviewRenderData(drape_ptr && renderData, ref_ptr mng); @@ -88,6 +93,9 @@ private: void RenderSubrouteArrows(SubrouteInfo const & subrouteInfo, ScreenBase const & screen, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); + void RenderSubrouteMarkers(SubrouteInfo const & subrouteInfo, ScreenBase const & screen, + ref_ptr mng, + dp::UniformValuesStorage const & commonUniforms); void RenderPreviewData(ScreenBase const & screen, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); void ClearPreviewHandles(); diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index bb66493214..fb2e08f10b 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -21,7 +21,8 @@ float const kLeftSide = 1.0f; float const kCenter = 0.0f; float const kRightSide = -1.0f; -float const kRouteDepth = 100.0f; +float const kRouteDepth = 99.0f; +float const kMarkersDepth = 100.0f; float const kArrowsDepth = 200.0f; float const kDepthPerSubroute = 200.0f; @@ -131,6 +132,10 @@ void GenerateArrowsTriangles(glsl::vec4 const & pivot, std::vector c } } +glsl::vec3 MarkerNormal(float x, float y, float z, float cosAngle, float sinAngle) +{ + return glsl::vec3(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z); +} } // namespace void RouteShape::PrepareGeometry(std::vector const & path, m2::PointD const & pivot, @@ -149,12 +154,12 @@ void RouteShape::PrepareGeometry(std::vector const & path, m2::Point // Build geometry. float length = 0.0f; - for (size_t i = 0; i < segments.size() ; ++i) - length += glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); + for (auto const & segment : segments) + length += glsl::length(segment.m_points[EndPoint] - segment.m_points[StartPoint]); float depth = baseDepth; float const depthStep = kRouteDepth / (1 + segments.size()); - for (int i = static_cast(segments.size() - 1); i >= 0; i--) + for (auto i = static_cast(segments.size() - 1); i >= 0; i--) { UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, (i < static_cast(segments.size()) - 1) ? &segments[i + 1] : nullptr); @@ -366,6 +371,80 @@ void RouteShape::PrepareArrowGeometry(std::vector const & path, m2:: } } +void RouteShape::PrepareMarkersGeometry(std::vector const & markers, + m2::PointD const & pivot, float baseDepth, + TMarkersGeometryBuffer & geometry) +{ + ASSERT(!markers.empty(), ()); + + static float const kSqrt3 = sqrt(3.0f); + static float const kSqrt2 = sqrt(2.0f); + static float const kInnerRadius = 0.6f; + static float const kOuterRadius = 1.0f; + + float const depth = baseDepth - 0.5f; + float const innerDepth = baseDepth + 0.5f; + for (SubrouteMarker const & marker : markers) + { + if (marker.m_colors.empty()) + { + LOG(LWARNING, ("Colors have not been specified.")); + continue; + } + + float const innerRadius = kInnerRadius * marker.m_scale; + float const outerRadius = kOuterRadius * marker.m_scale; + + m2::PointD const pt = MapShape::ConvertToLocal(marker.m_position, pivot, kShapeCoordScalar); + MV::TPosition outerPos(pt.x, pt.y, depth, static_cast(marker.m_distance)); + MV::TPosition innerPos(pt.x, pt.y, innerDepth, static_cast(marker.m_distance)); + + if (marker.m_colors.size() == 1) + { + dp::Color const color = df::GetColorConstant(marker.m_colors[0]); + MV::TColor const c(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), color.GetAlphaF()); + + // Here we use an equilateral triangle to render circle (incircle of a triangle). + geometry.emplace_back(outerPos, MV::TNormal(-kSqrt3, -1.0f, outerRadius), c); + geometry.emplace_back(outerPos, MV::TNormal(kSqrt3, -1.0f, outerRadius), c); + geometry.emplace_back(outerPos, MV::TNormal(0.0f, 2.0f, outerRadius), c); + } + else if (marker.m_colors.size() >= 2) + { + dp::Color const color1 = df::GetColorConstant(marker.m_colors[0]); + dp::Color const color2 = df::GetColorConstant(marker.m_colors[1]); + dp::Color const innerColor = df::GetColorConstant(marker.m_innerColor); + MV::TColor const c1(color1.GetRedF(), color1.GetGreenF(), color1.GetBlueF(), color1.GetAlphaF()); + MV::TColor const c2(color2.GetRedF(), color2.GetGreenF(), color2.GetBlueF(), color2.GetAlphaF()); + MV::TColor const ic(innerColor.GetRedF(), innerColor.GetGreenF(), + innerColor.GetBlueF(), innerColor.GetAlphaF()); + + auto const cosAngle = static_cast(m2::DotProduct(marker.m_up, m2::PointD(0.0, 1.0))); + auto const sinAngle = static_cast(m2::CrossProduct(marker.m_up, m2::PointD(0.0, 1.0))); + + // Here we use a right triangle to render half-circle. + geometry.emplace_back(outerPos, MarkerNormal(-kSqrt2, 0.0f, outerRadius, cosAngle, sinAngle), c1); + geometry.emplace_back(outerPos, MarkerNormal(0.0f, -kSqrt2, outerRadius, cosAngle, sinAngle), c1); + geometry.emplace_back(outerPos, MarkerNormal(0.0f, kSqrt2, outerRadius, cosAngle, sinAngle), c1); + + geometry.emplace_back(outerPos, MarkerNormal(kSqrt2, 0.0f, outerRadius, cosAngle, sinAngle), c2); + geometry.emplace_back(outerPos, MarkerNormal(0.0f, kSqrt2, outerRadius, cosAngle, sinAngle), c2); + geometry.emplace_back(outerPos, MarkerNormal(0.0f, -kSqrt2, outerRadius, cosAngle, sinAngle), c2); + } + + if (marker.m_colors.size() > 1 || marker.m_colors.front() != marker.m_innerColor) + { + dp::Color const innerColor = df::GetColorConstant(marker.m_innerColor); + MV::TColor const ic(innerColor.GetRedF(), innerColor.GetGreenF(), + innerColor.GetBlueF(), innerColor.GetAlphaF()); + + geometry.emplace_back(innerPos, MV::TNormal(-kSqrt3, -1.0f, innerRadius), ic); + geometry.emplace_back(innerPos, MV::TNormal(kSqrt3, -1.0f, innerRadius), ic); + geometry.emplace_back(innerPos, MV::TNormal(0.0f, 2.0f, innerRadius), ic); + } + } +} + void RouteShape::CacheRouteArrows(ref_ptr mng, m2::PolylineD const & polyline, std::vector const & borders, double baseDepthIndex, SubrouteArrowsData & routeArrowsData) @@ -427,6 +506,7 @@ drape_ptr RouteShape::CacheRoute(dp::DrapeID subrouteId, Subro subrouteData->m_endPointIndex = endIndex; subrouteData->m_pivot = subroute->m_polyline.GetLimitRect().Center(); subrouteData->m_recacheId = recacheId; + subrouteData->m_distanceOffset = subroute->m_polyline.GetLength(startIndex); TGeometryBuffer geometry; TGeometryBuffer joinsGeometry; @@ -445,6 +525,46 @@ drape_ptr RouteShape::CacheRoute(dp::DrapeID subrouteId, Subro return subrouteData; } +drape_ptr RouteShape::CacheMarkers(dp::DrapeID subrouteId, + SubrouteConstPtr subroute, int recacheId, + ref_ptr textures) +{ + if (subroute->m_markers.empty()) + return nullptr; + + auto markersData = make_unique_dp(); + markersData->m_subrouteId = subrouteId; + markersData->m_pivot = subroute->m_polyline.GetLimitRect().Center(); + markersData->m_recacheId = recacheId; + + TMarkersGeometryBuffer geometry; + auto const depth = static_cast(subroute->m_baseDepthIndex * kDepthPerSubroute + kMarkersDepth); + PrepareMarkersGeometry(subroute->m_markers, markersData->m_pivot, depth, geometry); + if (geometry.empty()) + return nullptr; + + auto state = CreateGLState(gpu::ROUTE_MARKER_PROGRAM, RenderState::GeometryLayer); + state.SetColorTexture(textures->GetSymbolsTexture()); + + // Batching. + { + uint32_t const kBatchSize = 200; + dp::Batcher batcher(kBatchSize, kBatchSize); + dp::SessionGuard guard(batcher, [&markersData](dp::GLState const & state, + drape_ptr &&b) + { + markersData->m_renderProperty.m_buckets.push_back(std::move(b)); + markersData->m_renderProperty.m_state = state; + }); + + dp::AttributeProvider provider(1 /* stream count */, static_cast(geometry.size())); + provider.InitStream(0 /* stream index */, MV::GetBindingInfo(), geometry.data()); + batcher.InsertTriangleList(state, make_ref(&provider)); + } + + return markersData; +} + void RouteShape::BatchGeometry(dp::GLState const & state, ref_ptr geometry, uint32_t geomSize, ref_ptr joinsGeometry, uint32_t joinsGeomSize, dp::BindingInfo const & bindingInfo, RouteRenderProperty & property) diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index 9760f786dc..51c228459f 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -112,6 +112,23 @@ struct SubrouteStyle } }; +// Colored circle on the subroute. +struct SubrouteMarker +{ + // Position in mercator. + m2::PointD m_position = {}; + // Distance from the beginning of route. + double m_distance = 0.0; + // Array of colors in range [0;2]. + std::vector m_colors; + // Color of inner circle. + df::ColorConstant m_innerColor; + // Normalized up vector to determine rotation of circle. + m2::PointD m_up = m2::PointD(0.0, 1.0); + // Scale (1.0 when the radius is equal to route line half-width). + float m_scale = 1.0f; +}; + struct Subroute { df::RouteType m_routeType; @@ -123,6 +140,8 @@ struct Subroute SubrouteStyleType m_styleType = SubrouteStyleType::Single; std::vector m_style; + + std::vector m_markers; }; using SubrouteConstPtr = std::shared_ptr; @@ -149,10 +168,13 @@ struct SubrouteData : public BaseSubrouteData SubrouteConstPtr m_subroute; size_t m_startPointIndex = 0; size_t m_endPointIndex = 0; + double m_distanceOffset = 0.0; }; struct SubrouteArrowsData : public BaseSubrouteData {}; +struct SubrouteMarkersData : public BaseSubrouteData {}; + struct ArrowBorders { double m_startDistance = 0.0; @@ -167,11 +189,17 @@ public: using TGeometryBuffer = buffer_vector; using AV = gpu::SolidTexturingVertex; using TArrowGeometryBuffer = buffer_vector; + using MV = gpu::RouteMarkerVertex; + using TMarkersGeometryBuffer = buffer_vector; static drape_ptr CacheRoute(dp::DrapeID subrouteId, SubrouteConstPtr subroute, size_t startIndex, size_t endIndex, int recacheId, ref_ptr textures); + static drape_ptr CacheMarkers(dp::DrapeID subrouteId, + SubrouteConstPtr subroute, int recacheId, + ref_ptr textures); + static void CacheRouteArrows(ref_ptr mng, m2::PolylineD const & polyline, std::vector const & borders, double baseDepthIndex, SubrouteArrowsData & routeArrowsData); @@ -184,6 +212,10 @@ private: m2::RectF const & texRect, float depthStep, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry); + static void PrepareMarkersGeometry(std::vector const & markers, + m2::PointD const & pivot, float baseDepth, + TMarkersGeometryBuffer & geometry); + static void BatchGeometry(dp::GLState const & state, ref_ptr geometry, uint32_t geomSize, ref_ptr joinsGeometry, uint32_t joinsGeomSize, dp::BindingInfo const & bindingInfo, RouteRenderProperty & property); diff --git a/drape_frontend/shaders/route_marker.fsh.glsl b/drape_frontend/shaders/route_marker.fsh.glsl new file mode 100644 index 0000000000..0d5bb799f0 --- /dev/null +++ b/drape_frontend/shaders/route_marker.fsh.glsl @@ -0,0 +1,31 @@ +// Warning! Beware to use this shader. "discard" command may significally reduce performance. +// Unfortunately some CG algorithms cannot be implemented on OpenGL ES 2.0 without discarding +// fragments from depth buffer. + +#ifdef SAMSUNG_GOOGLE_NEXUS +uniform sampler2D u_colorTex; +#endif + +uniform vec2 u_routeParams; +uniform vec4 u_maskColor; +uniform float u_opacity; + +varying vec4 v_radius; +varying vec4 v_color; + +const float kAntialiasingPixelsCount = 2.5; + +void main() +{ + vec4 finalColor = v_color; + + float aaRadius = max(v_radius.z - kAntialiasingPixelsCount, 0.0); + float stepValue = smoothstep(aaRadius * aaRadius, v_radius.z * v_radius.z, + dot(v_radius.xy, v_radius.xy)); + finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue); + if (finalColor.a < 0.01 || u_routeParams.y > v_radius.w) + discard; + + finalColor = vec4(mix(finalColor.rgb, u_maskColor.rgb, u_maskColor.a), finalColor.a); + gl_FragColor = samsungGoogleNexusWorkaround(finalColor); +} diff --git a/drape_frontend/shaders/route_marker.vsh.glsl b/drape_frontend/shaders/route_marker.vsh.glsl new file mode 100644 index 0000000000..497442459c --- /dev/null +++ b/drape_frontend/shaders/route_marker.vsh.glsl @@ -0,0 +1,24 @@ +attribute vec4 a_position; +attribute vec3 a_normal; +attribute vec4 a_color; + +uniform mat4 modelView; +uniform mat4 projection; +uniform mat4 pivotTransform; + +uniform vec2 u_routeParams; + +varying vec4 v_radius; +varying vec4 v_color; + +void main() +{ + float r = u_routeParams.x * a_normal.z; + vec4 radius = vec4(a_normal.xy * r, r, a_position.w); + vec4 pos = vec4(a_position.xy, 0, 1) * modelView; + vec2 shiftedPos = radius.xy + pos.xy; + pos = vec4(shiftedPos, a_position.z, 1.0) * projection; + gl_Position = applyPivotTransform(pos, pivotTransform, 0.0); + v_radius = radius; + v_color = a_color; +} diff --git a/drape_frontend/shaders/shader_index.txt b/drape_frontend/shaders/shader_index.txt index b53e6bf915..f6de9a5d5b 100644 --- a/drape_frontend/shaders/shader_index.txt +++ b/drape_frontend/shaders/shader_index.txt @@ -23,6 +23,7 @@ BOOKMARK_ANIM_PROGRAM user_mark.vsh.glsl discarded_texturing.fsh.glsl ROUTE_PROGRAM route.vsh.glsl route.fsh.glsl ROUTE_DASH_PROGRAM route.vsh.glsl route_dash.fsh.glsl ROUTE_ARROW_PROGRAM route_arrow.vsh.glsl route_arrow.fsh.glsl +ROUTE_MARKER_PROGRAM route_marker.vsh.glsl route_marker.fsh.glsl CIRCLE_POINT_PROGRAM circle_point.vsh.glsl circle_point.fsh.glsl DEBUG_RECT_PROGRAM debug_rect.vsh.glsl debug_rect.fsh.glsl SCREEN_QUAD_PROGRAM screen_quad.vsh.glsl texturing.fsh.glsl diff --git a/geometry/polyline2d.hpp b/geometry/polyline2d.hpp index f214b72e4d..673df5cd88 100644 --- a/geometry/polyline2d.hpp +++ b/geometry/polyline2d.hpp @@ -51,6 +51,14 @@ public: return dist; } + double GetLength(size_t pointIndex) const + { + double dist = 0; + for (size_t i = 0; i < min(pointIndex, m_points.size() - 1); ++i) + dist += m_points[i].Length(m_points[i + 1]); + return dist; + } + double CalcMinSquaredDistance(m2::Point const & point) const { double res = numeric_limits::max(); @@ -140,8 +148,8 @@ public: } vector> result(endPointIndex - startPointIndex + 1); - for (size_t i = startPointIndex; i <= endPointIndex; ++i) - result[i] = m_points[i]; + for (size_t i = startPointIndex, j = 0; i <= endPointIndex; ++i, ++j) + result[j] = m_points[i]; return result; } diff --git a/map/bookmark.cpp b/map/bookmark.cpp index 7bc0cee984..026b5385b8 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -752,7 +752,7 @@ void BookmarkCategory::SaveToKML(std::ostream & s) s << "