From 01be5f1c98d7d2c20f42392fdf0425c7d904a4f5 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Wed, 12 Jul 2017 14:42:09 +0300 Subject: [PATCH] User marks with overlay and title. --- drape/glstate.hpp | 1 + drape/overlay_handle.cpp | 9 +- drape/overlay_handle.hpp | 3 +- drape_frontend/apply_feature_functors.cpp | 28 +++--- drape_frontend/colored_symbol_shape.cpp | 4 +- drape_frontend/drape_engine.cpp | 8 +- drape_frontend/frontend_renderer.cpp | 28 +++--- drape_frontend/frontend_renderer.hpp | 44 ++++----- drape_frontend/path_text_shape.cpp | 4 +- drape_frontend/poi_symbol_shape.cpp | 7 +- drape_frontend/shape_view_params.hpp | 11 ++- drape_frontend/text_shape.cpp | 37 +++++++- drape_frontend/text_shape.hpp | 4 +- drape_frontend/user_mark_shapes.cpp | 103 ++++++++++++++++------ drape_frontend/user_mark_shapes.hpp | 6 +- drape_frontend/user_marks_provider.hpp | 16 ++-- map/routing_mark.cpp | 47 ++++++++++ map/routing_mark.hpp | 17 ++-- map/track.cpp | 7 +- map/track.hpp | 4 +- map/user_mark.cpp | 5 ++ map/user_mark.hpp | 10 ++- 22 files changed, 299 insertions(+), 104 deletions(-) diff --git a/drape/glstate.hpp b/drape/glstate.hpp index 06684caad8..2e185639f2 100644 --- a/drape/glstate.hpp +++ b/drape/glstate.hpp @@ -42,6 +42,7 @@ public: OverlayLayer, UserMarkLayer, NavigationLayer, + RoutingMarkLayer, Gui }; diff --git a/drape/overlay_handle.cpp b/drape/overlay_handle.cpp index 83874428d1..ca4c2fb68a 100644 --- a/drape/overlay_handle.cpp +++ b/drape/overlay_handle.cpp @@ -274,7 +274,7 @@ uint64_t CalculateOverlayPriority(int minZoomLevel, uint8_t rank, float depth) static_cast(0xFFFF); } -uint64_t CalculateSpecialModePriority(int specialPriority) +uint64_t CalculateSpecialModePriority(uint16_t specialPriority) { static uint64_t constexpr kMask = ~static_cast(0xFFFF); uint64_t priority = dp::kPriorityMaskAll; @@ -282,4 +282,11 @@ uint64_t CalculateSpecialModePriority(int specialPriority) priority |= specialPriority; return priority; } + +uint64_t CalculateUserMarkPriority(int minZoomLevel, uint16_t specialPriority) +{ + uint8_t const minZoom = 0xFF - static_cast(std::max(minZoomLevel, 0)); + uint64_t priority = ~dp::kPriorityMaskZoomLevel; + return priority | (static_cast(minZoom) << 56) | static_cast(specialPriority); +} } // namespace dp diff --git a/drape/overlay_handle.hpp b/drape/overlay_handle.hpp index bc0a9fb573..3b19de6881 100644 --- a/drape/overlay_handle.hpp +++ b/drape/overlay_handle.hpp @@ -219,5 +219,6 @@ private: }; uint64_t CalculateOverlayPriority(int minZoomLevel, uint8_t rank, float depth); -uint64_t CalculateSpecialModePriority(int specialPriority); +uint64_t CalculateSpecialModePriority(uint16_t specialPriority); +uint64_t CalculateUserMarkPriority(int minZoomLevel, uint16_t specialPriority); } // namespace dp diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index ff6a0703a0..24f76100e6 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -599,8 +599,9 @@ void ApplyPointFeature::Finish(ref_ptr texMng, params.m_hasArea = m_hasArea; params.m_prioritized = prioritized || m_createdByEditor; params.m_obsoleteInEditor = m_obsoleteInEditor; - params.m_specialDisplacementMode = specialDisplacementMode; - params.m_specialModePriority = specialModePriority; + params.m_specialDisplacement = specialDisplacementMode ? SpecialDisplacement::SpecialMode + : SpecialDisplacement::None; + params.m_specialPriority = specialModePriority; m_insertShape(make_unique_dp(m_centerPoint, params, m_tileKey, 0 /* text index */)); @@ -611,10 +612,12 @@ void ApplyPointFeature::Finish(ref_ptr texMng, for (auto textParams : m_textParams) { - textParams.m_specialDisplacementMode = specialDisplacementMode; - textParams.m_specialModePriority = specialModePriority; + textParams.m_specialDisplacement = specialDisplacementMode ? SpecialDisplacement::SpecialMode + : SpecialDisplacement::None; + textParams.m_specialPriority = specialModePriority; m_insertShape(make_unique_dp(m_centerPoint, textParams, m_tileKey, - hasPOI, symbolSize, 0 /* textIndex */)); + hasPOI, symbolSize, + dp::Center /* symbolAnchor */, 0 /* textIndex */)); } } @@ -1080,10 +1083,10 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ref_ptr texMng, params.m_baseGtoPScale = m_currentScaleGtoP; bool const navigationEnabled = GetStyleReader().IsCarNavigationStyle(); if (navigationEnabled) - params.m_specialDisplacementMode = true; + params.m_specialDisplacement = SpecialDisplacement::SpecialMode; uint32_t textIndex = kPathTextBaseTextIndex; for (auto const & spline : m_clippedSplines) { PathTextViewParams p = params; if (navigationEnabled) - p.m_specialModePriority = CalculateNavigationPathTextPriority(textIndex); + p.m_specialPriority = CalculateNavigationPathTextPriority(textIndex); auto shape = make_unique_dp(spline, p, m_tileKey, textIndex); if (!shape->CalculateLayout(texMng)) @@ -1198,7 +1201,8 @@ void ApplyLineFeatureAdditional::Finish(ref_ptr texMng, continue; m_insertShape(make_unique_dp(shieldPos, textParams, m_tileKey, true /* hasPOI */, - m2::PointF(0.0f, 0.0f) /* symbolSize */, textIndex)); + m2::PointF(0.0f, 0.0f) /* symbolSize */, + dp::Center /* symbolAnchor */, textIndex)); if (IsColoredRoadShield(shield)) m_insertShape(make_unique_dp(shieldPos, symbolParams, m_tileKey, textIndex)); else if (IsSymbolRoadShield(shield)) diff --git a/drape_frontend/colored_symbol_shape.cpp b/drape_frontend/colored_symbol_shape.cpp index 6e491fb75f..9e23d51d2e 100644 --- a/drape_frontend/colored_symbol_shape.cpp +++ b/drape_frontend/colored_symbol_shape.cpp @@ -248,8 +248,8 @@ void ColoredSymbolShape::Draw(ref_ptr batcher, uint64_t ColoredSymbolShape::GetOverlayPriority() const { // Special displacement mode. - if (m_params.m_specialDisplacementMode) - return dp::CalculateSpecialModePriority(m_params.m_specialModePriority); + if (m_params.m_specialDisplacement == SpecialDisplacement::SpecialMode) + return dp::CalculateSpecialModePriority(m_params.m_specialPriority); return dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, m_params.m_depth); } diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 7d35e6a4c6..c06b9f101a 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -222,12 +222,16 @@ void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provi auto renderInfo = make_unique_dp(); renderInfo->m_anchor = mark->GetAnchor(); renderInfo->m_depth = mark->GetDepth(); + renderInfo->m_depthLayer = mark->GetDepthLayer(); + renderInfo->m_minZoom = mark->GetMinZoom(); renderInfo->m_isVisible = mark->IsVisible(); renderInfo->m_pivot = mark->GetPivot(); renderInfo->m_pixelOffset = mark->GetPixelOffset(); renderInfo->m_runCreationAnim = mark->HasCreationAnimation(); renderInfo->m_symbolName = mark->GetSymbolName(); renderInfo->m_titleDecl = mark->GetTitleDecl(); + renderInfo->m_symbolHasPriority = mark->SymbolHasPriority(); + renderInfo->m_titleHasPriority = mark->TitleHasPriority(); renderInfo->m_priority = mark->GetProirity(); marksRenderCollection->emplace(mark->GetId(), std::move(renderInfo)); mark->AcceptChanges(); @@ -243,13 +247,15 @@ void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provi if (mark->IsDirty()) { auto renderInfo = make_unique_dp(); + renderInfo->m_minZoom = mark->GetMinZoom(); + renderInfo->m_depthLayer = mark->GetDepthLayer(); renderInfo->m_spline = m2::SharedSpline(mark->GetPoints()); renderInfo->m_layers.reserve(mark->GetLayerCount()); for (size_t layerIndex = 0, layersCount = mark->GetLayerCount(); layerIndex < layersCount; ++layerIndex) { renderInfo->m_layers.emplace_back(mark->GetColor(layerIndex), mark->GetWidth(layerIndex), - mark->GetLayerDepth(layerIndex)); + mark->GetDepth(layerIndex)); } linesRenderCollection->emplace(mark->GetId(), std::move(renderInfo)); mark->AcceptChanges(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index b81fe6d85c..77ef951256 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1136,7 +1136,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) GLFunctions::glClear(gl_const::GLColorBit | gl_const::GLDepthBit | gl_const::GLStencilBit); Render2dLayer(modelView); - RenderUserLinesLayer(modelView); + RenderUserMarksLayer(modelView, RenderLayer::UserLineID); if (m_buildingsFramebuffer->IsSupported()) { @@ -1186,7 +1186,8 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) { StencilWriterGuard guard(make_ref(m_postprocessRenderer)); - RenderUserMarksLayer(modelView); + RenderUserMarksLayer(modelView, RenderLayer::UserMarkID); + RenderUserMarksLayer(modelView, RenderLayer::RoutingMarkID); } m_myPositionController->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), @@ -1284,9 +1285,9 @@ void FrontendRenderer::RenderTrafficAndRouteLayer(ScreenBase const & modelView) make_ref(m_gpuProgramManager), m_generalUniforms); } -void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView) +void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView, RenderLayer::RenderLayerID layerId) { - auto & renderGroups = m_layers[RenderLayer::UserMarkID].m_renderGroups; + auto & renderGroups = m_layers[layerId].m_renderGroups; if (renderGroups.empty()) return; @@ -1312,7 +1313,8 @@ void FrontendRenderer::RenderUserLinesLayer(ScreenBase const & modelView) void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) { static std::vector layers = {RenderLayer::OverlayID, - RenderLayer::NavigationID}; + RenderLayer::NavigationID, + RenderLayer::RoutingMarkID}; BeginUpdateOverlayTree(modelView); for (auto const & layerId : layers) { @@ -2046,14 +2048,14 @@ void FrontendRenderer::CheckAndRunFirstLaunchAnimation() FrontendRenderer::RenderLayer::RenderLayerID FrontendRenderer::RenderLayer::GetLayerID(dp::GLState const & state) { - if (state.GetDepthLayer() == dp::GLState::OverlayLayer) - return OverlayID; - if (state.GetDepthLayer() == dp::GLState::UserMarkLayer) - return UserMarkID; - if (state.GetDepthLayer() == dp::GLState::UserLineLayer) - return UserLineID; - if (state.GetDepthLayer() == dp::GLState::NavigationLayer) - return NavigationID; + switch (state.GetDepthLayer()) + { + case dp::GLState::OverlayLayer: return OverlayID; + case dp::GLState::UserMarkLayer: return UserMarkID; + case dp::GLState::UserLineLayer: return UserLineID; + case dp::GLState::RoutingMarkLayer: return RoutingMarkID; + case dp::GLState::NavigationLayer: return NavigationID; + } if (state.GetProgram3dIndex() == gpu::AREA_3D_PROGRAM || state.GetProgram3dIndex() == gpu::AREA_3D_OUTLINE_PROGRAM) diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 4c04e120e0..a7d961ed92 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -145,12 +145,33 @@ private: void RefreshPivotTransform(ScreenBase const & screen); void RefreshBgColor(); + struct RenderLayer + { + enum RenderLayerID + { + Geometry2dID, + UserLineID, + OverlayID, + Geometry3dID, + UserMarkID, + NavigationID, + RoutingMarkID, + LayerCountID + }; + + static RenderLayerID GetLayerID(dp::GLState const & renderGroup); + + std::vector> m_renderGroups; + bool m_isDirty = false; + + void Sort(ref_ptr overlayTree); + }; // Render part of scene void Render2dLayer(ScreenBase const & modelView); void Render3dLayer(ScreenBase const & modelView, bool useFramebuffer); void RenderOverlayLayer(ScreenBase const & modelView); void RenderNavigationOverlayLayer(ScreenBase const & modelView); - void RenderUserMarksLayer(ScreenBase const & modelView); + void RenderUserMarksLayer(ScreenBase const & modelView, RenderLayer::RenderLayerID layerId); void RenderUserLinesLayer(ScreenBase const & modelView); void RenderTrafficAndRouteLayer(ScreenBase const & modelView); @@ -235,27 +256,6 @@ private: drape_ptr m_gpuProgramManager; - struct RenderLayer - { - enum RenderLayerID - { - Geometry2dID, - UserLineID, - OverlayID, - Geometry3dID, - UserMarkID, - NavigationID, - LayerCountID - }; - - static RenderLayerID GetLayerID(dp::GLState const & renderGroup); - - std::vector> m_renderGroups; - bool m_isDirty = false; - - void Sort(ref_ptr overlayTree); - }; - std::array m_layers; drape_ptr m_guiRenderer; diff --git a/drape_frontend/path_text_shape.cpp b/drape_frontend/path_text_shape.cpp index baf1701939..7271484017 100644 --- a/drape_frontend/path_text_shape.cpp +++ b/drape_frontend/path_text_shape.cpp @@ -246,8 +246,8 @@ uint64_t PathTextShape::GetOverlayPriority(uint32_t textIndex, size_t textLength // [6 bytes - standard overlay priority][1 byte - length][1 byte - path text index]. // Special displacement mode. - if (m_params.m_specialDisplacementMode) - return dp::CalculateSpecialModePriority(m_params.m_specialModePriority); + if (m_params.m_specialDisplacement == SpecialDisplacement::SpecialMode) + return dp::CalculateSpecialModePriority(m_params.m_specialPriority); static uint64_t constexpr kMask = ~static_cast(0xFFFF); uint64_t priority = dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index 7aaee945e2..a292acf5d0 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -165,8 +165,11 @@ uint64_t PoiSymbolShape::GetOverlayPriority() const return dp::kPriorityMaskAll; // Special displacement mode. - if (m_params.m_specialDisplacementMode) - return dp::CalculateSpecialModePriority(m_params.m_specialModePriority); + if (m_params.m_specialDisplacement == SpecialDisplacement::SpecialMode) + return dp::CalculateSpecialModePriority(m_params.m_specialPriority); + + if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) + return dp::CalculateUserMarkPriority(m_params.m_minVisibleScale, m_params.m_specialPriority); // Set up minimal priority for shapes which belong to areas. if (m_params.m_hasArea) diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index 4b9b85f364..33aa3df74f 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -26,10 +26,17 @@ struct CommonViewParams m2::PointD m_tileCenter; }; +enum class SpecialDisplacement +{ + None, + SpecialMode, + UserMark +}; + struct CommonOverlayViewParams : public CommonViewParams { - bool m_specialDisplacementMode = false; - uint16_t m_specialModePriority = std::numeric_limits::max();; + SpecialDisplacement m_specialDisplacement = SpecialDisplacement::None; + uint16_t m_specialPriority = std::numeric_limits::max(); }; struct PoiSymbolViewParams : CommonOverlayViewParams diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index 030ccfb56f..4856d8f1d7 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -110,13 +110,15 @@ private: } // namespace TextShape::TextShape(m2::PointD const & basePoint, TextViewParams const & params, - TileKey const & tileKey, bool hasPOI, m2::PointF const & symbolSize, + TileKey const & tileKey, bool hasPOI, + m2::PointF const & symbolSize, dp::Anchor symbolAnchor, uint32_t textIndex) : m_basePoint(basePoint) , m_params(params) , m_tileCoords(tileKey.GetTileCoords()) , m_hasPOI(hasPOI) , m_symbolSize(symbolSize) + , m_symbolAnchor(symbolAnchor) , m_textIndex(textIndex) {} @@ -199,6 +201,32 @@ void TextShape::Draw(ref_ptr batcher, ref_ptr t secondaryOffset.x = primaryOffset.x; } + if (m_symbolAnchor & dp::Top) + { + primaryOffset.y += halfSymbolH; + if (secondaryLayout != nullptr) + secondaryOffset.y += halfSymbolH; + } + else if (m_symbolAnchor & dp::Bottom) + { + primaryOffset.y -= halfSymbolH; + if (secondaryLayout != nullptr) + secondaryOffset.y -= halfSymbolH; + } + + if (m_symbolAnchor & dp::Left) + { + primaryOffset.x += halfSymbolW; + if (secondaryLayout != nullptr) + secondaryOffset.x += halfSymbolW; + } + else if (m_symbolAnchor & dp::Right) + { + primaryOffset.x -= halfSymbolW; + if (secondaryLayout != nullptr) + secondaryOffset.x -= halfSymbolW; + } + if (primaryLayout.GetGlyphCount() > 0) { DrawSubString(primaryLayout, titleDecl.m_primaryTextFont, primaryOffset, batcher, @@ -337,8 +365,11 @@ uint64_t TextShape::GetOverlayPriority() const return dp::kPriorityMaskAll; // Special displacement mode. - if (m_params.m_specialDisplacementMode) - return dp::CalculateSpecialModePriority(m_params.m_specialModePriority); + if (m_params.m_specialDisplacement == SpecialDisplacement::SpecialMode) + return dp::CalculateSpecialModePriority(m_params.m_specialPriority); + + if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) + return dp::CalculateUserMarkPriority(m_params.m_minVisibleScale, m_params.m_specialPriority); // Set up minimal priority for shapes which belong to areas if (m_params.m_hasArea) diff --git a/drape_frontend/text_shape.hpp b/drape_frontend/text_shape.hpp index e5176e5e3d..f520dcd783 100644 --- a/drape_frontend/text_shape.hpp +++ b/drape_frontend/text_shape.hpp @@ -16,7 +16,8 @@ class TextShape : public MapShape { public: TextShape(m2::PointD const & basePoint, TextViewParams const & params, - TileKey const & tileKey, bool hasPOI, m2::PointF const & symbolSize, uint32_t textIndex); + TileKey const & tileKey, bool hasPOI, m2::PointF const & symbolSize, + dp::Anchor symbolAnchor, uint32_t textIndex); void Draw(ref_ptr batcher, ref_ptr textures) const override; MapShapeType GetType() const override { return MapShapeType::OverlayType; } @@ -43,6 +44,7 @@ private: m2::PointI m_tileCoords; bool m_hasPOI; m2::PointF m_symbolSize; + dp::Anchor m_symbolAnchor; uint32_t m_textIndex; bool m_disableDisplacing = false; diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index c3df07d4c9..364de5dc73 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -2,8 +2,10 @@ #include "drape_frontend/line_shape.hpp" #include "drape_frontend/map_shape.hpp" +#include "drape_frontend/poi_symbol_shape.hpp" #include "drape_frontend/shader_def.hpp" #include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/text_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/visual_params.hpp" @@ -11,6 +13,8 @@ #include "drape/attribute_provider.hpp" #include "drape/batcher.hpp" +#include "indexer/feature_decl.hpp" + #include "geometry/clipping.hpp" namespace df @@ -87,9 +91,9 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture using UPV = UserPointVertex; uint32_t const vertexCount = static_cast(marksId.size()) * dp::Batcher::VertexPerQuad; buffer_vector buffer; - buffer.reserve(vertexCount); dp::TextureManager::SymbolRegion region; + dp::GLState::DepthLayer depthLayer = dp::GLState::UserMarkLayer; for (auto const id : marksId) { auto const it = renderParams.find(id); @@ -99,38 +103,83 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture if (!renderInfo.m_isVisible) continue; - textures->GetSymbolRegion(renderInfo.m_symbolName, region); - m2::RectF const & texRect = region.GetTexRect(); - m2::PointF const pxSize = region.GetPixelSize(); - dp::Anchor const anchor = renderInfo.m_anchor; - m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), - kShapeCoordScalar); - glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth); - bool const runAnim = renderInfo.m_runCreationAnim; - renderInfo.m_runCreationAnim = false; + m2::PointD const tileCenter = tileKey.GetGlobalRect().Center(); + depthLayer = renderInfo.m_depthLayer; - glsl::vec2 left, right, up, down; - AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); - AlignVertical(pxSize.y * 0.5f, anchor, up, down); + if (renderInfo.m_symbolHasPriority) + { + PoiSymbolViewParams params((FeatureID())); + params.m_depth = renderInfo.m_depth; + params.m_depthLayer = renderInfo.m_depthLayer; + params.m_minVisibleScale = renderInfo.m_minZoom; + params.m_specialDisplacement = SpecialDisplacement::UserMark; + params.m_specialPriority = renderInfo.m_priority; + PoiSymbolShape(renderInfo.m_pivot, params, tileKey, + 0 /* textIndex */).Draw(&batcher, textures); + } + else + { + buffer.reserve(vertexCount); - m2::PointD const pixelOffset = renderInfo.m_pixelOffset; - glsl::vec2 const offset(pixelOffset.x, pixelOffset.y); + textures->GetSymbolRegion(renderInfo.m_symbolName, region); + m2::RectF const & texRect = region.GetTexRect(); + m2::PointF const pxSize = region.GetPixelSize(); + dp::Anchor const anchor = renderInfo.m_anchor; + m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileCenter, + kShapeCoordScalar); + glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth); + bool const runAnim = renderInfo.m_runCreationAnim; + renderInfo.m_runCreationAnim = false; - buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim); - buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim); - buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim); - buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); + glsl::vec2 left, right, up, down; + AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); + AlignVertical(pxSize.y * 0.5f, anchor, up, down); + + m2::PointD const pixelOffset = renderInfo.m_pixelOffset; + glsl::vec2 const offset(pixelOffset.x, pixelOffset.y); + + buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim); + buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim); + buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim); + buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); + } + + if (renderInfo.m_titleDecl != nullptr && !renderInfo.m_titleDecl->m_primaryText.empty()) + { + TextViewParams params; + params.m_tileCenter = tileCenter; + params.m_titleDecl = *renderInfo.m_titleDecl; + params.m_depth = renderInfo.m_depth; + params.m_depthLayer = renderInfo.m_depthLayer; + params.m_minVisibleScale = renderInfo.m_minZoom; + if (renderInfo.m_titleHasPriority) + { + params.m_specialDisplacement = SpecialDisplacement::UserMark; + params.m_specialPriority = renderInfo.m_priority; + } + + dp::TextureManager::SymbolRegion region; + textures->GetSymbolRegion(renderInfo.m_symbolName, region); + m2::PointF const symbolSize = region.GetPixelSize(); + + TextShape(renderInfo.m_pivot, params, tileKey, false /* hasPOI */, + symbolSize, renderInfo.m_anchor, + 0 /* textIndex */).Draw(&batcher, textures); + } } - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); - state.SetTextureFilter(gl_const::GLNearest); + if (!buffer.empty()) + { + dp::GLState state(gpu::BOOKMARK_PROGRAM, depthLayer); + state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); + state.SetColorTexture(region.GetTexture()); + state.SetTextureFilter(gl_const::GLNearest); - dp::AttributeProvider attribProvider(1, static_cast(buffer.size())); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + dp::AttributeProvider attribProvider(1, static_cast(buffer.size())); + attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); - batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + } } void CacheUserLines(TileKey const & tileKey, ref_ptr textures, @@ -188,7 +237,7 @@ void CacheUserLines(TileKey const & tileKey, ref_ptr texture params.m_join = dp::RoundJoin; params.m_color = layer.m_color; params.m_depth = layer.m_depth; - params.m_depthLayer = dp::GLState::UserLineLayer; + params.m_depthLayer = renderInfo.m_depthLayer; params.m_width = layer.m_width * vs; params.m_minVisibleScale = 1; params.m_rank = 0; diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index 92ad10fafc..8001770111 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -20,8 +20,11 @@ struct UserMarkRenderParams std::string m_symbolName; dp::Anchor m_anchor = dp::Center; drape_ptr m_titleDecl; - uint16_t m_priority; + bool m_symbolHasPriority = false; + bool m_titleHasPriority = false; + uint16_t m_priority = 0; float m_depth = 0.0; + dp::GLState::DepthLayer m_depthLayer = dp::GLState::UserMarkLayer; bool m_runCreationAnim = false; bool m_isVisible = true; }; @@ -43,6 +46,7 @@ struct LineLayer struct UserLineRenderParams { int m_minZoom = 1; + dp::GLState::DepthLayer m_depthLayer = dp::GLState::UserLineLayer; std::vector m_layers; m2::SharedSpline m_spline; }; diff --git a/drape_frontend/user_marks_provider.hpp b/drape_frontend/user_marks_provider.hpp index dd3e5716b5..f5f51a412a 100644 --- a/drape_frontend/user_marks_provider.hpp +++ b/drape_frontend/user_marks_provider.hpp @@ -1,6 +1,7 @@ #pragma once #include "drape/drape_global.hpp" +#include "drape/glstate.hpp" #include "drape/pointers.hpp" #include "geometry/polyline2d.hpp" @@ -29,11 +30,14 @@ public: virtual std::string GetSymbolName() const = 0; virtual dp::Anchor GetAnchor() const = 0; virtual float GetDepth() const = 0; + virtual dp::GLState::DepthLayer GetDepthLayer() const = 0; virtual bool HasCreationAnimation() const = 0; - virtual bool IsVisible() const { return true; } - - virtual drape_ptr GetTitleDecl() const { return nullptr; } - virtual uint16_t GetProirity() const { return 0; } + virtual bool IsVisible() const = 0; + virtual drape_ptr GetTitleDecl() const = 0; + virtual uint16_t GetProirity() const = 0; + virtual bool SymbolHasPriority() const = 0; + virtual bool TitleHasPriority() const = 0; + virtual int GetMinZoom() const = 0; private: uint32_t m_id; @@ -50,10 +54,12 @@ public: virtual uint32_t GetId() const { return m_id; } + virtual int GetMinZoom() const = 0; + virtual dp::GLState::DepthLayer GetDepthLayer() const = 0; virtual size_t GetLayerCount() const = 0; virtual dp::Color const & GetColor(size_t layerIndex) const = 0; virtual float GetWidth(size_t layerIndex) const = 0; - virtual float GetLayerDepth(size_t layerIndex) const = 0; + virtual float GetDepth(size_t layerIndex) const = 0; virtual std::vector const & GetPoints() const = 0; private: diff --git a/map/routing_mark.cpp b/map/routing_mark.cpp index b2366131cf..05b7c61fda 100644 --- a/map/routing_mark.cpp +++ b/map/routing_mark.cpp @@ -6,6 +6,11 @@ RouteMarkPoint::RouteMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container) : UserMark(ptOrg, container) { + m_titleDecl.m_anchor = dp::Top; + m_titleDecl.m_primaryTextFont.m_color = dp::Color::Black(); + m_titleDecl.m_primaryTextFont.m_outlineColor = dp::Color::White(); + m_titleDecl.m_primaryTextFont.m_size = 22; + m_markData.m_position = ptOrg; } @@ -16,6 +21,48 @@ dp::Anchor RouteMarkPoint::GetAnchor() const return dp::Center; } +dp::GLState::DepthLayer RouteMarkPoint::GetDepthLayer() const +{ + return dp::GLState::RoutingMarkLayer; +} + +void RouteMarkPoint::SetRoutePointType(RouteMarkType type) +{ + SetDirty(); + m_markData.m_pointType = type; +} + +void RouteMarkPoint::SetIntermediateIndex(int8_t index) +{ + SetDirty(); + m_markData.m_intermediateIndex = index; +} + +void RouteMarkPoint::SetIsMyPosition(bool isMyPosition) +{ + SetDirty(); + m_markData.m_isMyPosition = isMyPosition; +} + +void RouteMarkPoint::SetPassed(bool isPassed) +{ + SetDirty(); + m_markData.m_isPassed = isPassed; +} + +void RouteMarkPoint::SetMarkData(RouteMarkData && data) +{ + SetDirty(); + m_markData = std::move(data); + m_titleDecl.m_primaryText = m_markData.m_name; +} + +drape_ptr RouteMarkPoint::GetTitleDecl() const +{ + drape_ptr titleDecl = make_unique_dp(m_titleDecl); + return titleDecl; +} + std::string RouteMarkPoint::GetSymbolName() const { switch (m_markData.m_pointType) diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index fd0b3ca7eb..35e71626a8 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -32,27 +32,34 @@ public: void SetIsVisible(bool isVisible) { m_markData.m_isVisible = isVisible; } dp::Anchor GetAnchor() const override; + dp::GLState::DepthLayer GetDepthLayer() const override; std::string GetSymbolName() const override; UserMark::Type GetMarkType() const override { return Type::ROUTING; } RouteMarkType GetRoutePointType() const { return m_markData.m_pointType; } - void SetRoutePointType(RouteMarkType type) { m_markData.m_pointType = type; } + void SetRoutePointType(RouteMarkType type); - void SetIntermediateIndex(int8_t index) { m_markData.m_intermediateIndex = index; } + void SetIntermediateIndex(int8_t index); int8_t GetIntermediateIndex() const { return m_markData.m_intermediateIndex; } - void SetIsMyPosition(bool isMyPosition) { m_markData.m_isMyPosition = isMyPosition; } + void SetIsMyPosition(bool isMyPosition); bool IsMyPosition() const { return m_markData.m_isMyPosition; } - void SetPassed(bool isPassed) { m_markData.m_isPassed = isPassed; } + void SetPassed(bool isPassed); bool IsPassed() const { return m_markData.m_isPassed; } RouteMarkData const & GetMarkData() const { return m_markData; } - void SetMarkData(RouteMarkData && data) { m_markData = std::move(data); } + void SetMarkData(RouteMarkData && data); + + drape_ptr GetTitleDecl() const override; + + bool SymbolHasPriority() const override { return false; } + bool TitleHasPriority() const override { return true; } private: RouteMarkData m_markData; + dp::TitleDecl m_titleDecl; }; class RouteUserMarkContainer : public UserMarkContainer diff --git a/map/track.cpp b/map/track.cpp index 7a921e9ef5..6271c73acb 100644 --- a/map/track.cpp +++ b/map/track.cpp @@ -42,6 +42,11 @@ double Track::GetLengthMeters() const return res; } +dp::GLState::DepthLayer Track::GetDepthLayer() const +{ + return dp::GLState::UserLineLayer; +} + size_t Track::GetLayerCount() const { return m_params.m_colors.size(); @@ -57,7 +62,7 @@ float Track::GetWidth(size_t layerIndex) const return m_params.m_colors[layerIndex].m_lineWidth; } -float Track::GetLayerDepth(size_t layerIndex) const +float Track::GetDepth(size_t layerIndex) const { return 0 + layerIndex * 10; } diff --git a/map/track.hpp b/map/track.hpp index d232004e1b..9905fbcc55 100644 --- a/map/track.hpp +++ b/map/track.hpp @@ -42,10 +42,12 @@ public: m2::RectD GetLimitRect() const; double GetLengthMeters() const; + int GetMinZoom() const override { return 1; } + dp::GLState::DepthLayer GetDepthLayer() const override; size_t GetLayerCount() const override; dp::Color const & GetColor(size_t layerIndex) const override; float GetWidth(size_t layerIndex) const override; - float GetLayerDepth(size_t layerIndex) const override; + float GetDepth(size_t layerIndex) const override; std::vector const & GetPoints() const override; private: diff --git a/map/user_mark.cpp b/map/user_mark.cpp index 9dd194e775..58d8bdc3c3 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -32,6 +32,11 @@ float UserMark::GetDepth() const return GetContainer()->GetPointDepth(); } +dp::GLState::DepthLayer UserMark::GetDepthLayer() const +{ + return dp::GLState::UserMarkLayer; +} + bool UserMark::HasCreationAnimation() const { return false; diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 92a605d91e..71ae0da086 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -35,15 +35,21 @@ public: UserMark(m2::PointD const & ptOrg, UserMarkContainer * container); virtual ~UserMark() {} + // df::UserPointMark overrides. bool IsDirty() const override { return m_isDirty; } void AcceptChanges() const override { m_isDirty = false; } - - // df::UserPointMark overrides. + bool IsVisible() const override { return true; } m2::PointD const & GetPivot() const override; m2::PointD GetPixelOffset() const override; dp::Anchor GetAnchor() const override; float GetDepth() const override; + dp::GLState::DepthLayer GetDepthLayer() const override; bool HasCreationAnimation() const override; + drape_ptr GetTitleDecl() const override { return nullptr; } + uint16_t GetProirity() const override { return 0xFFFF; } + bool SymbolHasPriority() const override { return false; } + bool TitleHasPriority() const override { return false; } + int GetMinZoom() const override { return 1; } UserMarkContainer const * GetContainer() const; ms::LatLon GetLatLon() const;