From 75d9e73f981dcf41a6b28131670a8f4d3f41a978 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Mon, 25 May 2015 10:03:32 +0300 Subject: [PATCH] Added separated clipping of transparent and solid objects by overlay tree --- drape/overlay_tree.cpp | 18 +++++++++--------- drape/overlay_tree.hpp | 27 ++++++++++++++++++++++----- drape/render_bucket.cpp | 4 ++-- drape/render_bucket.hpp | 2 +- drape_frontend/render_group.cpp | 2 +- drape_head/testing_engine.cpp | 2 +- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp index 7fd5c2b9dc..43f964735e 100644 --- a/drape/overlay_tree.cpp +++ b/drape/overlay_tree.cpp @@ -12,7 +12,7 @@ void OverlayTree::StartOverlayPlacing(ScreenBase const & screen, bool canOverlap ASSERT(IsEmpty(), ()); } -void OverlayTree::Add(ref_ptr handle) +void OverlayTree::Add(ref_ptr handle, bool isTransparent) { ScreenBase const & modelView = GetModelView(); @@ -29,16 +29,16 @@ void OverlayTree::Add(ref_ptr handle) return; } - typedef buffer_vector, 8> OverlayContainerT; + typedef buffer_vector OverlayContainerT; OverlayContainerT elements; /* * Find elements that already on OverlayTree and it's pixel rect * intersect with handle pixel rect ("Intersected elements") */ - ForEachInRect(pixelRect, [&] (ref_ptr r) + ForEachInRect(pixelRect, [&] (detail::OverlayInfo const & info) { - if (handle->IsIntersect(modelView, r)) - elements.push_back(r); + if (handle->IsIntersect(modelView, info.m_handle) && isTransparent == info.m_isTransparent) + elements.push_back(info); }); double const inputPriority = handle->GetPriority(); @@ -49,20 +49,20 @@ void OverlayTree::Add(ref_ptr handle) * But if some of already inserted elements more priority than we don't insert "handle" */ for (OverlayContainerT::const_iterator it = elements.begin(); it != elements.end(); ++it) - if (inputPriority < (*it)->GetPriority()) + if (inputPriority < (*it).m_handle->GetPriority()) return; for (OverlayContainerT::const_iterator it = elements.begin(); it != elements.end(); ++it) Erase(*it); - BaseT::Add(handle, pixelRect); + BaseT::Add(detail::OverlayInfo(handle, isTransparent), pixelRect); } void OverlayTree::EndOverlayPlacing() { - ForEach([] (ref_ptr handle) + ForEach([] (detail::OverlayInfo const & info) { - handle->SetIsVisible(true); + info.m_handle->SetIsVisible(true); }); Clear(); diff --git a/drape/overlay_tree.hpp b/drape/overlay_tree.hpp index b389c69eb6..6c0282e3e6 100644 --- a/drape/overlay_tree.hpp +++ b/drape/overlay_tree.hpp @@ -12,25 +12,42 @@ namespace dp namespace detail { +struct OverlayInfo +{ + ref_ptr m_handle; + bool m_isTransparent = false; + + OverlayInfo() = default; + OverlayInfo(ref_ptr handle, bool isTransparent) + : m_handle(handle) + , m_isTransparent(isTransparent) + {} + + bool operator==(OverlayInfo const & rhs) const + { + return m_handle == rhs.m_handle && m_isTransparent == rhs.m_isTransparent; + } +}; + struct OverlayTraits { ScreenBase m_modelView; - inline m2::RectD const LimitRect(ref_ptr handle) + inline m2::RectD const LimitRect(OverlayInfo const & info) { - return handle->GetPixelRect(m_modelView); + return info.m_handle->GetPixelRect(m_modelView); } }; } -class OverlayTree : public m4::Tree, detail::OverlayTraits> +class OverlayTree : public m4::Tree { - typedef m4::Tree, detail::OverlayTraits> BaseT; + typedef m4::Tree BaseT; public: void StartOverlayPlacing(ScreenBase const & screen, bool canOverlap = false); - void Add(ref_ptr handle); + void Add(ref_ptr handle, bool isTransparent); void EndOverlayPlacing(); private: diff --git a/drape/render_bucket.cpp b/drape/render_bucket.cpp index 1c1babad64..836c98f07e 100644 --- a/drape/render_bucket.cpp +++ b/drape/render_bucket.cpp @@ -61,10 +61,10 @@ void RenderBucket::Update(ScreenBase const & modelView) overlayHandle->Update(modelView); } -void RenderBucket::CollectOverlayHandles(ref_ptr tree) +void RenderBucket::CollectOverlayHandles(ref_ptr tree, bool isTransparent) { for (drape_ptr const & overlayHandle : m_overlay) - tree->Add(make_ref(overlayHandle)); + tree->Add(make_ref(overlayHandle), isTransparent); } void RenderBucket::Render(ScreenBase const & screen) diff --git a/drape/render_bucket.hpp b/drape/render_bucket.hpp index 5eddca0029..d41ae7b283 100644 --- a/drape/render_bucket.hpp +++ b/drape/render_bucket.hpp @@ -26,7 +26,7 @@ public: void AddOverlayHandle(drape_ptr && handle); void Update(ScreenBase const & modelView); - void CollectOverlayHandles(ref_ptr tree); + void CollectOverlayHandles(ref_ptr tree, bool isTransparent); void Render(ScreenBase const & screen); /// Only for testing! Don't use this function in production code! diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 8998f9793c..62c94947ad 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -60,7 +60,7 @@ void RenderGroup::Update(ScreenBase const & modelView) void RenderGroup::CollectOverlay(ref_ptr tree) { for(drape_ptr & renderBucket : m_renderBuckets) - renderBucket->CollectOverlayHandles(tree); + renderBucket->CollectOverlayHandles(tree, GetOpacity() != 1.0); } void RenderGroup::Render(ScreenBase const & screen) diff --git a/drape_head/testing_engine.cpp b/drape_head/testing_engine.cpp index b10a0ea2dc..89f182825f 100644 --- a/drape_head/testing_engine.cpp +++ b/drape_head/testing_engine.cpp @@ -416,7 +416,7 @@ void TestingEngine::Draw() dp::OverlayTree tree; tree.StartOverlayPlacing(m_modelView, true); for (size_t i = 0; i < buckets.size(); ++i) - buckets[i]->CollectOverlayHandles(make_ref(&tree)); + buckets[i]->CollectOverlayHandles(make_ref(&tree), false); for (size_t i = 0; i < buckets.size(); ++i) buckets[i]->Render(m_modelView); tree.EndOverlayPlacing();