diff --git a/drape/batcher.cpp b/drape/batcher.cpp index 6614b7fcf4..b7c86782f0 100644 --- a/drape/batcher.cpp +++ b/drape/batcher.cpp @@ -37,6 +37,11 @@ public: void FlushData(BindingInfo const & info, void const * data, uint16_t count) { + if (!m_overlay.IsNull() && info.IsDynamic()) + { + uint16_t offset = m_buffer->GetDynamicBufferOffset(info); + m_overlay->AddDynamicAttribute(info, offset, count); + } m_buffer->UploadData(info, data, count); } diff --git a/drape/overlay_handle.cpp b/drape/overlay_handle.cpp index 244e832709..cff854efd3 100644 --- a/drape/overlay_handle.cpp +++ b/drape/overlay_handle.cpp @@ -1,14 +1,26 @@ #include "overlay_handle.hpp" +#include "../base/macros.hpp" + +struct OverlayHandle::OffsetNodeFinder +{ +public: + OffsetNodeFinder(uint8_t bufferID) : m_bufferID(bufferID) {} + + bool operator()(OverlayHandle::offset_node_t const & node) + { + return node.first.GetID() == m_bufferID; + } + +private: + uint8_t m_bufferID; +}; + OverlayHandle::OverlayHandle(FeatureID const & id, OverlayHandle::Anchor anchor, - m2::PointD const & gbPivot, - m2::PointD const & pxSize, double priority) : m_id(id) , m_anchor(anchor) - , m_gbPivot(gbPivot) - , m_pxHalfSize(pxSize.x / 2.0, pxSize.y / 2.0) , m_priority(priority) , m_isVisible(false) { @@ -24,26 +36,6 @@ void OverlayHandle::SetIsVisible(bool isVisible) m_isVisible = isVisible; } -m2::RectD OverlayHandle::GetPixelRect(ScreenBase const & screen) const -{ - m2::PointD pxPivot = screen.GtoP(m_gbPivot); - m2::RectD result(pxPivot - m_pxHalfSize, pxPivot + m_pxHalfSize); - m2::PointD offset(0.0, 0.0); - - if (m_anchor & Left) - offset.x = m_pxHalfSize.x; - else if (m_anchor & Right) - offset.x = -m_pxHalfSize.x; - - if (m_anchor & Top) - offset.y = m_pxHalfSize.y; - else if (m_anchor & Bottom) - offset.y = -m_pxHalfSize.y; - - result.Offset(offset); - return result; -} - uint16_t * OverlayHandle::IndexStorage(uint16_t size) { m_indexes.resize(size); @@ -61,6 +53,23 @@ void OverlayHandle::GetElementIndexes(RefPointer mutator) co mutator->AppendIndexes(&m_indexes[0], m_indexes.size()); } +void OverlayHandle::GetAttributeMutation(RefPointer mutator) const +{ + UNUSED_VALUE(mutator); +} + +bool OverlayHandle::HasDynamicAttributes() const +{ + return !m_offsets.empty(); +} + +void OverlayHandle::AddDynamicAttribute(BindingInfo const & binding, uint16_t offset, uint16_t count) +{ + ASSERT(binding.IsDynamic(), ()); + ASSERT(find_if(m_offsets.begin(), m_offsets.end(), OffsetNodeFinder(binding.GetID())) == m_offsets.end(), ()); + m_offsets.insert(make_pair(binding, MutateRegion(offset, count))); +} + FeatureID const & OverlayHandle::GetFeatureID() const { return m_id; @@ -70,3 +79,41 @@ double const & OverlayHandle::GetPriority() const { return m_priority; } + +OverlayHandle::offset_node_t const & OverlayHandle::GetOffsetNode(uint8_t bufferID) const +{ + set::const_iterator it = find_if(m_offsets.begin(), m_offsets.end(), OffsetNodeFinder(bufferID)); + ASSERT(it != m_offsets.end(), ()); + return *it; +} + +//////////////////////////////////////////////////////////////////////////////// + +SquareHandle::SquareHandle(FeatureID const & id, OverlayHandle::Anchor anchor, + m2::PointD const & gbPivot, m2::PointD const & pxSize, + double priority) + : base_t(id, anchor, priority) + , m_gbPivot(gbPivot) + , m_pxHalfSize(pxSize.x / 2.0, pxSize.y / 2.0) +{ +} + +m2::RectD SquareHandle::GetPixelRect(ScreenBase const & screen) const +{ + m2::PointD pxPivot = screen.GtoP(m_gbPivot); + m2::RectD result(pxPivot - m_pxHalfSize, pxPivot + m_pxHalfSize); + m2::PointD offset(0.0, 0.0); + + if (m_anchor & Left) + offset.x = m_pxHalfSize.x; + else if (m_anchor & Right) + offset.x = -m_pxHalfSize.x; + + if (m_anchor & Top) + offset.y = m_pxHalfSize.y; + else if (m_anchor & Bottom) + offset.y = -m_pxHalfSize.y; + + result.Offset(offset); + return result; +} diff --git a/drape/overlay_handle.hpp b/drape/overlay_handle.hpp index f0f70eb68b..dbdefa5859 100644 --- a/drape/overlay_handle.hpp +++ b/drape/overlay_handle.hpp @@ -1,12 +1,15 @@ #pragma once +#include "binding_info.hpp" +#include "index_buffer_mutator.hpp" +#include "attribute_buffer_mutator.hpp" + #include "../indexer/feature_decl.hpp" #include "../geometry/screenbase.hpp" #include "../geometry/point2d.hpp" #include "../geometry/rect2d.hpp" -#include "index_buffer_mutator.hpp" class OverlayHandle { @@ -26,28 +29,64 @@ public: OverlayHandle(FeatureID const & id, Anchor anchor, - m2::PointD const & gbPivot, - m2::PointD const & pxSize, double priority); + virtual ~OverlayHandle() {} + bool IsVisible() const; void SetIsVisible(bool isVisible); - m2::RectD GetPixelRect(ScreenBase const & screen) const; + virtual void Update(ScreenBase const & /*screen*/) {} + virtual m2::RectD GetPixelRect(ScreenBase const & screen) const = 0; uint16_t * IndexStorage(uint16_t size); size_t GetIndexCount() const; void GetElementIndexes(RefPointer mutator) const; + virtual void GetAttributeMutation(RefPointer mutator) const; + + bool HasDynamicAttributes() const; + void AddDynamicAttribute(BindingInfo const & binding, uint16_t offset, uint16_t count); FeatureID const & GetFeatureID() const; double const & GetPriority() const; +protected: + FeatureID const m_id; + Anchor const m_anchor; + double const m_priority; + + typedef pair offset_node_t; + offset_node_t const & GetOffsetNode(uint8_t bufferID) const; + private: - FeatureID m_id; - Anchor m_anchor; - m2::PointD m_gbPivot; - m2::PointD m_pxHalfSize; - double m_priority; bool m_isVisible; vector m_indexes; + struct LessOffsetNode + { + bool operator()(offset_node_t const & node1, offset_node_t const & node2) const + { + return node1.first.GetID() < node2.first.GetID(); + } + }; + + struct OffsetNodeFinder; + + set m_offsets; +}; + +class SquareHandle : public OverlayHandle +{ + typedef OverlayHandle base_t; +public: + SquareHandle(FeatureID const & id, + Anchor anchor, + m2::PointD const & gbPivot, + m2::PointD const & pxSize, + double priority); + + m2::RectD GetPixelRect(ScreenBase const & screen) const; + +private: + m2::PointD m_gbPivot; + m2::PointD m_pxHalfSize; }; diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 84a71b63ca..0b62322c2c 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -74,10 +74,10 @@ void CircleShape::Draw(RefPointer batcher, RefPointer normalDecl.m_offset = 3 * sizeof(float); normalDecl.m_stride = 5 * sizeof(float); - OverlayHandle * overlay = new OverlayHandle(m_params.m_id, - OverlayHandle::Center, m_pt, - m2::PointD(m_params.m_radius, m_params.m_radius), - m_params.m_depth); + OverlayHandle * overlay = new SquareHandle(m_params.m_id, + OverlayHandle::Center, m_pt, + m2::PointD(m_params.m_radius, m_params.m_radius), + m_params.m_depth); provider.InitStream(0, info, MakeStackRefPointer(&stream[0])); batcher->InsertTriangleFan(state, MakeStackRefPointer(&provider), MovePointer(overlay)); diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index ede5a36840..1ec14e5d09 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -64,11 +64,11 @@ void PoiSymbolShape::Draw(RefPointer batcher, RefPointer(stream)); batcher->InsertTriangleStrip(state, MakeStackRefPointer(&provider), MovePointer(handle));