From feda627f30fd97b62f904c43ca3c8f3f1e608ca0 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Thu, 1 Sep 2016 18:13:15 +0300 Subject: [PATCH 1/2] Added tile-based model-view --- drape/glsl_types.hpp | 5 ++ .../shaders/arrow3d_shadow_vertex_shader.vsh | 4 +- drape/shaders/arrow3d_vertex_shader.vsh | 4 +- drape/shaders/circle_shader.vsh | 4 +- drape/shaders/dashed_vertex_shader.vsh | 4 +- .../masked_texturing_vertex_shader.vsh | 6 +- drape/shaders/my_position_shader.vsh | 6 +- drape/shaders/path_symbol_vertex_shader.vsh | 6 +- .../text_outlined_gui_vertex_shader.vsh | 6 +- drape/shaders/text_outlined_vertex_shader.vsh | 6 +- drape/shaders/text_vertex_shader.vsh | 6 +- drape/shaders/texturing_vertex_shader.vsh | 6 +- drape/shaders/trackpoint_vertex_shader.vsh | 7 +- drape_frontend/apply_feature_functors.cpp | 43 +++++++---- drape_frontend/apply_feature_functors.hpp | 26 ++++--- drape_frontend/area_shape.cpp | 34 ++++----- drape_frontend/area_shape.hpp | 4 +- drape_frontend/arrow3d.cpp | 4 +- drape_frontend/arrow3d.hpp | 2 +- drape_frontend/circle_shape.cpp | 7 +- drape_frontend/frontend_renderer.cpp | 34 +++------ drape_frontend/frontend_renderer.hpp | 2 +- drape_frontend/gps_track_renderer.cpp | 15 +++- drape_frontend/gps_track_renderer.hpp | 1 + drape_frontend/line_shape.cpp | 73 ++++--------------- drape_frontend/map_shape.hpp | 7 ++ drape_frontend/my_position.cpp | 27 +++++-- drape_frontend/my_position.hpp | 4 +- drape_frontend/my_position_controller.cpp | 7 +- drape_frontend/my_position_controller.hpp | 2 +- drape_frontend/path_symbol_shape.cpp | 2 +- drape_frontend/path_text_shape.cpp | 4 +- drape_frontend/poi_symbol_shape.cpp | 3 +- drape_frontend/render_group.cpp | 12 ++- drape_frontend/route_builder.cpp | 2 + drape_frontend/route_renderer.cpp | 8 +- drape_frontend/route_shape.cpp | 57 +++++++++------ drape_frontend/route_shape.hpp | 10 ++- drape_frontend/rule_drawer.cpp | 18 +++-- drape_frontend/selection_shape.cpp | 12 ++- drape_frontend/selection_shape.hpp | 3 +- drape_frontend/shape_view_params.hpp | 3 + drape_frontend/text_layout.cpp | 11 +-- drape_frontend/text_layout.hpp | 8 +- drape_frontend/text_shape.cpp | 6 +- drape_frontend/tile_key.cpp | 7 ++ drape_frontend/tile_key.hpp | 5 ++ drape_frontend/tile_utils.cpp | 9 +++ drape_frontend/tile_utils.hpp | 3 + drape_head/testing_engine.cpp | 4 +- geometry/screenbase.cpp | 21 ++++++ geometry/screenbase.hpp | 3 + 52 files changed, 332 insertions(+), 241 deletions(-) diff --git a/drape/glsl_types.hpp b/drape/glsl_types.hpp index 48f3a27092..7831e2d45b 100644 --- a/drape/glsl_types.hpp +++ b/drape/glsl_types.hpp @@ -56,6 +56,11 @@ inline vec2 ToVec2(m2::PointD const & pt) return glsl::vec2(pt.x, pt.y); } +inline m2::PointD FromVec2(glsl::vec2 const & pt) +{ + return m2::PointD(pt.x, pt.y); +} + inline vec4 ToVec4(dp::Color const & color) { return glsl::vec4(double(color.GetRed()) / 255, diff --git a/drape/shaders/arrow3d_shadow_vertex_shader.vsh b/drape/shaders/arrow3d_shadow_vertex_shader.vsh index a46afd5dc6..1eb3664869 100644 --- a/drape/shaders/arrow3d_shadow_vertex_shader.vsh +++ b/drape/shaders/arrow3d_shadow_vertex_shader.vsh @@ -1,12 +1,12 @@ attribute vec4 a_pos; -uniform mat4 m_transform; +uniform mat4 u_transform; varying float v_intensity; void main() { - vec4 position = m_transform * vec4(a_pos.x, a_pos.y, 0.0, 1.0); + vec4 position = u_transform * vec4(a_pos.x, a_pos.y, 0.0, 1.0); v_intensity = a_pos.w; gl_Position = position; } diff --git a/drape/shaders/arrow3d_vertex_shader.vsh b/drape/shaders/arrow3d_vertex_shader.vsh index ddd1063394..8e6e2194ce 100644 --- a/drape/shaders/arrow3d_vertex_shader.vsh +++ b/drape/shaders/arrow3d_vertex_shader.vsh @@ -1,7 +1,7 @@ attribute vec4 a_pos; attribute vec3 a_normal; -uniform mat4 m_transform; +uniform mat4 u_transform; varying vec2 v_intensity; @@ -9,7 +9,7 @@ const vec3 lightDir = vec3(0.316, 0.0, 0.948); void main() { - vec4 position = m_transform * vec4(a_pos.xyz, 1.0); + vec4 position = u_transform * vec4(a_pos.xyz, 1.0); v_intensity = vec2(max(0.0, -dot(lightDir, a_normal)), a_pos.w); gl_Position = position; } diff --git a/drape/shaders/circle_shader.vsh b/drape/shaders/circle_shader.vsh index 8c26ea861c..84fc8029fe 100644 --- a/drape/shaders/circle_shader.vsh +++ b/drape/shaders/circle_shader.vsh @@ -16,8 +16,8 @@ varying vec2 v_colorTexCoords; void main(void) { - lowp vec4 p = vec4(a_position, 1) * modelView; - highp vec4 pos = vec4(a_normal.xy, 0, 0) + p; + vec4 p = vec4(a_position, 1) * modelView; + vec4 pos = vec4(a_normal.xy, 0, 0) + p; pos = pos * projection; float w = pos.w; diff --git a/drape/shaders/dashed_vertex_shader.vsh b/drape/shaders/dashed_vertex_shader.vsh index 5704469871..63455bbcae 100644 --- a/drape/shaders/dashed_vertex_shader.vsh +++ b/drape/shaders/dashed_vertex_shader.vsh @@ -11,6 +11,8 @@ varying vec2 v_colorTexCoord; varying vec2 v_maskTexCoord; varying vec2 v_halfLength; +const float kShapeCoordScalar = 1000.0; + void main(void) { vec2 normal = a_normal.xy; @@ -23,7 +25,7 @@ void main(void) transformedAxisPos = transformedAxisPos + normalize(shiftPos - transformedAxisPos) * halfWidth; } - float uOffset = min(length(vec4(1, 0, 0, 0) * modelView) * a_maskTexCoord.x, 1.0); + float uOffset = min(length(vec4(kShapeCoordScalar, 0, 0, 0) * modelView) * a_maskTexCoord.x, 1.0); v_colorTexCoord = a_colorTexCoord; v_maskTexCoord = vec2(a_maskTexCoord.y + uOffset * a_maskTexCoord.z, a_maskTexCoord.w); v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z)); diff --git a/drape/shaders/masked_texturing_vertex_shader.vsh b/drape/shaders/masked_texturing_vertex_shader.vsh index 66f03e7077..4b6a261ed8 100644 --- a/drape/shaders/masked_texturing_vertex_shader.vsh +++ b/drape/shaders/masked_texturing_vertex_shader.vsh @@ -12,10 +12,8 @@ varying vec2 v_maskTexCoords; void main(void) { - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = vec4(a_position.xyz, 1) * modelView; - highp vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; + vec4 pos = vec4(a_position.xyz, 1) * modelView; + vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; diff --git a/drape/shaders/my_position_shader.vsh b/drape/shaders/my_position_shader.vsh index eabd2537f0..d6653f75d9 100644 --- a/drape/shaders/my_position_shader.vsh +++ b/drape/shaders/my_position_shader.vsh @@ -21,9 +21,9 @@ void main(void) rotation[2] = vec4(0.0, 0.0, 1.0, 0.0); rotation[3] = vec4(0.0, 0.0, 0.0, 1.0); - lowp vec4 pos = vec4(u_position, 1.0) * modelView; - highp vec4 normal = vec4(a_normal, 0, 0); - highp vec4 shiftedPos = normal * rotation + pos; + vec4 pos = vec4(u_position, 1.0) * modelView; + vec4 normal = vec4(a_normal, 0, 0); + vec4 shiftedPos = normal * rotation + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; diff --git a/drape/shaders/path_symbol_vertex_shader.vsh b/drape/shaders/path_symbol_vertex_shader.vsh index 38c6b7791a..0cfc4e6d44 100644 --- a/drape/shaders/path_symbol_vertex_shader.vsh +++ b/drape/shaders/path_symbol_vertex_shader.vsh @@ -10,9 +10,9 @@ varying vec2 v_colorTexCoords; void main(void) { - lowp vec4 pos = vec4(a_position.xyz, 1) * modelView; - highp vec4 norm = vec4(a_normal, 0, 0) * modelView; - highp vec4 shiftedPos = norm + pos; + vec4 pos = vec4(a_position.xyz, 1) * modelView; + vec4 norm = vec4(a_normal, 0, 0) * modelView; + vec4 shiftedPos = norm + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; diff --git a/drape/shaders/text_outlined_gui_vertex_shader.vsh b/drape/shaders/text_outlined_gui_vertex_shader.vsh index 6a60995631..d789392d11 100755 --- a/drape/shaders/text_outlined_gui_vertex_shader.vsh +++ b/drape/shaders/text_outlined_gui_vertex_shader.vsh @@ -27,10 +27,8 @@ void main() float notOutline = One - isOutline; float depthShift = BaseDepthShift * isOutline; - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = (vec4(a_position.xyz, 1.0) + vec4(Zero, Zero, depthShift, Zero)) * modelView; - highp vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; + vec4 pos = (vec4(a_position.xyz, 1.0) + vec4(Zero, Zero, depthShift, Zero)) * modelView; + vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; gl_Position = shiftedPos * projection; vec2 colorTexCoord = a_colorTexCoord * notOutline + a_outlineColorTexCoord * isOutline; #ifdef ENABLE_VTF diff --git a/drape/shaders/text_outlined_vertex_shader.vsh b/drape/shaders/text_outlined_vertex_shader.vsh index 977a3de444..2631954ce2 100755 --- a/drape/shaders/text_outlined_vertex_shader.vsh +++ b/drape/shaders/text_outlined_vertex_shader.vsh @@ -28,10 +28,8 @@ void main() float notOutline = One - isOutline; float depthShift = BaseDepthShift * isOutline; - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = (vec4(a_position.xyz, 1) + vec4(Zero, Zero, depthShift, Zero)) * modelView; - highp vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; + vec4 pos = (vec4(a_position.xyz, 1) + vec4(Zero, Zero, depthShift, Zero)) * modelView; + vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; diff --git a/drape/shaders/text_vertex_shader.vsh b/drape/shaders/text_vertex_shader.vsh index e7be2fd7eb..dd11320841 100644 --- a/drape/shaders/text_vertex_shader.vsh +++ b/drape/shaders/text_vertex_shader.vsh @@ -22,10 +22,8 @@ const float One = 1.0; void main() { - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = vec4(a_position.xyz, 1) * modelView; - highp vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; + vec4 pos = vec4(a_position.xyz, 1) * modelView; + vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; diff --git a/drape/shaders/texturing_vertex_shader.vsh b/drape/shaders/texturing_vertex_shader.vsh index d633a12540..fd05958500 100644 --- a/drape/shaders/texturing_vertex_shader.vsh +++ b/drape/shaders/texturing_vertex_shader.vsh @@ -10,10 +10,8 @@ varying vec2 v_colorTexCoords; void main(void) { - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = vec4(a_position.xyz, 1) * modelView; - highp vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; + vec4 pos = vec4(a_position.xyz, 1) * modelView; + vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; diff --git a/drape/shaders/trackpoint_vertex_shader.vsh b/drape/shaders/trackpoint_vertex_shader.vsh index 1997cea791..4c87712fc2 100644 --- a/drape/shaders/trackpoint_vertex_shader.vsh +++ b/drape/shaders/trackpoint_vertex_shader.vsh @@ -17,11 +17,8 @@ varying vec4 v_color; void main(void) { vec3 radius = a_normal * a_position.z; - - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = vec4(a_position.xy, 0, 1) * modelView; - highp vec4 shiftedPos = vec4(radius.xy, 0, 0) + pos; + vec4 pos = vec4(a_position.xy, 0, 1) * modelView; + vec4 shiftedPos = vec4(radius.xy, 0, 0) + pos; vec4 finalPos = shiftedPos * projection; float w = finalPos.w; finalPos.xyw = (pivotTransform * vec4(finalPos.xy, 0.0, w)).xyw; diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 3091f10cb1..f3c38b68da 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,9 +422,12 @@ 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 tileRect, 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) @@ -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..b95baf4ab0 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -31,7 +31,8 @@ using TInsertShapeFn = function && 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 tileRect, float minPosZ, + float posZ, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions); using TBase::operator (); @@ -112,7 +119,7 @@ private: bool FindEdge(TEdge const & edge); m2::PointD CalculateNormal(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) const; - vector m_triangles; + vector m_triangles; unordered_map m_indices; vector> m_edges; @@ -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..6955ccb2df 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -15,7 +15,7 @@ namespace df { -AreaShape::AreaShape(vector && triangleList, vector && buildingEdges, +AreaShape::AreaShape(vector && triangleList, vector && buildingEdges, AreaViewParams const & params) : m_vertexes(move(triangleList)) , m_buildingEdges(move(buildingEdges)) @@ -36,26 +36,25 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t for (auto const & edge : m_buildingEdges) { - 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)); + glsl::vec2 const startPt = glsl::ToVec2(ConvertPt(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const endPt = glsl::ToVec2(ConvertPt(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); - 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)); + glsl::vec3 normal(glsl::ToVec2(edge.m_normal), 0.0f); + 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(ConvertPt(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 batcher, ref_ptr 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(ConvertPt(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 && triangleList, vector && buildingEdges, + AreaShape(vector && triangleList, vector && buildingEdges, AreaViewParams const & params); void Draw(ref_ptr batcher, ref_ptr textures) const override; private: - vector m_vertexes; + vector m_vertexes; vector 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 mng) +void Arrow3d::Render(ScreenBase const & screen, int zoomLevel, ref_ptr 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 pro dp::UniformValuesStorage uniforms; math::Matrix 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 texMng); void SetPositionObsolete(bool obsolete); - void Render(ScreenBase const & screen, ref_ptr mng); + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng); private: void Build(); diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 3fd8fba4aa..537133d0b5 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -24,12 +24,13 @@ void CircleShape::Draw(ref_ptr batcher, ref_ptr 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(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); buffer_vector 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 batcher, ref_ptr 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/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index e73e37def3..55c0999e4e 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1027,12 +1027,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,19 +1059,18 @@ 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); @@ -1082,7 +1083,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & 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); @@ -1223,22 +1224,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 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 +1696,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..48418794a7 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -161,7 +161,7 @@ private: void MergeBuckets(); void RenderSingleGroup(ScreenBase const & modelView, ref_ptr group); void RefreshProjection(ScreenBase const & screen); - void RefreshModelView(ScreenBase const & screen); + void RefreshZScale(ScreenBase const & screen); void RefreshPivotTransform(ScreenBase const & screen); void RefreshBgColor(); diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index b5137402be..fcb47e6f70 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::ConvertPt(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(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::ConvertPt(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::ConvertPt(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 mv = screen.GetModelView(m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr 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> 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..20d95615a5 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(); @@ -135,42 +128,6 @@ public: return isLeft ? 1.0 : -1.0; } -protected: - vector 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 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; @@ -200,8 +157,7 @@ class SolidLineBuilder : public BaseLineBuilder : 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((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); - maskSize = globalLength / steps; + return static_cast((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); } dp::GLState GetState() override @@ -381,16 +336,16 @@ void LineShape::Construct(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(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(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((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 & 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 & builder) const generateJoins = false; // build geometry - glsl::vec2 firstPoint = glsl::vec2(path.front().x, path.front().y); + glsl::vec2 firstPoint = glsl::ToVec2(ConvertPt(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 & 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(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(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..8582670328 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 ConvertPt(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) + { + return (basePt - tileCenter) * scalar; + } + private: int m_minZoom = 0; }; diff --git a/drape_frontend/my_position.cpp b/drape_frontend/my_position.cpp index f3e682fa1e..98afdd7f2f 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 mng, - dp::UniformValuesStorage const & commonUniforms) +void MyPosition::RenderAccuracy(ScreenBase const & screen, int zoomLevel, + ref_ptr 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 mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(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 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 mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(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 mng, dp::UniformValuesStorage const & commonUniforms); - void RenderMyPosition(ScreenBase const & screen, + void RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr 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 mng, +void MyPositionController::Render(ScreenBase const & screen, int zoomLevel, + ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { if (IsWaitingForLocation()) @@ -551,8 +552,8 @@ void MyPositionController::Render(ScreenBase const & screen, ref_ptrSetAccuracy(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 mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr 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..8715588fce 100644 --- a/drape_frontend/path_symbol_shape.cpp +++ b/drape_frontend/path_symbol_shape.cpp @@ -40,7 +40,7 @@ void PathSymbolShape::Draw(ref_ptr batcher, ref_ptr textures, void PathTextShape::Draw(ref_ptr batcher, ref_ptr textures) const { - unique_ptr layout = make_unique(strings::MakeUniString(m_params.m_text), - m_params.m_textFont.m_size, textures); + auto layout = make_unique(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..8567d4e4f0 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -108,7 +108,8 @@ void PoiSymbolShape::Draw(ref_ptr batcher, ref_ptrGetSymbolRegion(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(ConvertPt(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 handle = make_unique_dp(m_params.m_id, diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index ffc8318b67..7cc96170f0 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 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) { @@ -215,6 +221,10 @@ void UserMarkRenderGroup::UpdateAnimation() void UserMarkRenderGroup::Render(ScreenBase const & screen) { BaseRenderGroup::Render(screen); + + math::Matrix mv = screen.GetModelView(); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + ref_ptr shader = screen.isPerspective() ? m_shader3d : m_shader; dp::ApplyUniforms(m_uniforms, shader); if (m_renderBucket != nullptr) 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 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 const & bord return; drape_ptr routeArrowsData = make_unique_dp(); + 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 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 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 const & sign, Scree return; dp::GLState const & state = sign->m_sign.m_state; - dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix mv = screen.GetModelView(sign->m_position, 1.0); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr program = screen.isPerspective() ? mng->GetProgram(state.GetProgram3dIndex()) diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 5acafd0e21..9954e098e7 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 const } // namespace -void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength) +void RouteShape::PrepareGeometry(vector const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength) { ASSERT(path.size() > 1, ()); @@ -139,8 +142,13 @@ void RouteShape::PrepareGeometry(vector 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::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertPt(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 const & path, TGeometryBuffe vector 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 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 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 const & path, TGeometryBuffe outputLength = length; } -void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF const & texRect, float depth, +void RouteShape::PrepareArrowGeometry(vector 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 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::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertPt(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 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 const & path, m2::RectF }; float const u = 1.0f - kArrowHeadSize; vector 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 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 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 mng, m2::PolylineD { vector 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 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 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 const & borders, RouteArrowsData & routeArrowsData); private: - static void PrepareGeometry(vector const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength); - static void PrepareArrowGeometry(vector const & path, m2::RectF const & texRect, float depth, + static void PrepareGeometry(vector const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength); + static void PrepareArrowGeometry(vector 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 geometry, size_t geomSize, ref_ptr 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(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..224ab48197 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 mng, +void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { ShowHideAnimation::EState state = m_animation.GetState(); @@ -133,7 +136,12 @@ void SelectionShape::Render(ScreenBase const & screen, ref_ptr mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(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 mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr 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..545dfa3878 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 textures) +PathTextLayout::PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text, + float fontSize, ref_ptr 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::ConvertPt(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 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..b1bcee28c6 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(ConvertPt(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(ConvertPt(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 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 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(floor(pt.x / rectSize)), + static_cast(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_head/testing_engine.cpp b/drape_head/testing_engine.cpp index e01769c0ed..162073862b 100644 --- a/drape_head/testing_engine.cpp +++ b/drape_head/testing_engine.cpp @@ -506,8 +506,8 @@ void TestingEngine::DrawImpl() } { - vector trg{ m2::PointD(110.0f, 30.0f), m2::PointD(112.0f, 30.0f), m2::PointD(112.0f, 28.0f), - m2::PointD(110.0f, 30.0f), m2::PointD(112.0f, 28.0f), m2::PointD(110.0f, 28.0f) }; + vector trg{ m2::PointD(110.0, 30.0), m2::PointD(112.0, 30.0), m2::PointD(112.0, 28.0), + m2::PointD(110.0, 30.0), m2::PointD(112.0, 28.0), m2::PointD(110.0, 28.0) }; vector edges; AreaViewParams p; p.m_color = dp::Color::White(); diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 32ba27b523..be334dbdf3 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -509,3 +509,24 @@ bool ScreenBase::IsReverseProjection3d(m2::PointD const & pt) const Vector3dT const perspectivePoint = normalizedPoint * m_Pto3d; return perspectivePoint(0, 3) < 0.0; } + +ScreenBase::Matrix3dT ScreenBase::GetModelView() const +{ + return ScreenBase::Matrix3dT { m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), + m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), + 0, 0, 1, 0, + 0, 0, 0, 1 }; +} + +ScreenBase::Matrix3dT ScreenBase::GetModelView(m2::PointD const & pivot, double scalar) const +{ + MatrixT const & m = m_GtoP; + double const s = 1.0 / scalar; + return ScreenBase::Matrix3dT + { + s * m(0, 0), s * m(1, 0), 0, m(2, 0) + pivot.x * m(0, 0) + pivot.y * m(1, 0), + s * m(0, 1), s * m(1, 1), 0, m(2, 1) + pivot.x * m(0, 1) + pivot.y * m(1, 1), + 0, 0, 1, 0, + 0, 0, 0, 1 + }; +} diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 5094eabc8f..c0d462a90f 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -165,6 +165,9 @@ public: m2::RectD CalculatePixelRect(double scale) const; double CalculatePerspectiveAngle(double scale) const; + Matrix3dT GetModelView() const; + Matrix3dT GetModelView(m2::PointD const & pivot, double scalar) const; + static double CalculateAutoPerspectiveAngle(double scale); /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2) From b3752b5aacda9fb4b383ee2933467a7bd2f69cf6 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 6 Sep 2016 11:43:03 +0300 Subject: [PATCH 2/2] Added tile-based model view for user marks --- drape/batcher.cpp | 2 +- drape/shaders/user_mark.vsh | 6 +- drape_frontend/apply_feature_functors.cpp | 8 +- drape_frontend/apply_feature_functors.hpp | 4 +- drape_frontend/area_shape.cpp | 8 +- drape_frontend/backend_renderer.cpp | 11 +- drape_frontend/circle_shape.cpp | 2 +- drape_frontend/drape_engine.cpp | 12 +- drape_frontend/drape_engine.hpp | 6 +- drape_frontend/frontend_renderer.cpp | 73 +++++--- drape_frontend/frontend_renderer.hpp | 4 +- drape_frontend/gps_track_renderer.cpp | 6 +- drape_frontend/line_shape.cpp | 10 +- drape_frontend/map_shape.hpp | 2 +- drape_frontend/message.hpp | 1 + drape_frontend/message_subclasses.hpp | 51 ++++- drape_frontend/my_position.cpp | 4 +- drape_frontend/path_symbol_shape.cpp | 2 +- drape_frontend/poi_symbol_shape.cpp | 2 +- drape_frontend/render_group.cpp | 16 +- drape_frontend/render_group.hpp | 15 +- drape_frontend/route_shape.cpp | 16 +- drape_frontend/selection_shape.cpp | 2 +- drape_frontend/text_layout.cpp | 2 +- drape_frontend/text_shape.cpp | 4 +- drape_frontend/user_mark_shapes.cpp | 219 +++++++++++----------- drape_frontend/user_mark_shapes.hpp | 24 ++- geometry/screenbase.cpp | 11 +- map/bookmark.hpp | 2 +- map/bookmark_manager.cpp | 2 +- map/user_mark_container.cpp | 97 +++++----- 31 files changed, 346 insertions(+), 278 deletions(-) diff --git a/drape/batcher.cpp b/drape/batcher.cpp index 0153267db0..ea72fe4f88 100644 --- a/drape/batcher.cpp +++ b/drape/batcher.cpp @@ -262,7 +262,7 @@ Batcher * BatcherFactory::GetNew() const return new Batcher(kIndexBufferSize, kVertexBufferSize); } -SessionGuard::SessionGuard(Batcher & batcher, const Batcher::TFlushFn & flusher) +SessionGuard::SessionGuard(Batcher & batcher, Batcher::TFlushFn const & flusher) : m_batcher(batcher) { m_batcher.StartSession(flusher); diff --git a/drape/shaders/user_mark.vsh b/drape/shaders/user_mark.vsh index d5ab17330f..0fce199d47 100644 --- a/drape/shaders/user_mark.vsh +++ b/drape/shaders/user_mark.vsh @@ -16,10 +16,8 @@ void main(void) if (a_animate > 0.0) normal = u_interpolationT * normal; - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 p = vec4(a_position, 1) * modelView; - highp vec4 pos = vec4(normal, 0, 0) + p; + vec4 p = vec4(a_position, 1) * modelView; + vec4 pos = vec4(normal, 0, 0) + p; pos = pos * projection; float w = pos.w; pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index f3c38b68da..0710a5716f 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -424,13 +424,13 @@ void ApplyPointFeature::Finish() ApplyAreaFeature::ApplyAreaFeature(m2::PointD const & tileCenter, TInsertShapeFn const & insertShape, FeatureID const & id, - m2::RectD tileRect, float minPosZ, + 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) @@ -459,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, diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp index b95baf4ab0..e95efe075c 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -99,7 +99,7 @@ class ApplyAreaFeature : public ApplyPointFeature public: ApplyAreaFeature(m2::PointD const & tileCenter, TInsertShapeFn const & insertShape, FeatureID const & id, - m2::RectD tileRect, float minPosZ, + m2::RectD const & clipRect, float minPosZ, float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); @@ -125,7 +125,7 @@ private: vector> m_edges; float const m_minPosZ; bool const m_isBuilding; - m2::RectD m_tileRect; + m2::RectD m_clipRect; }; class ApplyLineFeature : public BaseApplyFeature diff --git a/drape_frontend/area_shape.cpp b/drape_frontend/area_shape.cpp index 6955ccb2df..44c7f9b459 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -36,8 +36,8 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t for (auto const & edge : m_buildingEdges) { - glsl::vec2 const startPt = glsl::ToVec2(ConvertPt(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const endPt = glsl::ToVec2(ConvertPt(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); + 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(startPt, -m_params.m_minPosZ), normal, colorPoint)); @@ -52,7 +52,7 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t glsl::vec3 normal(0.0f, 0.0f, -1.0f); for (auto const & vertex : m_vertexes) { - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)); + 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)); } @@ -70,7 +70,7 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr 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(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)), + return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(ConvertToLocal(vertex, m_params.m_tileCenter, kShapeCoordScalar)), m_params.m_depth), colorPoint); }); 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) case Message::UpdateUserMarkLayer: { ref_ptr 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(key), + make_unique_dp(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(layerId, move(shapes)), + MessagePriority::Normal); } msg->EndProcess(); break; diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 537133d0b5..8cdb09bcd4 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -25,7 +25,7 @@ void CircleShape::Draw(ref_ptr batcher, ref_ptr dp::TextureManager::ColorRegion region; textures->GetColorRegion(m_params.m_color, region); glsl::vec2 const colorPoint(glsl::ToVec2(region.GetTexRect().Center())); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); buffer_vector vertexes; vertexes.push_back(gpu::SolidTexturingVertex 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(rect, isAnim)); } -void DrapeEngine::ClearUserMarksLayer(df::TileKey const & tileKey) +void DrapeEngine::ClearUserMarksLayer(size_t layerId) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(tileKey), + make_unique_dp(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(tileKey, isVisible), + make_unique_dp(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(tileKey, provider), + make_unique_dp(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 contextFactory = nullptr); void SetRenderingDisabled(bool const destroyContext); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 55c0999e4e..94d0e14362 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -248,23 +248,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) dp::GLState const & state = msg->GetState(); TileKey const & key = msg->GetKey(); drape_ptr 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 program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - ref_ptr program3d = m_gpuProgramManager->GetProgram(state.GetProgram3dIndex()); - - m_userMarkRenderGroups.emplace_back(make_unique_dp(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) 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) break; } + case Message::FlushUserMarks: + { + ref_ptr 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(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(message)->GetKey(); - auto const functor = [&tileKey](drape_ptr const & g) + ref_ptr msg = message; + size_t const layerId = msg->GetLayerId(); + auto const functor = [&layerId](drape_ptr 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 m = message; - TileKey const & key = m->GetKey(); - if (m->IsVisible()) - m_userMarkVisibility.insert(key); + ref_ptr msg = message; + if (msg->IsVisible()) + m_userMarkVisibility.insert(msg->GetLayerId()); else - m_userMarkVisibility.erase(key); + m_userMarkVisibility.erase(msg->GetLayerId()); break; } @@ -1074,12 +1076,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) m_routeRenderer->RenderRoute(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - for (drape_ptr 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); @@ -1127,6 +1124,20 @@ void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) for (drape_ptr & 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) { diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 48418794a7..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 { @@ -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 m_layers; vector> m_userMarkRenderGroups; - set m_userMarkVisibility; + unordered_set m_userMarkVisibility; drape_ptr m_guiRenderer; drape_ptr m_myPositionController; diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index fcb47e6f70..6dfe0a692b 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -235,7 +235,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (m_points.size() == 1) { dp::Color const color = GetColorBySpeed(m_points.front().m_speedMPS); - m2::PointD const pt = MapShape::ConvertPt(m_points.front().m_point, m_pivot, kShapeCoordScalar); + 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++; } @@ -253,7 +253,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (screen.ClipRect().IsIntersect(pointRect)) { dp::Color const color = CalculatePointColor(static_cast(it.GetIndex()), pt, it.GetLength(), it.GetFullLength()); - m2::PointD const convertedPt = MapShape::ConvertPt(pt, m_pivot, kShapeCoordScalar); + 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()) @@ -272,7 +272,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, #ifdef SHOW_RAW_POINTS for (size_t i = 0; i < m_points.size(); i++) { - m2::PointD const convertedPt = MapShape::ConvertPt(m_points[i].m_point, m_pivot, kShapeCoordScalar); + 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()) diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index 20d95615a5..8130117f56 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -336,8 +336,8 @@ void LineShape::Construct(DashedLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); + 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); @@ -379,7 +379,7 @@ void LineShape::Construct(SolidLineBuilder & builder) const generateJoins = false; // build geometry - glsl::vec2 firstPoint = glsl::ToVec2(ConvertPt(path.front(), m_params.m_tileCenter, kShapeCoordScalar)); + 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) @@ -387,8 +387,8 @@ void LineShape::Construct(SolidLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); + 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 8582670328..52579140b8 100644 --- a/drape_frontend/map_shape.hpp +++ b/drape_frontend/map_shape.hpp @@ -35,7 +35,7 @@ public: void SetFeatureMinZoom(int minZoom) { m_minZoom = minZoom; } int GetFeatureMinZoom() const { return m_minZoom; } - static m2::PointD ConvertPt(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) + static m2::PointD ConvertToLocal(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) { return (basePt - tileCenter) * scalar; } 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 98afdd7f2f..99f6b89ef6 100644 --- a/drape_frontend/my_position.cpp +++ b/drape_frontend/my_position.cpp @@ -110,7 +110,7 @@ void MyPosition::RenderAccuracy(ScreenBase const & screen, int zoomLevel, math::Matrix mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + 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); @@ -134,7 +134,7 @@ void MyPosition::RenderMyPosition(ScreenBase const & screen, int zoomLevel, math::Matrix mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + 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); diff --git a/drape_frontend/path_symbol_shape.cpp b/drape_frontend/path_symbol_shape.cpp index 8715588fce..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 batcher, ref_ptr batcher, ref_ptrGetSymbolRegion(m_params.m_symbolName, region); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + 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(); diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 7cc96170f0..ac5e7b63b2 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -192,12 +192,12 @@ bool RenderGroupComparator::operator()(drape_ptr 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 && 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); @@ -222,8 +222,11 @@ void UserMarkRenderGroup::Render(ScreenBase const & screen) { BaseRenderGroup::Render(screen); - math::Matrix mv = screen.GetModelView(); - m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + // Set tile-based model-view matrix. + { + math::Matrix mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } ref_ptr shader = screen.isPerspective() ? m_shader3d : m_shader; dp::ApplyUniforms(m_uniforms, shader); @@ -234,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 shader, ref_ptr shader3d, ref_ptr 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 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 && bucket); - ~UserMarkRenderGroup(); + ~UserMarkRenderGroup() override; void UpdateAnimation() override; void Render(ScreenBase const & screen) override; + size_t GetLayerId() const; + private: drape_ptr m_renderBucket; unique_ptr m_animation; ValueMapping m_mapping; + size_t m_layerId; }; } // namespace df diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 9954e098e7..5a839d5a17 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -142,10 +142,10 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), - pivot, kShapeCoordScalar); - m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), - pivot, kShapeCoordScalar); + 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); @@ -248,10 +248,10 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::Point (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), - pivot, kShapeCoordScalar); - m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), - pivot, kShapeCoordScalar); + 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); diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp index 224ab48197..caafa84566 100644 --- a/drape_frontend/selection_shape.cpp +++ b/drape_frontend/selection_shape.cpp @@ -140,7 +140,7 @@ void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + 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()); diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp index 545dfa3878..dd758b09df 100644 --- a/drape_frontend/text_layout.cpp +++ b/drape_frontend/text_layout.cpp @@ -482,7 +482,7 @@ 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::ConvertPt(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f); + 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]; diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index b1bcee28c6..1147282e66 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -197,7 +197,7 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + 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); @@ -245,7 +245,7 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + 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); 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" @@ -11,40 +14,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 { @@ -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 batcher, - ref_ptr textures) +void CacheUserPoints(UserMarksProvider const * provider, ref_ptr 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 buffer; - buffer.reserve(vertexCount); - - vector marks; - marks.reserve(markCount); + int const kZoomLevel = 10; + map> 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; - }); - - dp::TextureManager::SymbolRegion region; - for (size_t i = 0; i < marks.size(); ++i) - { - 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); + UserPointMark const * userMark = provider->GetUserPointMark(i); + TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel); + marks[tileKey].push_back(userMark); } - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); + for (auto it = marks.begin(); it != marks.end(); ++it) + { + TileKey const & key = it->first; + m2::PointD const tileCenter = key.GetGlobalRect().Center(); - dp::AttributeProvider attribProvider(1, buffer.size()); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2) + { + return v1->GetPivot().y < v2->GetPivot().y; + }); - batcher->InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + dp::TextureManager::SymbolRegion region; + + uint32_t const vertexCount = static_cast(it->second.size()) * dp::Batcher::VertexPerQuad; + uint32_t const indicesCount = static_cast(it->second.size()) * dp::Batcher::IndexPerQuad; + buffer_vector buffer; + buffer.reserve(vertexCount); + + 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 && 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 batcher, - ref_ptr textures) +void CacheUserLines(UserMarksProvider const * provider, ref_ptr textures, + TUserMarkShapes & outShapes) { + int const kZoomLevel = 10; + map>> 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 points; + m2::RectD rect; points.reserve(pointCount); for (size_t i = 0; i < pointCount; ++i) - points.push_back(line->GetPoint(i)); - - m2::SharedSpline spline(points); - - for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) { - 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; + points.push_back(line->GetPoint(i)); + rect.Add(points.back()); + } - LineShape(spline, params).Draw(batcher, textures); + TileKey const tileKey = GetTileKeyByPoint(rect.Center(), kZoomLevel); + userLines[tileKey].push_back(make_pair(line, m2::SharedSpline(points))); + } + + 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 && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + for (auto const & lineData : it->second) + { + 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 batcher, - ref_ptr textures) +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr 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 batcher, - ref_ptr textures); +struct UserMarkShape +{ + dp::GLState m_state; + drape_ptr m_bucket; + TileKey m_tileKey; + + UserMarkShape(dp::GLState const & state, drape_ptr && bucket, + TileKey const & tileKey) + : m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey) + {} +}; + +using TUserMarkShapes = vector; + +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, + ref_ptr textures); + } // namespace df diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index be334dbdf3..a052b87c4d 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -512,10 +512,13 @@ bool ScreenBase::IsReverseProjection3d(m2::PointD const & pt) const ScreenBase::Matrix3dT ScreenBase::GetModelView() const { - return ScreenBase::Matrix3dT { m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), - m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), - 0, 0, 1, 0, - 0, 0, 0, 1 }; + return ScreenBase::Matrix3dT + { + m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), + m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), + 0, 0, 1, 0, + 0, 0, 0, 1 + }; } ScreenBase::Matrix3dT ScreenBase::GetModelView(m2::PointD const & pivot, double scalar) const diff --git a/map/bookmark.hpp b/map/bookmark.hpp index 6d5f8362c5..60c9242eae 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -136,7 +136,7 @@ public: }; BookmarkCategory(string const & name, Framework & framework); - ~BookmarkCategory(); + ~BookmarkCategory() override; size_t GetUserLineCount() const override; df::UserLineMark const * GetUserLineMark(size_t index) const override; diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index dd013cd7e3..fa50285751 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -148,7 +148,7 @@ size_t BookmarkManager::LastEditedBMCategory() } if (m_categories.empty()) - m_categories.push_back(new BookmarkCategory(m_framework.GetStringsBundle().GetString("my_places"), m_framework)); + CreateBmCategory(m_framework.GetStringsBundle().GetString("my_places")); return 0; } diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index 198aeb6e57..401a435994 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -13,59 +13,48 @@ namespace { - class FindMarkFunctor + +class FindMarkFunctor +{ +public: + FindMarkFunctor(UserMark ** mark, double & minD, m2::AnyRectD const & rect) + : m_mark(mark) + , m_minD(minD) + , m_rect(rect) { - public: - FindMarkFunctor(UserMark ** mark, double & minD, m2::AnyRectD const & rect) - : m_mark(mark) - , m_minD(minD) - , m_rect(rect) - { - m_globalCenter = rect.GlobalCenter(); - } - - void operator()(UserMark * mark) - { - m2::PointD const & org = mark->GetPivot(); - if (m_rect.IsPointInside(org)) - { - double minDCandidate = m_globalCenter.SquareLength(org); - if (minDCandidate < m_minD) - { - *m_mark = mark; - m_minD = minDCandidate; - } - } - } - - UserMark ** m_mark; - double & m_minD; - m2::AnyRectD const & m_rect; - m2::PointD m_globalCenter; - }; - - df::TileKey CreateTileKey(UserMarkContainer const * cont) - { - switch (cont->GetType()) - { - case UserMarkType::API_MARK: - return df::GetApiTileKey(); - case UserMarkType::SEARCH_MARK: - return df::GetSearchTileKey(); - case UserMarkType::BOOKMARK_MARK: - return df::GetBookmarkTileKey(reinterpret_cast(cont)); - case UserMarkType::DEBUG_MARK: - return df::GetDebugTileKey(); - } - - ASSERT(false, ()); - return df::TileKey(); + m_globalCenter = rect.GlobalCenter(); } - size_t const VisibleFlag = 0; - size_t const DrawableFlag = 1; + void operator()(UserMark * mark) + { + m2::PointD const & org = mark->GetPivot(); + if (m_rect.IsPointInside(org)) + { + double minDCandidate = m_globalCenter.SquareLength(org); + if (minDCandidate < m_minD) + { + *m_mark = mark; + m_minD = minDCandidate; + } + } + } + + UserMark ** m_mark; + double & m_minD; + m2::AnyRectD const & m_rect; + m2::PointD m_globalCenter; +}; + +size_t const VisibleFlag = 0; +size_t const DrawableFlag = 1; + +size_t GenerateLayerId(UserMarkContainer const * cont) +{ + return reinterpret_cast(cont); } +} // namespace + UserMarkContainer::UserMarkContainer(double layerDepth, UserMarkType type, Framework & fm) : m_framework(fm) , m_layerDepth(layerDepth) @@ -97,9 +86,11 @@ UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, do namespace { + unique_ptr g_selectionUserMark; unique_ptr g_myPosition; -} + +} // namespace void UserMarkContainer::InitStaticMarks(UserMarkContainer * container) { @@ -135,15 +126,15 @@ void UserMarkContainer::ReleaseController() if (engine == nullptr) return; - df::TileKey key = CreateTileKey(this); - engine->ChangeVisibilityUserMarksLayer(key, IsVisible() && IsDrawable()); + size_t const layerId = GenerateLayerId(this); + engine->ChangeVisibilityUserMarksLayer(layerId, IsVisible() && IsDrawable()); if (IsDirty()) { if (GetUserPointCount() == 0 && GetUserLineCount() == 0) - engine->ClearUserMarksLayer(key); + engine->ClearUserMarksLayer(layerId); else - engine->UpdateUserMarksLayer(key, this); + engine->UpdateUserMarksLayer(layerId, this); } }