diff options
author | Daria Volvenkova <d.volvenkova@corp.mail.ru> | 2016-09-06 15:32:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-06 15:32:24 +0300 |
commit | 0bcb0eb42bd19e652a2012148b76c3c96692dcdf (patch) | |
tree | 239d7a6ca3a16c7807f69b6da69a618989f7c3e6 /drape_frontend | |
parent | d1c09dee99fea872e5b90a13db85e75bb0ae3bb8 (diff) | |
parent | b3752b5aacda9fb4b383ee2933467a7bd2f69cf6 (diff) |
Merge pull request #4202 from rokuz/tile-based-model-view
Added tile-based model-view
Diffstat (limited to 'drape_frontend')
44 files changed, 528 insertions, 379 deletions
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 3091f10cb1..0710a5716f 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -222,13 +222,15 @@ uint16_t CalculateHotelOverlayPriority(BaseApplyFeature::HotelData const & data) } // namespace -BaseApplyFeature::BaseApplyFeature(TInsertShapeFn const & insertShape, FeatureID const & id, - int minVisibleScale, uint8_t rank, CaptionDescription const & caption) +BaseApplyFeature::BaseApplyFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + int minVisibleScale, uint8_t rank, CaptionDescription const & captions) : m_insertShape(insertShape) , m_id(id) - , m_captions(caption) + , m_captions(captions) , m_minVisibleScale(minVisibleScale) , m_rank(rank) + , m_tileCenter(tileCenter) { ASSERT(m_insertShape != nullptr, ()); } @@ -283,10 +285,11 @@ void BaseApplyFeature::SetHotelData(HotelData && hotelData) m_hotelData = move(hotelData); } -ApplyPointFeature::ApplyPointFeature(TInsertShapeFn const & insertShape, FeatureID const & id, +ApplyPointFeature::ApplyPointFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions, float posZ) - : TBase(insertShape, id, minVisibleScale, rank, captions) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions) , m_posZ(posZ) , m_hasPoint(false) , m_hasArea(false) @@ -338,6 +341,7 @@ void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule) if (capRule && isNode) { TextViewParams params; + params.m_tileCenter = m_tileCenter; ExtractCaptionParams(capRule, pRule->GetCaption(1), depth, params); params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -381,6 +385,7 @@ void ApplyPointFeature::Finish() else if (m_circleRule) { CircleViewParams params(m_id); + params.m_tileCenter = m_tileCenter; params.m_depth = m_circleDepth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -393,6 +398,7 @@ void ApplyPointFeature::Finish() else if (m_symbolRule) { PoiSymbolViewParams params(m_id); + params.m_tileCenter = m_tileCenter; params.m_depth = m_symbolDepth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -416,12 +422,15 @@ void ApplyPointFeature::Finish() } } -ApplyAreaFeature::ApplyAreaFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, float minPosZ, - float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions) - : TBase(insertShape, id, minVisibleScale, rank, captions, posZ) +ApplyAreaFeature::ApplyAreaFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, float minPosZ, + float posZ, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions, posZ) , m_minPosZ(minPosZ) , m_isBuilding(posZ > 0.0f) - , m_tileRect(tileRect) + , m_clipRect(clipRect) {} void ApplyAreaFeature::operator()(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) @@ -450,9 +459,9 @@ void ApplyAreaFeature::operator()(m2::PointD const & p1, m2::PointD const & p2, }; if (m2::CrossProduct(p2 - p1, p3 - p1) < 0) - m2::ClipTriangleByRect(m_tileRect, p1, p2, p3, clipFunctor); + m2::ClipTriangleByRect(m_clipRect, p1, p2, p3, clipFunctor); else - m2::ClipTriangleByRect(m_tileRect, p1, p3, p2, clipFunctor); + m2::ClipTriangleByRect(m_clipRect, p1, p3, p2, clipFunctor); } void ApplyAreaFeature::ProcessBuildingPolygon(m2::PointD const & p1, m2::PointD const & p2, @@ -575,6 +584,7 @@ void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule) if (areaRule && !m_triangles.empty()) { AreaViewParams params; + params.m_tileCenter = m_tileCenter; params.m_depth = depth; params.m_color = ToDrapeColor(areaRule->color()); params.m_minVisibleScale = m_minVisibleScale; @@ -595,17 +605,18 @@ void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule) TBase::ProcessRule(rule); } -ApplyLineFeature::ApplyLineFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, - int minVisibleScale, uint8_t rank, CaptionDescription const & captions, - double currentScaleGtoP, bool simplify, size_t pointsCount) - : TBase(insertShape, id, minVisibleScale, rank, captions) +ApplyLineFeature::ApplyLineFeature(m2::PointD const & tileCenter, double currentScaleGtoP, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions, bool simplify, size_t pointsCount) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions) , m_currentScaleGtoP(currentScaleGtoP) , m_sqrScale(math::sqr(m_currentScaleGtoP)) , m_simplify(simplify) , m_initialPointsCount(pointsCount) , m_shieldDepth(0.0) , m_shieldRule(nullptr) - , m_tileRect(tileRect) + , m_clipRect(move(clipRect)) #ifdef CALC_FILTERED_POINTS , m_readedCount(0) #endif @@ -659,7 +670,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) LineDefProto const * pLineRule = pRule->GetLine(); ShieldRuleProto const * pShieldRule = pRule->GetShield(); - m_clippedSplines = m2::ClipSplineByRect(m_tileRect, m_spline); + m_clippedSplines = m2::ClipSplineByRect(m_clipRect, m_spline); if (m_clippedSplines.empty()) return; @@ -671,6 +682,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) CaptionDefProtoToFontDecl(pCaptionRule, fontDecl); PathTextViewParams params; + params.m_tileCenter = m_tileCenter; params.m_featureID = m_id; params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; @@ -689,6 +701,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) { PathSymProto const & symRule = pLineRule->pathsym(); PathSymbolViewParams params; + params.m_tileCenter = m_tileCenter; params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -704,6 +717,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) else { LineViewParams params; + params.m_tileCenter = m_tileCenter; Extract(pLineRule, params); params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; @@ -741,6 +755,7 @@ void ApplyLineFeature::Finish() float const mainScale = df::VisualParams::Instance().GetVisualScale(); TextViewParams viewParams; + viewParams.m_tileCenter = m_tileCenter; viewParams.m_depth = m_shieldDepth; viewParams.m_minVisibleScale = m_minVisibleScale; viewParams.m_rank = m_rank; diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp index b2edc079bd..e95efe075c 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -31,7 +31,8 @@ using TInsertShapeFn = function<void(drape_ptr<MapShape> && shape)>; class BaseApplyFeature { public: - BaseApplyFeature(TInsertShapeFn const & insertShape, FeatureID const & id, + BaseApplyFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); virtual ~BaseApplyFeature() {} @@ -58,6 +59,8 @@ protected: int m_minVisibleScale; uint8_t m_rank; HotelData m_hotelData; + + m2::PointD m_tileCenter; }; class ApplyPointFeature : public BaseApplyFeature @@ -65,7 +68,8 @@ class ApplyPointFeature : public BaseApplyFeature using TBase = BaseApplyFeature; public: - ApplyPointFeature(TInsertShapeFn const & insertShape, FeatureID const & id, + ApplyPointFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions, float posZ); @@ -93,8 +97,11 @@ class ApplyAreaFeature : public ApplyPointFeature using TBase = ApplyPointFeature; public: - ApplyAreaFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, float minPosZ, - float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); + ApplyAreaFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, float minPosZ, + float posZ, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions); using TBase::operator (); @@ -112,13 +119,13 @@ private: bool FindEdge(TEdge const & edge); m2::PointD CalculateNormal(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) const; - vector<m2::PointF> m_triangles; + vector<m2::PointD> m_triangles; unordered_map<int, m2::PointD> m_indices; vector<pair<TEdge, int>> m_edges; float const m_minPosZ; bool const m_isBuilding; - m2::RectD m_tileRect; + m2::RectD m_clipRect; }; class ApplyLineFeature : public BaseApplyFeature @@ -126,9 +133,10 @@ class ApplyLineFeature : public BaseApplyFeature using TBase = BaseApplyFeature; public: - ApplyLineFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, - int minVisibleScale, uint8_t rank, CaptionDescription const & captions, - double currentScaleGtoP, bool simplify, size_t pointsCount); + ApplyLineFeature(m2::PointD const & tileCenter, double currentScaleGtoP, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions, bool simplify, size_t pointsCount); void operator() (m2::PointD const & point); bool HasGeometry() const; @@ -145,7 +153,7 @@ private: size_t m_initialPointsCount; double m_shieldDepth; ShieldRuleProto const * m_shieldRule; - m2::RectD m_tileRect; + m2::RectD m_clipRect; #ifdef CALC_FILTERED_POINTS int m_readedCount; diff --git a/drape_frontend/area_shape.cpp b/drape_frontend/area_shape.cpp index 59d632eda5..44c7f9b459 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -15,7 +15,7 @@ namespace df { -AreaShape::AreaShape(vector<m2::PointF> && triangleList, vector<BuildingEdge> && buildingEdges, +AreaShape::AreaShape(vector<m2::PointD> && triangleList, vector<BuildingEdge> && buildingEdges, AreaViewParams const & params) : m_vertexes(move(triangleList)) , m_buildingEdges(move(buildingEdges)) @@ -36,26 +36,25 @@ void AreaShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t for (auto const & edge : m_buildingEdges) { + glsl::vec2 const startPt = glsl::ToVec2(ConvertToLocal(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const endPt = glsl::ToVec2(ConvertToLocal(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec3 normal(glsl::ToVec2(edge.m_normal), 0.0f); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_posZ), - normal, colorPoint)); - - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_posZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_posZ), - normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_posZ), normal, colorPoint)); + + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_posZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_posZ), normal, colorPoint)); } glsl::vec3 normal(0.0f, 0.0f, -1.0f); for (auto const & vertex : m_vertexes) - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(vertex), -m_params.m_posZ), - normal, colorPoint)); + { + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(vertex, m_params.m_tileCenter, kShapeCoordScalar)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(pt, -m_params.m_posZ), normal, colorPoint)); + } dp::GLState state(gpu::AREA_3D_PROGRAM, dp::GLState::GeometryLayer); state.SetColorTexture(region.GetTexture()); @@ -71,7 +70,8 @@ void AreaShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t vertexes.resize(m_vertexes.size()); transform(m_vertexes.begin(), m_vertexes.end(), vertexes.begin(), [&colorPoint, this](m2::PointF const & vertex) { - return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(vertex), m_params.m_depth), colorPoint); + return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(ConvertToLocal(vertex, m_params.m_tileCenter, kShapeCoordScalar)), + m_params.m_depth), colorPoint); }); dp::GLState state(gpu::AREA_PROGRAM, dp::GLState::GeometryLayer); diff --git a/drape_frontend/area_shape.hpp b/drape_frontend/area_shape.hpp index 7dc2844082..c6ae7d1579 100644 --- a/drape_frontend/area_shape.hpp +++ b/drape_frontend/area_shape.hpp @@ -21,13 +21,13 @@ struct BuildingEdge class AreaShape : public MapShape { public: - AreaShape(vector<m2::PointF> && triangleList, vector<BuildingEdge> && buildingEdges, + AreaShape(vector<m2::PointD> && triangleList, vector<BuildingEdge> && buildingEdges, AreaViewParams const & params); void Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const override; private: - vector<m2::PointF> m_vertexes; + vector<m2::PointD> m_vertexes; vector<BuildingEdge> m_buildingEdges; AreaViewParams m_params; }; diff --git a/drape_frontend/arrow3d.cpp b/drape_frontend/arrow3d.cpp index a4a66e72ce..54aac7d554 100644 --- a/drape_frontend/arrow3d.cpp +++ b/drape_frontend/arrow3d.cpp @@ -118,7 +118,7 @@ void Arrow3d::SetPositionObsolete(bool obsolete) m_obsoletePosition = obsolete; } -void Arrow3d::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng) +void Arrow3d::Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng) { // Unbind current VAO, because glVertexAttributePointer and glEnableVertexAttribute can affect it. if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) @@ -170,7 +170,7 @@ void Arrow3d::RenderArrow(ScreenBase const & screen, ref_ptr<dp::GpuProgram> pro dp::UniformValuesStorage uniforms; math::Matrix<float, 4, 4> const modelTransform = CalculateTransform(screen, dz); - uniforms.SetMatrix4x4Value("m_transform", modelTransform.m_data); + uniforms.SetMatrix4x4Value("u_transform", modelTransform.m_data); glsl::vec4 const c = glsl::ToVec4(color); uniforms.SetFloatValue("u_color", c.r, c.g, c.b, c.a); dp::ApplyState(m_state, program); diff --git a/drape_frontend/arrow3d.hpp b/drape_frontend/arrow3d.hpp index 56128c2b1d..7dcaeec3e2 100644 --- a/drape_frontend/arrow3d.hpp +++ b/drape_frontend/arrow3d.hpp @@ -30,7 +30,7 @@ public: void SetTexture(ref_ptr<dp::TextureManager> texMng); void SetPositionObsolete(bool obsolete); - void Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng); + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng); private: void Build(); diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index b26819750b..94a9f16654 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -221,18 +221,19 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message) case Message::UpdateUserMarkLayer: { ref_ptr<UpdateUserMarkLayerMessage> msg = message; - TileKey const & key = msg->GetKey(); UserMarksProvider const * marksProvider = msg->StartProcess(); if (marksProvider->IsDirty()) { + size_t const layerId = msg->GetLayerId(); m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ClearUserMarkLayerMessage>(key), + make_unique_dp<ClearUserMarkLayerMessage>(layerId), MessagePriority::Normal); - m_batchersPool->ReserveBatcher(key); - CacheUserMarks(marksProvider, m_batchersPool->GetTileBatcher(key), m_texMng); - m_batchersPool->ReleaseBatcher(key); + TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<FlushUserMarksMessage>(layerId, move(shapes)), + MessagePriority::Normal); } msg->EndProcess(); break; diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 3fd8fba4aa..8cdb09bcd4 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -24,12 +24,13 @@ void CircleShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> dp::TextureManager::ColorRegion region; textures->GetColorRegion(m_params.m_color, region); - glsl::vec2 colorPoint(glsl::ToVec2(region.GetTexRect().Center())); + glsl::vec2 const colorPoint(glsl::ToVec2(region.GetTexRect().Center())); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); buffer_vector<gpu::SolidTexturingVertex, 22> vertexes; vertexes.push_back(gpu::SolidTexturingVertex { - glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f), + glsl::vec4(pt, m_params.m_depth, 0.0f), glsl::vec2(0.0f, 0.0f), colorPoint }); @@ -41,7 +42,7 @@ void CircleShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> m2::PointD rotatedNormal = m2::Rotate(startNormal, (i) * etalonSector); vertexes.push_back(gpu::SolidTexturingVertex { - glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f), + glsl::vec4(pt, m_params.m_depth, 0.0f), glsl::ToVec2(rotatedNormal), colorPoint }); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 445d939146..42b4b554a2 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -143,24 +143,24 @@ void DrapeEngine::SetModelViewAnyRect(m2::AnyRectD const & rect, bool isAnim) AddUserEvent(make_unique_dp<SetAnyRectEvent>(rect, isAnim)); } -void DrapeEngine::ClearUserMarksLayer(df::TileKey const & tileKey) +void DrapeEngine::ClearUserMarksLayer(size_t layerId) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ClearUserMarkLayerMessage>(tileKey), + make_unique_dp<ClearUserMarkLayerMessage>(layerId), MessagePriority::Normal); } -void DrapeEngine::ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible) +void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ChangeUserMarkLayerVisibilityMessage>(tileKey, isVisible), + make_unique_dp<ChangeUserMarkLayerVisibilityMessage>(layerId, isVisible), MessagePriority::Normal); } -void DrapeEngine::UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider) +void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp<UpdateUserMarkLayerMessage>(tileKey, provider), + make_unique_dp<UpdateUserMarkLayerMessage>(layerId, provider), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 63f38e616f..8eacbbde71 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -100,9 +100,9 @@ public: using TModelViewListenerFn = FrontendRenderer::TModelViewChanged; void SetModelViewListener(TModelViewListenerFn && fn); - void ClearUserMarksLayer(TileKey const & tileKey); - void ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible); - void UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider); + void ClearUserMarksLayer(size_t layerId); + void ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible); + void UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider); void SetRenderingEnabled(ref_ptr<dp::OGLContextFactory> contextFactory = nullptr); void SetRenderingDisabled(bool const destroyContext); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index e73e37def3..94d0e14362 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -248,23 +248,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) dp::GLState const & state = msg->GetState(); TileKey const & key = msg->GetKey(); drape_ptr<dp::RenderBucket> bucket = msg->AcceptBuffer(); - if (!IsUserMarkLayer(key)) - { - if (key.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(key)) - { - PrepareBucket(state, bucket); - AddToRenderGroup(state, move(bucket), key); - } - } - else + if (key.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(key)) { PrepareBucket(state, bucket); - - ref_ptr<dp::GpuProgram> program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - ref_ptr<dp::GpuProgram> program3d = m_gpuProgramManager->GetProgram(state.GetProgram3dIndex()); - - m_userMarkRenderGroups.emplace_back(make_unique_dp<UserMarkRenderGroup>(state, key, move(bucket))); - m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms)); + AddToRenderGroup(state, move(bucket), key); } break; } @@ -275,7 +262,6 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) TOverlaysRenderData renderData = msg->AcceptRenderData(); for (auto & overlayRenderData : renderData) { - ASSERT(!IsUserMarkLayer(overlayRenderData.m_tileKey), ()); if (overlayRenderData.m_tileKey.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(overlayRenderData.m_tileKey)) { @@ -315,30 +301,46 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) break; } + case Message::FlushUserMarks: + { + ref_ptr<FlushUserMarksMessage> msg = message; + size_t const layerId = msg->GetLayerId(); + for (UserMarkShape & shape : msg->GetShapes()) + { + PrepareBucket(shape.m_state, shape.m_bucket); + auto program = m_gpuProgramManager->GetProgram(shape.m_state.GetProgramIndex()); + auto program3d = m_gpuProgramManager->GetProgram(shape.m_state.GetProgram3dIndex()); + auto group = make_unique_dp<UserMarkRenderGroup>(layerId, shape.m_state, shape.m_tileKey, + move(shape.m_bucket)); + m_userMarkRenderGroups.push_back(move(group)); + m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms)); + } + break; + } + case Message::ClearUserMarkLayer: { - TileKey const & tileKey = ref_ptr<ClearUserMarkLayerMessage>(message)->GetKey(); - auto const functor = [&tileKey](drape_ptr<UserMarkRenderGroup> const & g) + ref_ptr<ClearUserMarkLayerMessage> msg = message; + size_t const layerId = msg->GetLayerId(); + auto const functor = [&layerId](drape_ptr<UserMarkRenderGroup> const & g) { - return g->GetTileKey() == tileKey; + return g->GetLayerId() == layerId; }; auto const iter = remove_if(m_userMarkRenderGroups.begin(), m_userMarkRenderGroups.end(), functor); - m_userMarkRenderGroups.erase(iter, m_userMarkRenderGroups.end()); break; } case Message::ChangeUserMarkLayerVisibility: { - ref_ptr<ChangeUserMarkLayerVisibilityMessage> m = message; - TileKey const & key = m->GetKey(); - if (m->IsVisible()) - m_userMarkVisibility.insert(key); + ref_ptr<ChangeUserMarkLayerVisibilityMessage> msg = message; + if (msg->IsVisible()) + m_userMarkVisibility.insert(msg->GetLayerId()); else - m_userMarkVisibility.erase(key); + m_userMarkVisibility.erase(msg->GetLayerId()); break; } @@ -1027,12 +1029,14 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) { ASSERT(m_myPositionController->IsModeHasPosition(), ()); m_selectionShape->SetPosition(m_myPositionController->Position()); - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, + make_ref(m_gpuProgramManager), m_generalUniforms); } else if (selectedObject == SelectionShape::OBJECT_POI) { if (!isPerspective && m_layers[RenderLayer::Geometry3dID].m_renderGroups.empty()) - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, + make_ref(m_gpuProgramManager), m_generalUniforms); else hasSelectedPOI = true; } @@ -1057,32 +1061,26 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (hasSelectedPOI) { GLFunctions::glDisable(gl_const::GLDepthTest); - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); } GLFunctions::glEnable(gl_const::GLDepthTest); GLFunctions::glClearDepth(); RenderOverlayLayer(modelView); - m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, - make_ref(m_gpuProgramManager), m_generalUniforms); + m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); GLFunctions::glDisable(gl_const::GLDepthTest); if (m_selectionShape != nullptr && m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK) - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); m_routeRenderer->RenderRoute(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - for (drape_ptr<UserMarkRenderGroup> const & group : m_userMarkRenderGroups) - { - ASSERT(group.get() != nullptr, ()); - if (m_userMarkVisibility.find(group->GetTileKey()) != m_userMarkVisibility.end()) - RenderSingleGroup(modelView, make_ref(group)); - } + RenderUserMarksLayer(modelView); m_routeRenderer->RenderRouteSigns(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - m_myPositionController->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_myPositionController->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); if (m_guiRenderer != nullptr) m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView); @@ -1126,6 +1124,20 @@ void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) for (drape_ptr<RenderGroup> & group : overlay.m_renderGroups) RenderSingleGroup(modelView, make_ref(group)); } + +void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView) +{ + double const kExtension = 1.1; + m2::RectD screenRect = modelView.ClipRect(); + screenRect.Scale(kExtension); + for (auto const & group : m_userMarkRenderGroups) + { + ASSERT(group.get() != nullptr, ()); + if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end() && + screenRect.IsIntersect(group->GetTileKey().GetGlobalRect())) + RenderSingleGroup(modelView, make_ref(group)); + } +} void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) { @@ -1223,22 +1235,9 @@ void FrontendRenderer::RefreshProjection(ScreenBase const & screen) m_generalUniforms.SetMatrix4x4Value("projection", m.data()); } -void FrontendRenderer::RefreshModelView(ScreenBase const & screen) +void FrontendRenderer::RefreshZScale(ScreenBase const & screen) { - ScreenBase::MatrixT const & m = screen.GtoPMatrix(); - math::Matrix<float, 4, 4> mv; - - /// preparing ModelView matrix - - mv(0, 0) = m(0, 0); mv(0, 1) = m(1, 0); mv(0, 2) = 0; mv(0, 3) = m(2, 0); - mv(1, 0) = m(0, 1); mv(1, 1) = m(1, 1); mv(1, 2) = 0; mv(1, 3) = m(2, 1); - mv(2, 0) = 0; mv(2, 1) = 0; mv(2, 2) = 1; mv(2, 3) = 0; - mv(3, 0) = m(0, 2); mv(3, 1) = m(1, 2); mv(3, 2) = 0; mv(3, 3) = m(2, 2); - - m_generalUniforms.SetMatrix4x4Value("modelView", mv.m_data); - - float const zScale = screen.GetZScale(); - m_generalUniforms.SetFloatValue("zScale", zScale); + m_generalUniforms.SetFloatValue("zScale", screen.GetZScale()); } void FrontendRenderer::RefreshPivotTransform(ScreenBase const & screen) @@ -1708,7 +1707,7 @@ ScreenBase const & FrontendRenderer::ProcessEvents(bool & modelViewChanged, bool void FrontendRenderer::PrepareScene(ScreenBase const & modelView) { - RefreshModelView(modelView); + RefreshZScale(modelView); RefreshPivotTransform(modelView); m_myPositionController->UpdatePixelPosition(modelView); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 6152e408f1..fd19a10e81 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -37,6 +37,7 @@ #include "std/function.hpp" #include "std/map.hpp" #include "std/array.hpp" +#include "std/unordered_set.hpp" namespace dp { @@ -161,7 +162,7 @@ private: void MergeBuckets(); void RenderSingleGroup(ScreenBase const & modelView, ref_ptr<BaseRenderGroup> group); void RefreshProjection(ScreenBase const & screen); - void RefreshModelView(ScreenBase const & screen); + void RefreshZScale(ScreenBase const & screen); void RefreshPivotTransform(ScreenBase const & screen); void RefreshBgColor(); @@ -170,6 +171,7 @@ private: void Render2dLayer(ScreenBase const & modelView); void Render3dLayer(ScreenBase const & modelView); void RenderOverlayLayer(ScreenBase const & modelView); + void RenderUserMarksLayer(ScreenBase const & modelView); ////// ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged); void PrepareScene(ScreenBase const & modelView); @@ -270,7 +272,7 @@ private: array<RenderLayer, RenderLayer::LayerCountID> m_layers; vector<drape_ptr<UserMarkRenderGroup>> m_userMarkRenderGroups; - set<TileKey> m_userMarkVisibility; + unordered_set<size_t> m_userMarkVisibility; drape_ptr<gui::LayerRenderer> m_guiRenderer; drape_ptr<MyPositionController> m_myPositionController; diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index b5137402be..6dfe0a692b 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -1,5 +1,7 @@ #include "drape_frontend/gps_track_renderer.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/glsl_func.hpp" @@ -227,11 +229,14 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, m_handlesCache.push_back(make_pair(handle, 0)); } + m_pivot = screen.GlobalRect().Center(); + size_t cacheIndex = 0; if (m_points.size() == 1) { dp::Color const color = GetColorBySpeed(m_points.front().m_speedMPS); - m_handlesCache[cacheIndex].first->SetPoint(0, m_points.front().m_point, m_radius, color); + m2::PointD const pt = MapShape::ConvertToLocal(m_points.front().m_point, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(0, pt, m_radius, color); m_handlesCache[cacheIndex].second++; } else @@ -248,7 +253,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (screen.ClipRect().IsIntersect(pointRect)) { dp::Color const color = CalculatePointColor(static_cast<size_t>(it.GetIndex()), pt, it.GetLength(), it.GetFullLength()); - m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, pt, m_radius, color); + m2::PointD const convertedPt = MapShape::ConvertToLocal(pt, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius, color); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) cacheIndex++; @@ -266,7 +272,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, #ifdef SHOW_RAW_POINTS for (size_t i = 0; i < m_points.size(); i++) { - m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, m_points[i].m_point, m_radius * 1.2, dp::Color(0, 0, 255, 255)); + m2::PointD const convertedPt = MapShape::ConvertToLocal(m_points[i].m_point, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius * 1.2, dp::Color(0, 0, 255, 255)); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) cacheIndex++; @@ -292,6 +299,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, // Render points. dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix<float, 4, 4> mv = screen.GetModelView(m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM); program->Bind(); diff --git a/drape_frontend/gps_track_renderer.hpp b/drape_frontend/gps_track_renderer.hpp index cb40cb34e8..b9c67005ce 100644 --- a/drape_frontend/gps_track_renderer.hpp +++ b/drape_frontend/gps_track_renderer.hpp @@ -51,6 +51,7 @@ private: bool m_waitForRenderData; vector<pair<GpsTrackHandle*, size_t>> m_handlesCache; float m_radius; + m2::PointD m_pivot; }; } // namespace df diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index b5f8073841..8130117f56 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -73,13 +73,6 @@ public: m_joinGeom.reserve(joinsSize); } - void GetTexturingInfo(float const globalLength, int & steps, float & maskSize) - { - UNUSED_VALUE(globalLength); - UNUSED_VALUE(steps); - UNUSED_VALUE(maskSize); - } - dp::BindingInfo const & GetBindingInfo() override { return TVertex::GetBindingInfo(); @@ -136,42 +129,6 @@ public: } protected: - vector<glsl::vec2> const & GenerateCap(LineSegment const & segment, EPointType type, - float sign, bool isStart) - { - m_normalBuffer.clear(); - m_normalBuffer.reserve(24); - - GenerateCapNormals(m_params.m_cap, - segment.m_leftNormals[type], - segment.m_rightNormals[type], - sign * segment.m_tangent, - GetHalfWidth(), isStart, m_normalBuffer); - - return m_normalBuffer; - } - - vector<glsl::vec2> const & GenerateJoin(LineSegment const & seg1, LineSegment const & seg2) - { - m_normalBuffer.clear(); - m_normalBuffer.reserve(24); - - glsl::vec2 n1 = seg1.m_hasLeftJoin[EndPoint] ? seg1.m_leftNormals[EndPoint] : - seg1.m_rightNormals[EndPoint]; - - glsl::vec2 n2 = seg2.m_hasLeftJoin[StartPoint] ? seg2.m_leftNormals[StartPoint] : - seg2.m_rightNormals[StartPoint]; - - float widthScalar = seg1.m_hasLeftJoin[EndPoint] ? seg1.m_rightWidthScalar[EndPoint].x : - seg1.m_leftWidthScalar[EndPoint].x; - - GenerateJoinNormals(m_params.m_join, n1, n2, GetHalfWidth(), - seg1.m_hasLeftJoin[EndPoint], widthScalar, m_normalBuffer); - - return m_normalBuffer; - } - -protected: using V = TVertex; using TGeometryBuffer = vector<V>; @@ -200,8 +157,7 @@ class SolidLineBuilder : public BaseLineBuilder<gpu::LineVertex> : m_position(pos) , m_normal(normal) , m_color(color) - { - } + {} TPosition m_position; TNormal m_normal; @@ -326,11 +282,10 @@ public: , m_baseGtoPScale(params.m_baseGtoP) {} - void GetTexturingInfo(float const globalLength, int & steps, float & maskSize) + int GetDashesCount(float const globalLength) const { float const pixelLen = globalLength * m_baseGtoPScale; - steps = static_cast<int>((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); - maskSize = globalLength / steps; + return static_cast<int>((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); } dp::GLState GetState() override @@ -381,16 +336,16 @@ void LineShape::Construct<DashedLineBuilder>(DashedLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::vec2(path[i - 1].x, path[i - 1].y); - glsl::vec2 const p2 = glsl::vec2(path[i].x, path[i].y); + glsl::vec2 const p1 = glsl::ToVec2(ConvertToLocal(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertToLocal(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); // calculate number of steps to cover line segment - float const initialGlobalLength = glsl::length(p2 - p1); - int steps = 1; - float maskSize = initialGlobalLength; - builder.GetTexturingInfo(initialGlobalLength, steps, maskSize); + float const initialGlobalLength = static_cast<float>((path[i] - path[i - 1]).Length()); + int const steps = max(1, builder.GetDashesCount(initialGlobalLength)); + float const maskSize = glsl::length(p2 - p1) / steps; + float const offsetSize = initialGlobalLength / steps; // generate vertices float currentSize = 0; @@ -402,8 +357,8 @@ void LineShape::Construct<DashedLineBuilder>(DashedLineBuilder & builder) const builder.SubmitVertex(currentStartPivot, rightNormal, false /* isLeft */, 0.0); builder.SubmitVertex(currentStartPivot, leftNormal, true /* isLeft */, 0.0); - builder.SubmitVertex(newPivot, rightNormal, false /* isLeft */, maskSize); - builder.SubmitVertex(newPivot, leftNormal, true /* isLeft */, maskSize); + builder.SubmitVertex(newPivot, rightNormal, false /* isLeft */, offsetSize); + builder.SubmitVertex(newPivot, leftNormal, true /* isLeft */, offsetSize); currentStartPivot = newPivot; } @@ -424,7 +379,7 @@ void LineShape::Construct<SolidLineBuilder>(SolidLineBuilder & builder) const generateJoins = false; // build geometry - glsl::vec2 firstPoint = glsl::vec2(path.front().x, path.front().y); + glsl::vec2 firstPoint = glsl::ToVec2(ConvertToLocal(path.front(), m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 lastPoint; bool hasConstructedSegments = false; for (size_t i = 1; i < path.size(); ++i) @@ -432,8 +387,8 @@ void LineShape::Construct<SolidLineBuilder>(SolidLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::vec2(path[i - 1].x, path[i - 1].y); - glsl::vec2 const p2 = glsl::vec2(path[i].x, path[i].y); + glsl::vec2 const p1 = glsl::ToVec2(ConvertToLocal(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertToLocal(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); diff --git a/drape_frontend/map_shape.hpp b/drape_frontend/map_shape.hpp index cdde3a35f4..52579140b8 100644 --- a/drape_frontend/map_shape.hpp +++ b/drape_frontend/map_shape.hpp @@ -5,6 +5,8 @@ #include "drape/pointers.hpp" +#include "geometry/point2d.hpp" + namespace dp { class Batcher; @@ -33,6 +35,11 @@ public: void SetFeatureMinZoom(int minZoom) { m_minZoom = minZoom; } int GetFeatureMinZoom() const { return m_minZoom; } + static m2::PointD ConvertToLocal(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) + { + return (basePt - tileCenter) * scalar; + } + private: int m_minZoom = 0; }; diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index bdc97bc437..e237b93c6c 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -23,6 +23,7 @@ public: ClearUserMarkLayer, ChangeUserMarkLayerVisibility, UpdateUserMarkLayer, + FlushUserMarks, GuiLayerRecached, GuiRecache, GuiLayerLayout, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 8ffd1ef3b3..e2263ee5fa 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -13,6 +13,7 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/user_marks_provider.hpp" +#include "drape_frontend/user_mark_shapes.hpp" #include "drape_frontend/viewport.hpp" #include "geometry/polyline2d.hpp" @@ -191,20 +192,33 @@ private: bool m_needInvalidateAll; }; -class ClearUserMarkLayerMessage : public BaseTileMessage +class BaseUserMarkLayerMessage : public Message { public: - ClearUserMarkLayerMessage(TileKey const & tileKey) - : BaseTileMessage(tileKey) {} + BaseUserMarkLayerMessage(size_t layerId) + : m_layerId(layerId) + {} + + size_t GetLayerId() const { return m_layerId; } + +private: + size_t m_layerId; +}; + +class ClearUserMarkLayerMessage : public BaseUserMarkLayerMessage +{ +public: + ClearUserMarkLayerMessage(size_t layerId) + : BaseUserMarkLayerMessage(layerId) {} Type GetType() const override { return Message::ClearUserMarkLayer; } }; -class ChangeUserMarkLayerVisibilityMessage : public BaseTileMessage +class ChangeUserMarkLayerVisibilityMessage : public BaseUserMarkLayerMessage { public: - ChangeUserMarkLayerVisibilityMessage(TileKey const & tileKey, bool isVisible) - : BaseTileMessage(tileKey) + ChangeUserMarkLayerVisibilityMessage(size_t layerId, bool isVisible) + : BaseUserMarkLayerMessage(layerId) , m_isVisible(isVisible) {} Type GetType() const override { return Message::ChangeUserMarkLayerVisibility; } @@ -215,17 +229,17 @@ private: bool m_isVisible; }; -class UpdateUserMarkLayerMessage : public BaseTileMessage +class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage { public: - UpdateUserMarkLayerMessage(TileKey const & tileKey, UserMarksProvider * provider) - : BaseTileMessage(tileKey) + UpdateUserMarkLayerMessage(size_t layerId, UserMarksProvider * provider) + : BaseUserMarkLayerMessage(layerId) , m_provider(provider) { m_provider->IncrementCounter(); } - ~UpdateUserMarkLayerMessage() + ~UpdateUserMarkLayerMessage() override { ASSERT(m_inProcess == false, ()); m_provider->DecrementCounter(); @@ -259,6 +273,23 @@ private: #endif }; +class FlushUserMarksMessage : public BaseUserMarkLayerMessage +{ +public: + FlushUserMarksMessage(size_t layerId, TUserMarkShapes && shapes) + : BaseUserMarkLayerMessage(layerId) + , m_shapes(move(shapes)) + {} + + Type GetType() const override { return Message::FlushUserMarks; } + bool IsGLContextDependent() const override { return true; } + + TUserMarkShapes & GetShapes() { return m_shapes; } + +private: + TUserMarkShapes m_shapes; +}; + class GuiLayerRecachedMessage : public Message { public: diff --git a/drape_frontend/my_position.cpp b/drape_frontend/my_position.cpp index f3e682fa1e..99f6b89ef6 100644 --- a/drape_frontend/my_position.cpp +++ b/drape_frontend/my_position.cpp @@ -1,5 +1,8 @@ #include "drape_frontend/my_position.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/constants.hpp" #include "drape/glsl_func.hpp" @@ -95,21 +98,26 @@ void MyPosition::SetPositionObsolete(bool obsolete) m_arrow3d.SetPositionObsolete(obsolete); } -void MyPosition::RenderAccuracy(ScreenBase const & screen, - ref_ptr<dp::GpuProgramManager> mng, - dp::UniformValuesStorage const & commonUniforms) +void MyPosition::RenderAccuracy(ScreenBase const & screen, int zoomLevel, + ref_ptr<dp::GpuProgramManager> mng, + dp::UniformValuesStorage const & commonUniforms) { dp::UniformValuesStorage uniforms = commonUniforms; m2::PointD accuracyPoint(m_position.x + m_accuracy, m_position.y); float pixelAccuracy = (screen.GtoP(accuracyPoint) - screen.GtoP(m_position)).Length(); - uniforms.SetFloatValue("u_position", m_position.x, m_position.y, 0.0f); + TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); + math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, 0.0f); uniforms.SetFloatValue("u_accuracy", pixelAccuracy); uniforms.SetFloatValue("u_opacity", 1.0f); RenderPart(mng, uniforms, MY_POSITION_ACCURACY); } -void MyPosition::RenderMyPosition(ScreenBase const & screen, +void MyPosition::RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { @@ -117,12 +125,17 @@ void MyPosition::RenderMyPosition(ScreenBase const & screen, { m_arrow3d.SetPosition(m_position); m_arrow3d.SetAzimuth(m_azimuth); - m_arrow3d.Render(screen, mng); + m_arrow3d.Render(screen, zoomLevel, mng); } else { dp::UniformValuesStorage uniforms = commonUniforms; - uniforms.SetFloatValue("u_position", m_position.x, m_position.y, dp::depth::MY_POSITION_MARK); + TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); + math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, dp::depth::MY_POSITION_MARK); uniforms.SetFloatValue("u_azimut", -(m_azimuth + screen.GetAngle())); uniforms.SetFloatValue("u_opacity", 1.0); RenderPart(mng, uniforms, MY_POSITION_POINT); diff --git a/drape_frontend/my_position.hpp b/drape_frontend/my_position.hpp index 65abf0b176..8310f01955 100644 --- a/drape_frontend/my_position.hpp +++ b/drape_frontend/my_position.hpp @@ -28,11 +28,11 @@ public: void SetRoutingMode(bool routingMode); void SetPositionObsolete(bool obsolete); - void RenderAccuracy(ScreenBase const & screen, + void RenderAccuracy(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); - void RenderMyPosition(ScreenBase const & screen, + void RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index e51f72c1ce..592ea95390 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -500,7 +500,8 @@ bool MyPositionController::UpdateViewportWithAutoZoom() return false; } -void MyPositionController::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, +void MyPositionController::Render(ScreenBase const & screen, int zoomLevel, + ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { if (IsWaitingForLocation()) @@ -551,8 +552,8 @@ void MyPositionController::Render(ScreenBase const & screen, ref_ptr<dp::GpuProg m_shape->SetAccuracy(m_errorRadius); m_shape->SetRoutingMode(IsInRouting()); - m_shape->RenderAccuracy(screen, mng, commonUniforms); - m_shape->RenderMyPosition(screen, mng, commonUniforms); + m_shape->RenderAccuracy(screen, zoomLevel, mng, commonUniforms); + m_shape->RenderMyPosition(screen, zoomLevel, mng, commonUniforms); } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 9d555fc880..51d9ff75ef 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -90,7 +90,7 @@ public: void SetModeListener(location::TMyPositionModeChanged const & fn); - void Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); bool IsRotationAvailable() const { return m_isDirectionAssigned; } diff --git a/drape_frontend/path_symbol_shape.cpp b/drape_frontend/path_symbol_shape.cpp index 896b3b6c5a..54b9ff03dc 100644 --- a/drape_frontend/path_symbol_shape.cpp +++ b/drape_frontend/path_symbol_shape.cpp @@ -40,7 +40,7 @@ void PathSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureMana glsl::vec2 dummy(0.0, 0.0); while (!splineIter.BeginAgain()) { - glsl::vec2 pivot = glsl::ToVec2(splineIter.m_pos); + glsl::vec2 const pivot = glsl::ToVec2(ConvertToLocal(splineIter.m_pos, m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 n = halfH * glsl::normalize(glsl::vec2(-splineIter.m_dir.y, splineIter.m_dir.x)); glsl::vec2 d = halfW * glsl::normalize(glsl::vec2(splineIter.m_dir.x, splineIter.m_dir.y)); float nLength = glsl::length(n) * pToGScale; diff --git a/drape_frontend/path_text_shape.cpp b/drape_frontend/path_text_shape.cpp index 601a796b63..2c3048b9d3 100644 --- a/drape_frontend/path_text_shape.cpp +++ b/drape_frontend/path_text_shape.cpp @@ -319,8 +319,8 @@ void PathTextShape::DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures, void PathTextShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const { - unique_ptr<PathTextLayout> layout = make_unique<PathTextLayout>(strings::MakeUniString(m_params.m_text), - m_params.m_textFont.m_size, textures); + auto layout = make_unique<PathTextLayout>(m_params.m_tileCenter, strings::MakeUniString(m_params.m_text), + m_params.m_textFont.m_size, textures); uint32_t glyphCount = layout->GetGlyphCount(); if (glyphCount == 0) diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index 46ab2394c0..1fd1b13495 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -108,7 +108,8 @@ void PoiSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManag dp::TextureManager::SymbolRegion region; textures->GetSymbolRegion(m_params.m_symbolName, region); - glsl::vec4 const position = glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, -m_params.m_posZ); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec4 const position = glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ); m2::PointU const pixelSize = region.GetPixelSize(); drape_ptr<dp::OverlayHandle> handle = make_unique_dp<dp::SquareHandle>(m_params.m_id, diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index ffc8318b67..ac5e7b63b2 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -88,9 +88,15 @@ void RenderGroup::Render(ScreenBase const & screen) for(auto & renderBucket : m_renderBuckets) renderBucket->GetBuffer()->Build(shader); - auto const & params = df::VisualParams::Instance().GetGlyphVisualParams(); + // Set tile-based model-view matrix. + { + math::Matrix<float, 4, 4> mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } + int programIndex = m_state.GetProgramIndex(); int program3dIndex = m_state.GetProgram3dIndex(); + auto const & params = df::VisualParams::Instance().GetGlyphVisualParams(); if (programIndex == gpu::TEXT_OUTLINED_PROGRAM || program3dIndex == gpu::TEXT_OUTLINED_BILLBOARD_PROGRAM) { @@ -186,12 +192,12 @@ bool RenderGroupComparator::operator()(drape_ptr<RenderGroup> const & l, drape_p return false; } -UserMarkRenderGroup::UserMarkRenderGroup(dp::GLState const & state, - TileKey const & tileKey, +UserMarkRenderGroup::UserMarkRenderGroup(size_t layerId, dp::GLState const & state, TileKey const & tileKey, drape_ptr<dp::RenderBucket> && bucket) : TBase(state, tileKey) , m_renderBucket(move(bucket)) , m_animation(new OpacityAnimation(0.25 /*duration*/, 0.0 /* minValue */, 1.0 /* maxValue*/)) + , m_layerId(layerId) { m_mapping.AddRangePoint(0.6, 1.3); m_mapping.AddRangePoint(0.85, 0.8); @@ -215,6 +221,13 @@ void UserMarkRenderGroup::UpdateAnimation() void UserMarkRenderGroup::Render(ScreenBase const & screen) { BaseRenderGroup::Render(screen); + + // Set tile-based model-view matrix. + { + math::Matrix<float, 4, 4> mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } + ref_ptr<dp::GpuProgram> shader = screen.isPerspective() ? m_shader3d : m_shader; dp::ApplyUniforms(m_uniforms, shader); if (m_renderBucket != nullptr) @@ -224,6 +237,11 @@ void UserMarkRenderGroup::Render(ScreenBase const & screen) } } +size_t UserMarkRenderGroup::GetLayerId() const +{ + return m_layerId; +} + string DebugPrint(RenderGroup const & group) { ostringstream out; diff --git a/drape_frontend/render_group.hpp b/drape_frontend/render_group.hpp index de62ad03dd..c28fdd2ca1 100755 --- a/drape_frontend/render_group.hpp +++ b/drape_frontend/render_group.hpp @@ -26,6 +26,8 @@ public: : m_state(state) , m_tileKey(tileKey) {} + virtual ~BaseRenderGroup() {} + void SetRenderParams(ref_ptr<dp::GpuProgram> shader, ref_ptr<dp::GpuProgram> shader3d, ref_ptr<dp::UniformValuesStorage> generalUniforms); @@ -50,11 +52,11 @@ private: class RenderGroup : public BaseRenderGroup { - typedef BaseRenderGroup TBase; + using TBase = BaseRenderGroup; friend class BatchMergeHelper; public: RenderGroup(dp::GLState const & state, TileKey const & tileKey); - ~RenderGroup(); + ~RenderGroup() override; void Update(ScreenBase const & modelView); void CollectOverlay(ref_ptr<dp::OverlayTree> tree); @@ -91,20 +93,23 @@ public: class UserMarkRenderGroup : public BaseRenderGroup { - typedef BaseRenderGroup TBase; + using TBase = BaseRenderGroup; public: - UserMarkRenderGroup(dp::GLState const & state, TileKey const & tileKey, + UserMarkRenderGroup(size_t layerId, dp::GLState const & state, TileKey const & tileKey, drape_ptr<dp::RenderBucket> && bucket); - ~UserMarkRenderGroup(); + ~UserMarkRenderGroup() override; void UpdateAnimation() override; void Render(ScreenBase const & screen) override; + size_t GetLayerId() const; + private: drape_ptr<dp::RenderBucket> m_renderBucket; unique_ptr<OpacityAnimation> m_animation; ValueMapping<float> m_mapping; + size_t m_layerId; }; } // namespace df diff --git a/drape_frontend/route_builder.cpp b/drape_frontend/route_builder.cpp index fbf06dcb0b..95946eb44f 100644 --- a/drape_frontend/route_builder.cpp +++ b/drape_frontend/route_builder.cpp @@ -23,6 +23,7 @@ void RouteBuilder::Build(m2::PolylineD const & routePolyline, vector<double> con routeData->m_sourcePolyline = routePolyline; routeData->m_sourceTurns = turns; routeData->m_pattern = pattern; + routeData->m_pivot = routePolyline.GetLimitRect().Center(); RouteShape::CacheRoute(textures, *routeData.get()); m_routeCache.insert(make_pair(routeData->m_routeIndex, routePolyline)); @@ -63,6 +64,7 @@ void RouteBuilder::BuildArrows(int routeIndex, vector<ArrowBorders> const & bord return; drape_ptr<RouteArrowsData> routeArrowsData = make_unique_dp<RouteArrowsData>(); + routeArrowsData->m_pivot = it->second.GetLimitRect().Center(); RouteShape::CacheRouteArrows(textures, it->second, borders, *routeArrowsData.get()); // Flush route arrows geometry. diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index f8c8866cd2..7c07b75c14 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -1,4 +1,5 @@ #include "drape_frontend/route_renderer.hpp" +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/message_subclasses.hpp" #include "drape/glsl_func.hpp" @@ -238,6 +239,8 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr<dp::GpuProgra // Set up uniforms. dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix<float, 4, 4> mv = screen.GetModelView(m_routeData->m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); glsl::vec4 const color = glsl::ToVec4(df::GetColorConstant(GetStyleReader().GetCurrentStyle(), m_routeData->m_color)); uniforms.SetFloatValue("u_color", color.r, color.g, color.b, m_currentAlpha); @@ -269,6 +272,8 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr<dp::GpuProgra // set up shaders and apply common uniforms dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix<float, 4, 4> mv = screen.GetModelView(m_routeArrows->m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_arrowHalfWidth", m_currentHalfWidth * kArrowHeightFactor); uniforms.SetFloatValue("u_opacity", 1.0f); @@ -305,8 +310,9 @@ void RouteRenderer::RenderRouteSign(drape_ptr<RouteSignData> const & sign, Scree return; dp::GLState const & state = sign->m_sign.m_state; - dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix<float, 4, 4> mv = screen.GetModelView(sign->m_position, 1.0); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr<dp::GpuProgram> program = screen.isPerspective() ? mng->GetProgram(state.GetProgram3dIndex()) diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 5acafd0e21..5a839d5a17 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -1,5 +1,7 @@ #include "drape_frontend/route_shape.hpp" #include "drape_frontend/line_shape_helper.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/attribute_provider.hpp" #include "drape/batcher.hpp" @@ -120,8 +122,9 @@ void GenerateArrowsTriangles(glsl::vec4 const & pivot, vector<glsl::vec2> const } // namespace -void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength) +void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength) { ASSERT(path.size() > 1, ()); @@ -139,8 +142,13 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffe (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - glsl::vec3 const startPivot = glsl::vec3(segments[i].m_points[StartPoint], kDepth); - glsl::vec3 const endPivot = glsl::vec3(segments[i].m_points[EndPoint], kDepth); + m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); + + glsl::vec3 const startPivot = glsl::vec3(glsl::ToVec2(startPt), kDepth); + glsl::vec3 const endPivot = glsl::vec3(glsl::ToVec2(endPt), kDepth); float const endLength = length + glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); @@ -177,10 +185,11 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffe vector<glsl::vec2> normals; normals.reserve(24); - GenerateJoinNormals(dp::RoundJoin, n1, n2, 1.0f, segments[i].m_hasLeftJoin[EndPoint], widthScalar, normals); + GenerateJoinNormals(dp::RoundJoin, n1, n2, 1.0f, segments[i].m_hasLeftJoin[EndPoint], + widthScalar, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[EndPoint], kDepth), normals, - glsl::vec2(endLength, 0), segments[i].m_hasLeftJoin[EndPoint], joinsGeometry); + GenerateJoinsTriangles(endPivot, normals, glsl::vec2(endLength, 0), + segments[i].m_hasLeftJoin[EndPoint], joinsGeometry); } // Generate caps. @@ -192,8 +201,7 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffe segments[i].m_rightNormals[StartPoint], -segments[i].m_tangent, 1.0f, true /* isStart */, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[StartPoint], kDepth), normals, - glsl::vec2(length, 0), true, joinsGeometry); + GenerateJoinsTriangles(startPivot, normals, glsl::vec2(length, 0), true, joinsGeometry); } if (i == segments.size() - 1) @@ -204,8 +212,7 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffe segments[i].m_rightNormals[EndPoint], segments[i].m_tangent, 1.0f, false /* isStart */, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[EndPoint], kDepth), normals, - glsl::vec2(endLength, 0), true, joinsGeometry); + GenerateJoinsTriangles(endPivot, normals, glsl::vec2(endLength, 0), true, joinsGeometry); } length = endLength; @@ -214,7 +221,8 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffe outputLength = length; } -void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF const & texRect, float depth, +void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::PointD const & pivot, + m2::RectF const & texRect, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry) { ASSERT(path.size() > 1, ()); @@ -240,8 +248,13 @@ void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - glsl::vec4 const startPivot = glsl::vec4(segments[i].m_points[StartPoint], depth, 1.0); - glsl::vec4 const endPivot = glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0); + m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); + + glsl::vec4 const startPivot = glsl::vec4(glsl::ToVec2(startPt), depth, 1.0); + glsl::vec4 const endPivot = glsl::vec4(glsl::ToVec2(endPt), depth, 1.0); float const endLength = length + glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); @@ -285,8 +298,7 @@ void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF ASSERT_EQUAL(normals.size(), uv.size(), ()); - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0), - normals, tr, uv, true /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(endPivot, normals, tr, uv, true /* normalizedUV */, joinsGeometry); } // Generate arrow head. @@ -300,8 +312,7 @@ void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF }; float const u = 1.0f - kArrowHeadSize; vector<glsl::vec2> uv = { glsl::vec2(u, 1.0f), glsl::vec2(u, 0.0f), glsl::vec2(1.0f, 0.5f) }; - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0), - normals, texRect, uv, true /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(endPivot, normals, texRect, uv, true /* normalizedUV */, joinsGeometry); } // Generate arrow tail. @@ -325,8 +336,7 @@ void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF glsl::ToVec2(t.LeftTop()) }; - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[StartPoint], depth, 1.0), - normals, texRect, uv, false /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(startPivot, normals, texRect, uv, false /* normalizedUV */, joinsGeometry); } length = endLength; @@ -341,8 +351,7 @@ void RouteShape::CacheRouteSign(ref_ptr<dp::TextureManager> mng, RouteSignData & m2::RectF const & texRect = symbol.GetTexRect(); m2::PointF halfSize = m2::PointF(symbol.GetPixelSize()) * 0.5f; - glsl::vec2 const pos = glsl::ToVec2(routeSignData.m_position); - glsl::vec4 const pivot = glsl::vec4(pos.x, pos.y, 0.0f /* depth */, 0.0f /* pivot z */); + glsl::vec4 const pivot = glsl::vec4(0.0f /* x */, 0.0f /* y */, 0.0f /* depth */, 0.0f /* pivot z */); gpu::SolidTexturingVertex data[4]= { { pivot, glsl::vec2(-halfSize.x, halfSize.y), glsl::ToVec2(texRect.LeftTop()) }, @@ -389,7 +398,7 @@ void RouteShape::CacheRouteArrows(ref_ptr<dp::TextureManager> mng, m2::PolylineD { vector<m2::PointD> points = CalculatePoints(polyline, b.m_startDistance, b.m_endDistance); ASSERT_LESS_OR_EQUAL(points.size(), polyline.GetSize(), ()); - PrepareArrowGeometry(points, region.GetTexRect(), depth, geometry, joinsGeometry); + PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depth, geometry, joinsGeometry); depth += 1.0f; } @@ -402,7 +411,7 @@ void RouteShape::CacheRoute(ref_ptr<dp::TextureManager> textures, RouteData & ro { TGeometryBuffer geometry; TGeometryBuffer joinsGeometry; - PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), + PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), routeData.m_pivot, 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 21af6439fa..8495826f02 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -62,6 +62,7 @@ struct RouteData int m_routeIndex; m2::PolylineD m_sourcePolyline; vector<double> m_sourceTurns; + m2::PointD m_pivot; df::ColorConstant m_color; double m_length; RouteRenderProperty m_route; @@ -79,6 +80,7 @@ struct RouteSignData struct RouteArrowsData { RouteRenderProperty m_arrows; + m2::PointD m_pivot; }; class RouteShape @@ -95,9 +97,11 @@ public: vector<ArrowBorders> const & borders, RouteArrowsData & routeArrowsData); private: - static void PrepareGeometry(vector<m2::PointD> const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength); - static void PrepareArrowGeometry(vector<m2::PointD> const & path, m2::RectF const & texRect, float depth, + static void PrepareGeometry(vector<m2::PointD> const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength); + static void PrepareArrowGeometry(vector<m2::PointD> const & path, m2::PointD const & pivot, + m2::RectF const & texRect, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry); static void BatchGeometry(dp::GLState const & state, ref_ptr<void> geometry, size_t geomSize, ref_ptr<void> joinsGeometry, size_t joinsGeomSize, diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 2a7a3a8102..e65a9eeabc 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -162,8 +162,8 @@ void RuleDrawer::operator()(FeatureType const & f) // highway-path-bridge and building (sic!) at the same time (pedestrian crossing). is3dBuilding = (ftypes::IsBuildingChecker::Instance()(f) || ftypes::IsBuildingPartChecker::Instance()(f)) && - !ftypes::IsBridgeChecker::Instance()(f) && - !ftypes::IsTunnelChecker::Instance()(f); + !ftypes::IsBridgeChecker::Instance()(f) && + !ftypes::IsTunnelChecker::Instance()(f); } m2::PointD featureCenter; @@ -220,8 +220,9 @@ void RuleDrawer::operator()(FeatureType const & f) if (applyPointStyle || is3dBuilding) minVisibleScale = feature::GetMinDrawableScale(f); - ApplyAreaFeature apply(insertShape, f.GetID(), m_globalRect, areaMinHeight, areaHeight, - minVisibleScale, f.GetRank(), s.GetCaptionDescription()); + ApplyAreaFeature apply(m_globalRect.Center(), insertShape, f.GetID(), m_globalRect, + areaMinHeight, areaHeight, minVisibleScale, f.GetRank(), + s.GetCaptionDescription()); f.ForEachTriangle(apply, zoomLevel); apply.SetHotelData(ExtractHotelData(f)); if (applyPointStyle) @@ -235,8 +236,9 @@ void RuleDrawer::operator()(FeatureType const & f) } else if (s.LineStyleExists()) { - ApplyLineFeature apply(insertShape, f.GetID(), m_globalRect, minVisibleScale, f.GetRank(), - s.GetCaptionDescription(), m_currentScaleGtoP, + ApplyLineFeature apply(m_globalRect.Center(), m_currentScaleGtoP, + insertShape, f.GetID(), m_globalRect, minVisibleScale, + f.GetRank(), s.GetCaptionDescription(), zoomLevel >= kLineSimplifyLevelStart && zoomLevel <= kLineSimplifyLevelEnd, f.GetPointsCount()); f.ForEachPoint(apply, zoomLevel); @@ -253,7 +255,7 @@ void RuleDrawer::operator()(FeatureType const & f) ASSERT(s.PointStyleExists(), ()); minVisibleScale = feature::GetMinDrawableScale(f); - ApplyPointFeature apply(insertShape, f.GetID(), minVisibleScale, f.GetRank(), + ApplyPointFeature apply(m_globalRect.Center(), insertShape, f.GetID(), minVisibleScale, f.GetRank(), s.GetCaptionDescription(), 0.0f /* posZ */); apply.SetHotelData(ExtractHotelData(f)); f.ForEachPoint([&apply](m2::PointD const & pt) { apply(pt, false /* hasArea */); }, zoomLevel); @@ -277,6 +279,7 @@ void RuleDrawer::operator()(FeatureType const & f) m2::SharedSpline spline(path); df::LineViewParams p; + p.m_tileCenter = m_globalRect.Center(); p.m_baseGtoPScale = 1.0; p.m_cap = dp::ButtCap; p.m_color = dp::Color::Red(); @@ -287,6 +290,7 @@ void RuleDrawer::operator()(FeatureType const & f) insertShape(make_unique_dp<LineShape>(spline, p)); df::TextViewParams tp; + tp.m_tileCenter = m_globalRect.Center(); tp.m_anchor = dp::Center; tp.m_depth = 20000; tp.m_primaryText = strings::to_string(key.m_x) + " " + diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp index dd5a6ebb4d..caafa84566 100644 --- a/drape_frontend/selection_shape.cpp +++ b/drape_frontend/selection_shape.cpp @@ -1,5 +1,8 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/attribute_provider.hpp" @@ -125,7 +128,7 @@ void SelectionShape::Hide() m_selectedObject = OBJECT_EMPTY; } -void SelectionShape::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, +void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { ShowHideAnimation::EState state = m_animation.GetState(); @@ -133,7 +136,12 @@ void SelectionShape::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramMan state == ShowHideAnimation::STATE_SHOW_DIRECTION) { dp::UniformValuesStorage uniforms = commonUniforms; - uniforms.SetFloatValue("u_position", m_position.x, m_position.y, -m_positionZ); + TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); + math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, -m_positionZ); float accuracy = m_mapping.GetValue(m_animation.GetT()); if (screen.isPerspective()) diff --git a/drape_frontend/selection_shape.hpp b/drape_frontend/selection_shape.hpp index 8eab71f90e..3f47a10c3a 100644 --- a/drape_frontend/selection_shape.hpp +++ b/drape_frontend/selection_shape.hpp @@ -35,8 +35,7 @@ public: void SetPosition(m2::PointD const & position) { m_position = position; } void Show(ESelectedObject obj, m2::PointD const & position, double positionZ, bool isAnimate); void Hide(); - void Render(ScreenBase const & screen, - ref_ptr<dp::GpuProgramManager> mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); ESelectedObject GetSelectedObject() const; diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index be8eea5fd8..51036d8eac 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -12,11 +12,14 @@ namespace df { +double const kShapeCoordScalar = 1000; + struct CommonViewParams { float m_depth = 0.0f; int m_minVisibleScale = 0; uint8_t m_rank = 0; + m2::PointD m_tileCenter; }; struct PoiSymbolViewParams : CommonViewParams diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp index d38f88f380..dd758b09df 100644 --- a/drape_frontend/text_layout.cpp +++ b/drape_frontend/text_layout.cpp @@ -1,6 +1,5 @@ #include "drape_frontend/text_layout.hpp" -#include "drape_frontend/visual_params.hpp" - +#include "drape_frontend/map_shape.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/fribidi.hpp" @@ -436,8 +435,9 @@ void StraightTextLayout::Cache(glm::vec4 const & pivot, glm::vec2 const & pixelO } } -PathTextLayout::PathTextLayout(strings::UniString const & text, float fontSize, - ref_ptr<dp::TextureManager> textures) +PathTextLayout::PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text, + float fontSize, ref_ptr<dp::TextureManager> textures) + : m_tileCenter(tileCenter) { Init(fribidi::log2vis(text), fontSize, textures); } @@ -481,6 +481,8 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo glsl::vec2 pxPivot = glsl::ToVec2(iter.m_pos); buffer.resize(4 * m_metrics.size()); + + glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertToLocal(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f); for (size_t i = 0; i < m_metrics.size(); ++i) { GlyphRegion const & g = m_metrics[i]; @@ -501,7 +503,6 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo size_t baseIndex = 4 * i; - glsl::vec4 pivot(glsl::ToVec2(globalPivot), depth, 0.0f); buffer[baseIndex + 0] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * xOffset); buffer[baseIndex + 1] = gpu::TextDynamicVertex(pivot, formingVector + normal * upVector + tangent * xOffset); buffer[baseIndex + 2] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * (pxSize.x + xOffset)); diff --git a/drape_frontend/text_layout.hpp b/drape_frontend/text_layout.hpp index 41edeca819..9b11365ba2 100644 --- a/drape_frontend/text_layout.hpp +++ b/drape_frontend/text_layout.hpp @@ -55,7 +55,7 @@ protected: class StraightTextLayout : public TextLayout { - typedef TextLayout TBase; + using TBase = TextLayout; public: StraightTextLayout(strings::UniString const & text, float fontSize, @@ -82,9 +82,9 @@ private: class PathTextLayout : public TextLayout { - typedef TextLayout TBase; + using TBase = TextLayout; public: - PathTextLayout(strings::UniString const & text, + PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text, float fontSize, ref_ptr<dp::TextureManager> textures); void CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion, @@ -107,6 +107,8 @@ public: private: static float CalculateTextLength(float textPixelLength); + + m2::PointD m_tileCenter; }; class SharedTextLayout diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index 7da84dda33..1147282e66 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -197,7 +197,8 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - layout.Cache(glsl::vec4(glsl::ToVec2(m_basePoint), m_params.m_depth, -m_params.m_posZ), + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, staticBuffer, dynamicBuffer); dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::OverlayLayer); @@ -244,7 +245,8 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - layout.Cache(glsl::vec4(glsl::ToVec2(m_basePoint), m_params.m_depth, -m_params.m_posZ), + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, outline, staticBuffer, dynamicBuffer); dp::GLState state(gpu::TEXT_OUTLINED_PROGRAM, dp::GLState::OverlayLayer); diff --git a/drape_frontend/tile_key.cpp b/drape_frontend/tile_key.cpp index 106795ce63..2449960f15 100755 --- a/drape_frontend/tile_key.cpp +++ b/drape_frontend/tile_key.cpp @@ -1,4 +1,6 @@ #include "drape_frontend/tile_key.hpp" + +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/tile_utils.hpp" #include "indexer/scales.hpp" @@ -80,6 +82,11 @@ m2::RectD TileKey::GetGlobalRect(bool clipByDataMaxZoom) const return m2::RectD (startX, startY, startX + rectSize, startY + rectSize); } +math::Matrix<float, 4, 4> TileKey::GetTileBasedModelView(ScreenBase const & screen) const +{ + return screen.GetModelView(GetGlobalRect().Center(), kShapeCoordScalar); +} + string DebugPrint(TileKey const & key) { ostringstream out; diff --git a/drape_frontend/tile_key.hpp b/drape_frontend/tile_key.hpp index b9a2de9395..9818728d4e 100755 --- a/drape_frontend/tile_key.hpp +++ b/drape_frontend/tile_key.hpp @@ -1,6 +1,9 @@ #pragma once #include "geometry/rect2d.hpp" +#include "geometry/screenbase.hpp" + +#include "base/matrix.hpp" namespace df { @@ -24,6 +27,8 @@ struct TileKey m2::RectD GetGlobalRect(bool clipByDataMaxZoom = true) const; + math::Matrix<float, 4, 4> GetTileBasedModelView(ScreenBase const & screen) const; + int m_x; int m_y; int m_zoomLevel; diff --git a/drape_frontend/tile_utils.cpp b/drape_frontend/tile_utils.cpp index 45853f459f..2496103581 100755 --- a/drape_frontend/tile_utils.cpp +++ b/drape_frontend/tile_utils.cpp @@ -46,4 +46,13 @@ int ClipTileZoomByMaxDataZoom(int zoom) return zoom <= upperScale ? zoom : upperScale; } +TileKey GetTileKeyByPoint(m2::PointD const & pt, int zoom) +{ + ASSERT_GREATER(zoom, 0, ()); + double const range = MercatorBounds::maxX - MercatorBounds::minX; + double const rectSize = range / (1 << (zoom - 1)); + return TileKey(static_cast<int>(floor(pt.x / rectSize)), + static_cast<int>(floor(pt.y / rectSize)), zoom); +} + } // namespace df diff --git a/drape_frontend/tile_utils.hpp b/drape_frontend/tile_utils.hpp index eb23761279..c6a098ceb7 100755 --- a/drape_frontend/tile_utils.hpp +++ b/drape_frontend/tile_utils.hpp @@ -28,4 +28,7 @@ bool IsNeighbours(TileKey const & tileKey1, TileKey const & tileKey2); /// This function performs clipping by maximum zoom label available for map data. int ClipTileZoomByMaxDataZoom(int zoom); +/// This function returns tile key by point on specific zoom level. +TileKey GetTileKeyByPoint(m2::PointD const & pt, int zoom); + } // namespace df diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index e186f9fcc4..6700da3e6d 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -1,6 +1,9 @@ -#include "user_mark_shapes.hpp" +#include "drape_frontend/user_mark_shapes.hpp" -#include "line_shape.hpp" +#include "drape_frontend/line_shape.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/utils/vertex_decl.hpp" #include "drape/shader_def.hpp" @@ -13,40 +16,6 @@ namespace df namespace { - int const ZUserMarksLayer = -1; - int const YSearchMarksLayer = 1; - int const YApiMarksLayer = 2; - int const YBookmarksLayer = 3; - int const YDebugLayer = 4; -} - -TileKey GetSearchTileKey() -{ - return TileKey(0, YSearchMarksLayer, ZUserMarksLayer); -} - -TileKey GetApiTileKey() -{ - return TileKey(0, YApiMarksLayer, ZUserMarksLayer); -} - -TileKey GetDebugTileKey() -{ - return TileKey(0, YDebugLayer, ZUserMarksLayer); -} - -TileKey GetBookmarkTileKey(size_t categoryIndex) -{ - return TileKey(categoryIndex, YBookmarksLayer, ZUserMarksLayer); -} - -bool IsUserMarkLayer(TileKey const & tileKey) -{ - return tileKey.m_zoomLevel == ZUserMarksLayer; -} - -namespace -{ template <typename TCreateVector> void AlignFormingNormals(TCreateVector const & fn, dp::Anchor anchor, @@ -87,8 +56,7 @@ struct UserPointVertex : gpu::BaseVertex , m_normal(normal) , m_texCoord(texCoord) , m_isAnim(isAnim ? 1.0 : -1.0) - { - } + {} static dp::BindingInfo GetBinding() { @@ -110,104 +78,143 @@ struct UserPointVertex : gpu::BaseVertex using UPV = UserPointVertex; -void CacheUserPoints(UserMarksProvider const * provider, - ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +void CacheUserPoints(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures, + TUserMarkShapes & outShapes) { size_t markCount = provider->GetUserPointCount(); if (markCount == 0) return; - uint32_t vertexCount = dp::Batcher::VertexPerQuad * markCount; // 4 vertex per quad - - buffer_vector<UPV, 1024> buffer; - buffer.reserve(vertexCount); - - vector<UserPointMark const *> marks; - marks.reserve(markCount); + int const kZoomLevel = 10; + map<TileKey, vector<UserPointMark const *>> marks; for (size_t i = 0; i < markCount; ++i) - marks.push_back(provider->GetUserPointMark(i)); - - sort(marks.begin(), marks.end(), [](UserPointMark const * v1, UserPointMark const * v2) { - return v1->GetPivot().y < v2->GetPivot().y; - }); + UserPointMark const * userMark = provider->GetUserPointMark(i); + TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel); + marks[tileKey].push_back(userMark); + } - dp::TextureManager::SymbolRegion region; - for (size_t i = 0; i < marks.size(); ++i) + for (auto it = marks.begin(); it != marks.end(); ++it) { - UserPointMark const * pointMark = marks[i]; - textures->GetSymbolRegion(pointMark->GetSymbolName(), region); - m2::RectF const & texRect = region.GetTexRect(); - m2::PointF pxSize = region.GetPixelSize(); - dp::Anchor anchor = pointMark->GetAnchor(); - glsl::vec3 pos = glsl::vec3(glsl::ToVec2(pointMark->GetPivot()), pointMark->GetDepth()); - bool runAnim = pointMark->RunCreationAnim(); - - 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 = pointMark->GetPixelOffset(); - 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); - } + TileKey const & key = it->first; + m2::PointD const tileCenter = key.GetGlobalRect().Center(); + + sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2) + { + return v1->GetPivot().y < v2->GetPivot().y; + }); - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); + dp::TextureManager::SymbolRegion region; - dp::AttributeProvider attribProvider(1, buffer.size()); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad; + uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad; + buffer_vector<UPV, 128> buffer; + buffer.reserve(vertexCount); - batcher->InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + for (size_t i = 0; i < it->second.size(); ++i) + { + UserPointMark const * pointMark = it->second[i]; + textures->GetSymbolRegion(pointMark->GetSymbolName(), region); + m2::RectF const & texRect = region.GetTexRect(); + m2::PointF const pxSize = region.GetPixelSize(); + dp::Anchor const anchor = pointMark->GetAnchor(); + m2::PointD const pt = MapShape::ConvertToLocal(pointMark->GetPivot(), tileCenter, kShapeCoordScalar); + glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), pointMark->GetDepth()); + bool const runAnim = pointMark->RunCreationAnim(); + + 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 = pointMark->GetPixelOffset(); + 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); + } + + dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); + state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); + state.SetColorTexture(region.GetTexture()); + state.SetTextureFilter(gl_const::GLNearest); + + dp::Batcher batcher(indicesCount, vertexCount); + dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, + drape_ptr<dp::RenderBucket> && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + dp::AttributeProvider attribProvider(1, buffer.size()); + attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + } } -void CacheUserLines(UserMarksProvider const * provider, - ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures, + TUserMarkShapes & outShapes) { + int const kZoomLevel = 10; + map<TileKey, vector<pair<UserLineMark const *, m2::SharedSpline>>> userLines; for (size_t i = 0; i < provider->GetUserLineCount(); ++i) { UserLineMark const * line = provider->GetUserLineMark(i); - size_t pointCount = line->GetPointCount(); + size_t const pointCount = line->GetPointCount(); vector<m2::PointD> points; + m2::RectD rect; points.reserve(pointCount); for (size_t i = 0; i < pointCount; ++i) + { points.push_back(line->GetPoint(i)); + rect.Add(points.back()); + } - m2::SharedSpline spline(points); + TileKey const tileKey = GetTileKeyByPoint(rect.Center(), kZoomLevel); + userLines[tileKey].push_back(make_pair(line, m2::SharedSpline(points))); + } - for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) + int const kBatchSize = 5000; + for (auto it = userLines.begin(); it != userLines.end(); ++it) + { + TileKey const & key = it->first; + dp::Batcher batcher(kBatchSize, kBatchSize); + dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, + drape_ptr<dp::RenderBucket> && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + for (auto const & lineData : it->second) { - LineViewParams params; - params.m_baseGtoPScale = 1.0f; - params.m_cap = dp::RoundCap; - params.m_join = dp::RoundJoin; - params.m_color = line->GetColor(layerIndex); - params.m_depth = line->GetLayerDepth(layerIndex); - params.m_width = line->GetWidth(layerIndex); - params.m_minVisibleScale = 1; - params.m_rank = 0; - - LineShape(spline, params).Draw(batcher, textures); + UserLineMark const * line = lineData.first; + for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) + { + LineViewParams params; + params.m_tileCenter = key.GetGlobalRect().Center(); + params.m_baseGtoPScale = 1.0f; + params.m_cap = dp::RoundCap; + params.m_join = dp::RoundJoin; + params.m_color = line->GetColor(layerIndex); + params.m_depth = line->GetLayerDepth(layerIndex); + params.m_width = line->GetWidth(layerIndex); + params.m_minVisibleScale = 1; + params.m_rank = 0; + + LineShape(lineData.second, params).Draw(make_ref(&batcher), textures); + } } } } } // namespace -void CacheUserMarks(UserMarksProvider const * provider, - ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures) { - CacheUserPoints(provider, batcher, textures); - CacheUserLines(provider, batcher, textures); + TUserMarkShapes shapes; + CacheUserPoints(provider, textures, shapes); + CacheUserLines(provider, textures, shapes); + return shapes; } } // namespace df diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index 361d6c86b3..bd0e35e1ff 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -12,12 +12,22 @@ namespace df { - TileKey GetSearchTileKey(); - TileKey GetApiTileKey(); - TileKey GetDebugTileKey(); - TileKey GetBookmarkTileKey(size_t categoryIndex); - bool IsUserMarkLayer(TileKey const & tileKey); - - void CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures); + +struct UserMarkShape +{ + dp::GLState m_state; + drape_ptr<dp::RenderBucket> m_bucket; + TileKey m_tileKey; + + UserMarkShape(dp::GLState const & state, drape_ptr<dp::RenderBucket> && bucket, + TileKey const & tileKey) + : m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey) + {} +}; + +using TUserMarkShapes = vector<UserMarkShape>; + +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, + ref_ptr<dp::TextureManager> textures); + } // namespace df |