diff options
Diffstat (limited to 'drape_frontend')
25 files changed, 775 insertions, 407 deletions
diff --git a/drape_frontend/CMakeLists.txt b/drape_frontend/CMakeLists.txt index 7b3f68f7bc..4e34f3aad6 100644 --- a/drape_frontend/CMakeLists.txt +++ b/drape_frontend/CMakeLists.txt @@ -66,6 +66,8 @@ set( batch_merge_helper.cpp batch_merge_helper.hpp batchers_pool.hpp + circles_pack_shape.cpp + circles_pack_shape.hpp color_constants.cpp color_constants.hpp colored_symbol_shape.cpp @@ -89,8 +91,6 @@ set( gps_track_point.hpp gps_track_renderer.cpp gps_track_renderer.hpp - gps_track_shape.cpp - gps_track_shape.hpp gui/choose_position_mark.cpp gui/choose_position_mark.hpp gui/compass.cpp @@ -250,6 +250,8 @@ set( shaders/arrow3d_shadow.vsh.glsl shaders/circle.fsh.glsl shaders/circle.vsh.glsl + shaders/circle_point.fsh.glsl + shaders/circle_point.vsh.glsl shaders/colored_symbol.fsh.glsl shaders/colored_symbol.vsh.glsl shaders/colored_symbol_billboard.vsh.glsl @@ -295,8 +297,6 @@ set( shaders/texturing3d.fsh.glsl shaders/texturing_billboard.vsh.glsl shaders/texturing_gui.vsh.glsl - shaders/trackpoint.fsh.glsl - shaders/trackpoint.vsh.glsl shaders/traffic.fsh.glsl shaders/traffic.vsh.glsl shaders/traffic_line.fsh.glsl diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 3060676315..ee8af08d56 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -434,7 +434,6 @@ void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule) m_symbolRule = symRule; } - bool const hasPOI = m_symbolRule != nullptr; bool const isNode = (pRule->GetType() & drule::node) != 0; CaptionDefProto const * capRule = pRule->GetCaption(0); if (capRule && isNode) diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 5f4bc53bb2..ad0065c1a8 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -2,9 +2,9 @@ #include "drape_frontend/backend_renderer.hpp" #include "drape_frontend/batchers_pool.hpp" +#include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/drape_api_builder.hpp" #include "drape_frontend/drape_measurer.hpp" -#include "drape_frontend/gps_track_shape.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/message_subclasses.hpp" #include "drape_frontend/read_manager.hpp" @@ -12,10 +12,10 @@ #include "drape_frontend/user_mark_shapes.hpp" #include "drape_frontend/visual_params.hpp" -#include "indexer/scales.hpp" - #include "drape/texture_manager.hpp" +#include "indexer/scales.hpp" + #include "platform/platform.hpp" #include "base/logging.hpp" @@ -303,14 +303,15 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message) break; } - case Message::CacheGpsTrackPoints: + case Message::CacheCirclesPack: { - ref_ptr<CacheGpsTrackPointsMessage> msg = message; - drape_ptr<GpsTrackRenderData> data = make_unique_dp<GpsTrackRenderData>(); + ref_ptr<CacheCirclesPackMessage> msg = message; + drape_ptr<CirclesPackRenderData> data = make_unique_dp<CirclesPackRenderData>(); data->m_pointsCount = msg->GetPointsCount(); - GpsTrackShape::Draw(m_texMng, *data.get()); + CirclesPackShape::Draw(m_texMng, *data.get()); m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<FlushGpsTrackPointsMessage>(move(data)), + make_unique_dp<FlushCirclesPackMessage>( + std::move(data), msg->GetDestination()), MessagePriority::Normal); break; } diff --git a/drape_frontend/circles_pack_shape.cpp b/drape_frontend/circles_pack_shape.cpp new file mode 100644 index 0000000000..5f4366d030 --- /dev/null +++ b/drape_frontend/circles_pack_shape.cpp @@ -0,0 +1,175 @@ +#include "drape_frontend/circles_pack_shape.hpp" +#include "drape_frontend/shader_def.hpp" + +#include "drape/attribute_provider.hpp" +#include "drape/batcher.hpp" +#include "drape/glsl_func.hpp" +#include "drape/glsl_types.hpp" +#include "drape/texture_manager.hpp" + +namespace df +{ +namespace +{ +uint32_t const kDynamicStreamID = 0x7F; + +struct CirclesPackStaticVertex +{ + using TNormal = glsl::vec3; + + CirclesPackStaticVertex() = default; + CirclesPackStaticVertex(TNormal const & normal) : m_normal(normal) {} + + TNormal m_normal; +}; + +dp::GLState GetCirclesPackState(ref_ptr<dp::TextureManager> texMng) +{ + dp::GLState state(gpu::CIRCLE_POINT_PROGRAM, dp::GLState::OverlayLayer); + state.SetColorTexture(texMng->GetSymbolsTexture()); + return state; +} + +dp::BindingInfo const & GetCirclesPackStaticBindingInfo() +{ + static unique_ptr<dp::BindingInfo> s_info; + if (s_info == nullptr) + { + dp::BindingFiller<CirclesPackStaticVertex> filler(1); + filler.FillDecl<CirclesPackStaticVertex::TNormal>("a_normal"); + s_info.reset(new dp::BindingInfo(filler.m_info)); + } + return *s_info; +} + +dp::BindingInfo const & GetCirclesPackDynamicBindingInfo() +{ + static unique_ptr<dp::BindingInfo> s_info; + if (s_info == nullptr) + { + dp::BindingFiller<CirclesPackDynamicVertex> filler(2, kDynamicStreamID); + filler.FillDecl<CirclesPackDynamicVertex::TPosition>("a_position"); + filler.FillDecl<CirclesPackDynamicVertex::TColor>("a_color"); + s_info.reset(new dp::BindingInfo(filler.m_info)); + } + return *s_info; +} +} // namespace + +CirclesPackHandle::CirclesPackHandle(size_t pointsCount) + : OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false) + , m_needUpdate(false) +{ + m_buffer.resize(pointsCount * dp::Batcher::VertexPerQuad); +} + +void CirclesPackHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const +{ + if (!m_needUpdate) + return; + + TOffsetNode const & node = GetOffsetNode(kDynamicStreamID); + ASSERT(node.first.GetElementSize() == sizeof(CirclesPackDynamicVertex), ()); + ASSERT(node.second.m_count == m_buffer.size(), ()); + + uint32_t const byteCount = + static_cast<uint32_t>(m_buffer.size()) * sizeof(CirclesPackDynamicVertex); + void * buffer = mutator->AllocateMutationBuffer(byteCount); + memcpy(buffer, m_buffer.data(), byteCount); + + dp::MutateNode mutateNode; + mutateNode.m_region = node.second; + mutateNode.m_data = make_ref(buffer); + mutator->AddMutation(node.first, mutateNode); + + m_needUpdate = false; +} + +bool CirclesPackHandle::Update(ScreenBase const & screen) +{ + UNUSED_VALUE(screen); + return true; +} + +bool CirclesPackHandle::IndexesRequired() const { return false; } + +m2::RectD CirclesPackHandle::GetPixelRect(ScreenBase const & screen, bool perspective) const +{ + UNUSED_VALUE(screen); + UNUSED_VALUE(perspective); + return m2::RectD(); +} + +void CirclesPackHandle::GetPixelShape(ScreenBase const & screen, bool perspective, + Rects & rects) const +{ + UNUSED_VALUE(screen); + UNUSED_VALUE(perspective); +} + +void CirclesPackHandle::SetPoint(size_t index, m2::PointD const & position, float radius, + dp::Color const & color) +{ + size_t bufferIndex = index * dp::Batcher::VertexPerQuad; + ASSERT_GREATER_OR_EQUAL(bufferIndex, 0, ()); + ASSERT_LESS(bufferIndex, m_buffer.size(), ()); + + for (size_t i = 0; i < dp::Batcher::VertexPerQuad; i++) + { + m_buffer[bufferIndex + i].m_position = glsl::vec3(position.x, position.y, radius); + m_buffer[bufferIndex + i].m_color = glsl::ToVec4(color); + } + m_needUpdate = true; +} + +void CirclesPackHandle::Clear() +{ + memset(m_buffer.data(), 0, m_buffer.size() * sizeof(CirclesPackDynamicVertex)); + m_needUpdate = true; +} + +size_t CirclesPackHandle::GetPointsCount() const +{ + return m_buffer.size() / dp::Batcher::VertexPerQuad; +} + +void CirclesPackShape::Draw(ref_ptr<dp::TextureManager> texMng, CirclesPackRenderData & data) +{ + ASSERT_NOT_EQUAL(data.m_pointsCount, 0, ()); + + uint32_t const kVerticesInPoint = dp::Batcher::VertexPerQuad; + uint32_t const kIndicesInPoint = dp::Batcher::IndexPerQuad; + std::vector<CirclesPackStaticVertex> staticVertexData; + staticVertexData.reserve(data.m_pointsCount * kVerticesInPoint); + for (size_t i = 0; i < data.m_pointsCount; i++) + { + staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(-1.0f, 1.0f, 1.0f)); + staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(-1.0f, -1.0f, 1.0f)); + staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(1.0f, 1.0f, 1.0f)); + staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(1.0f, -1.0f, 1.0f)); + } + + std::vector<CirclesPackDynamicVertex> dynamicVertexData; + dynamicVertexData.resize(data.m_pointsCount * kVerticesInPoint); + + dp::Batcher batcher(data.m_pointsCount * kIndicesInPoint, data.m_pointsCount * kVerticesInPoint); + dp::SessionGuard guard(batcher, [&data](dp::GLState const & state, drape_ptr<dp::RenderBucket> && b) + { + data.m_bucket = std::move(b); + data.m_state = state; + }); + + drape_ptr<dp::OverlayHandle> handle = make_unique_dp<CirclesPackHandle>(data.m_pointsCount); + + dp::AttributeProvider provider(2 /* stream count */, + static_cast<uint32_t>(staticVertexData.size())); + provider.InitStream(0 /* stream index */, GetCirclesPackStaticBindingInfo(), + make_ref(staticVertexData.data())); + provider.InitStream(1 /* stream index */, GetCirclesPackDynamicBindingInfo(), + make_ref(dynamicVertexData.data())); + batcher.InsertListOfStrip(GetCirclesPackState(texMng), make_ref(&provider), std::move(handle), + kVerticesInPoint); + + GLFunctions::glFlush(); +} +} // namespace df diff --git a/drape_frontend/gps_track_shape.hpp b/drape_frontend/circles_pack_shape.hpp index 6a19bbadfb..bc820292f0 100644 --- a/drape_frontend/gps_track_shape.hpp +++ b/drape_frontend/circles_pack_shape.hpp @@ -4,51 +4,49 @@ #include "drape_frontend/shape_view_params.hpp" #include "drape/glstate.hpp" -#include "drape/render_bucket.hpp" -#include "drape/utils/vertex_decl.hpp" #include "drape/overlay_handle.hpp" #include "drape/pointers.hpp" +#include "drape/render_bucket.hpp" +#include "drape/utils/vertex_decl.hpp" -#include "std/vector.hpp" +#include <vector> namespace dp { - class TextureManager; -} +class TextureManager; +} // namespace dp namespace df { - -struct GpsTrackRenderData +struct CirclesPackRenderData { uint32_t m_pointsCount; dp::GLState m_state; drape_ptr<dp::RenderBucket> m_bucket; - GpsTrackRenderData() : m_pointsCount(0), m_state(0, dp::GLState::OverlayLayer) {} + CirclesPackRenderData() : m_pointsCount(0), m_state(0, dp::GLState::OverlayLayer) {} }; -struct GpsTrackDynamicVertex +struct CirclesPackDynamicVertex { using TPosition = glsl::vec3; using TColor = glsl::vec4; - GpsTrackDynamicVertex() = default; - GpsTrackDynamicVertex(TPosition const & pos, TColor const & color) - : m_position(pos) - , m_color(color) + CirclesPackDynamicVertex() = default; + CirclesPackDynamicVertex(TPosition const & pos, TColor const & color) + : m_position(pos), m_color(color) {} TPosition m_position; TColor m_color; }; -class GpsTrackHandle : public dp::OverlayHandle +class CirclesPackHandle : public dp::OverlayHandle { using TBase = dp::OverlayHandle; public: - GpsTrackHandle(size_t pointsCount); + CirclesPackHandle(size_t pointsCount); void GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const override; bool Update(ScreenBase const & screen) override; m2::RectD GetPixelRect(ScreenBase const & screen, bool perspective) const override; @@ -60,14 +58,13 @@ public: size_t GetPointsCount() const; private: - vector<GpsTrackDynamicVertex> m_buffer; + std::vector<CirclesPackDynamicVertex> m_buffer; mutable bool m_needUpdate; }; -class GpsTrackShape +class CirclesPackShape { public: - static void Draw(ref_ptr<dp::TextureManager> texMng, GpsTrackRenderData & data); + static void Draw(ref_ptr<dp::TextureManager> texMng, CirclesPackRenderData & data); }; - -} // namespace df +} // namespace df diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 14d2eb5b5b..3ad284934e 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -444,6 +444,36 @@ void DrapeEngine::DeactivateRouteFollowing() MessagePriority::Normal); } +void DrapeEngine::SetRouteSegmentVisibility(dp::DrapeID segmentId, bool isVisible) +{ + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<SetRouteSegmentVisibilityMessage>(segmentId, isVisible), + MessagePriority::Normal); +} + +dp::DrapeID DrapeEngine::AddRoutePreviewSegment(m2::PointD const & startPt, m2::PointD const & finishPt) +{ + dp::DrapeID const id = GenerateDrapeID(); + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<AddRoutePreviewSegmentMessage>(id, startPt, finishPt), + MessagePriority::Normal); + return id; +} + +void DrapeEngine::RemoveRoutePreviewSegment(dp::DrapeID segmentId) +{ + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<RemoveRoutePreviewSegmentMessage>(segmentId), + MessagePriority::Normal); +} + +void DrapeEngine::RemoveAllRoutePreviewSegments() +{ + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<RemoveRoutePreviewSegmentMessage>(), + MessagePriority::Normal); +} + void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info) { m_widgetsLayout = std::move(info); diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 10c0dd8cb6..b6c52bc969 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -161,9 +161,12 @@ public: dp::DrapeID AddRouteSegment(drape_ptr<RouteSegment> && segment); void RemoveRouteSegment(dp::DrapeID segmentId, bool deactivateFollowing); - void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, bool enableAutoZoom); void DeactivateRouteFollowing(); + void SetRouteSegmentVisibility(dp::DrapeID segmentId, bool isVisible); + dp::DrapeID AddRoutePreviewSegment(m2::PointD const & startPt, m2::PointD const & finishPt); + void RemoveRoutePreviewSegment(dp::DrapeID segmentId); + void RemoveAllRoutePreviewSegments(); void SetWidgetLayout(gui::TWidgetsLayoutInfo && info); diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 51077eb59f..da8970357d 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -47,6 +47,7 @@ SOURCES += \ backend_renderer.cpp \ base_renderer.cpp \ batch_merge_helper.cpp \ + circles_pack_shape.cpp \ color_constants.cpp \ colored_symbol_shape.cpp \ drape_api.cpp \ @@ -57,7 +58,6 @@ SOURCES += \ engine_context.cpp \ frontend_renderer.cpp \ gps_track_renderer.cpp \ - gps_track_shape.cpp \ line_shape.cpp \ line_shape_helper.cpp \ map_data_provider.cpp \ @@ -149,6 +149,7 @@ HEADERS += \ base_renderer.hpp \ batchers_pool.hpp \ batch_merge_helper.hpp \ + circles_pack_shape.hpp \ color_constants.hpp \ colored_symbol_shape.hpp \ custom_symbol.hpp \ @@ -162,7 +163,6 @@ HEADERS += \ frontend_renderer.hpp \ gps_track_point.hpp \ gps_track_renderer.hpp \ - gps_track_shape.hpp \ intrusive_vector.hpp \ line_shape.hpp \ line_shape_helper.hpp \ @@ -243,6 +243,8 @@ OTHER_FILES += \ shaders/arrow3d_shadow.vsh.glsl \ shaders/circle.fsh.glsl \ shaders/circle.vsh.glsl \ + shaders/circle_point.fsh.glsl \ + shaders/circle_point.vsh.glsl \ shaders/colored_symbol.fsh.glsl \ shaders/colored_symbol.vsh.glsl \ shaders/colored_symbol_billboard.vsh.glsl \ @@ -288,8 +290,6 @@ OTHER_FILES += \ shaders/texturing3d.fsh.glsl \ shaders/texturing_billboard.vsh.glsl \ shaders/texturing_gui.vsh.glsl \ - shaders/trackpoint.fsh.glsl \ - shaders/trackpoint.vsh.glsl \ shaders/traffic.fsh.glsl \ shaders/traffic.vsh.glsl \ shaders/traffic_line.fsh.glsl \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 8d93e0bbe7..c086380798 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -113,10 +113,7 @@ struct RemoveTilePredicate FrontendRenderer::FrontendRenderer(Params && params) : BaseRenderer(ThreadsCommutator::RenderThread, params) , m_gpuProgramManager(new dp::GpuProgramManager()) - , m_routeRenderer(new RouteRenderer()) , m_trafficRenderer(new TrafficRenderer()) - , m_gpsTrackRenderer( - new GpsTrackRenderer(std::bind(&FrontendRenderer::PrepareGpsTrackPoints, this, _1))) , m_drapeApiRenderer(new DrapeApiRenderer()) , m_overlayTree(new dp::OverlayTree()) , m_enablePerspectiveInNavigation(false) @@ -147,7 +144,23 @@ FrontendRenderer::FrontendRenderer(Params && params) ASSERT(m_tapEventInfoFn, ()); ASSERT(m_userPositionChangedFn, ()); - m_myPositionController.reset(new MyPositionController(std::move(params.m_myPositionParams))); + m_gpsTrackRenderer = make_unique_dp<GpsTrackRenderer>([this](size_t pointsCount) + { + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp<CacheCirclesPackMessage>( + pointsCount, CacheCirclesPackMessage::GpsTrack), + MessagePriority::Normal); + }); + + m_routeRenderer = make_unique_dp<RouteRenderer>([this](size_t pointsCount) + { + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp<CacheCirclesPackMessage>( + pointsCount, CacheCirclesPackMessage::RoutePreview), + MessagePriority::Normal); + }); + + m_myPositionController = make_unique_dp<MyPositionController>(std::move(params.m_myPositionParams)); for (auto const & effect : params.m_enabledEffects) m_postprocessRenderer->SetEffectEnabled(effect, true /* enabled */); @@ -542,6 +555,33 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) break; } + case Message::AddRoutePreviewSegment: + { + ref_ptr<AddRoutePreviewSegmentMessage> const msg = message; + RouteRenderer::PreviewInfo info; + info.m_startPoint = msg->GetStartPoint(); + info.m_finishPoint = msg->GetFinishPoint(); + m_routeRenderer->AddPreviewSegment(msg->GetSegmentId(), std::move(info)); + break; + } + + case Message::RemoveRoutePreviewSegment: + { + ref_ptr<RemoveRoutePreviewSegmentMessage> const msg = message; + if (msg->NeedRemoveAll()) + m_routeRenderer->RemoveAllPreviewSegments(); + else + m_routeRenderer->RemovePreviewSegment(msg->GetSegmentId()); + break; + } + + case Message::SetRouteSegmentVisibility: + { + ref_ptr<SetRouteSegmentVisibilityMessage> const msg = message; + m_routeRenderer->SetRouteSegmentVisibility(msg->GetSegmentId(), msg->IsVisible()); + break; + } + case Message::RecoverGLResources: { UpdateGLResources(); @@ -624,10 +664,18 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) break; } - case Message::FlushGpsTrackPoints: + case Message::FlushCirclesPack: { - ref_ptr<FlushGpsTrackPointsMessage> msg = message; - m_gpsTrackRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptRenderData()); + ref_ptr<FlushCirclesPackMessage> msg = message; + switch (msg->GetDestination()) + { + case CacheCirclesPackMessage::GpsTrack: + m_gpsTrackRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptRenderData()); + break; + case CacheCirclesPackMessage::RoutePreview: + m_routeRenderer->AddPreviewRenderData(msg->AcceptRenderData(), make_ref(m_gpuProgramManager)); + break; + } break; } @@ -1014,13 +1062,6 @@ FeatureID FrontendRenderer::GetVisiblePOI(m2::RectD const & pixelRect) return featureID; } -void FrontendRenderer::PrepareGpsTrackPoints(uint32_t pointsCount) -{ - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp<CacheGpsTrackPointsMessage>(pointsCount), - MessagePriority::Normal); -} - void FrontendRenderer::PullToBoundArea(bool randomPlace, bool applyZoom) { if (m_dragBoundArea.empty()) @@ -1766,14 +1807,16 @@ void FrontendRenderer::Routine::Do() if (viewportChanged) m_renderer.OnResize(modelView); - if (modelViewChanged || viewportChanged) - m_renderer.PrepareScene(modelView); - // Check for a frame is active. - bool isActiveFrame = modelViewChanged || viewportChanged || - m_renderer.m_myPositionController->IsWaitingForTimers(); + bool isActiveFrame = modelViewChanged || viewportChanged; + if (isActiveFrame) + m_renderer.PrepareScene(modelView); + + isActiveFrame |= m_renderer.m_myPositionController->IsWaitingForTimers(); isActiveFrame |= m_renderer.m_texMng->UpdateDynamicTextures(); + isActiveFrame |= m_renderer.m_routeRenderer->UpdatePreview(modelView); + m_renderer.RenderScene(modelView); if (modelViewChanged || m_renderer.m_forceUpdateScene) diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 0ab7728a5f..7412b1edbd 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -220,8 +220,6 @@ private: FeatureID GetVisiblePOI(m2::PointD const & pixelPoint); FeatureID GetVisiblePOI(m2::RectD const & pixelRect); - void PrepareGpsTrackPoints(uint32_t pointsCount); - void PullToBoundArea(bool randomPlace, bool applyZoom); void ProcessSelection(ref_ptr<SelectObjectMessage> msg); diff --git a/drape_frontend/gps_track_point.hpp b/drape_frontend/gps_track_point.hpp index 4de53e85e5..a3387b327b 100644 --- a/drape_frontend/gps_track_point.hpp +++ b/drape_frontend/gps_track_point.hpp @@ -4,7 +4,6 @@ namespace df { - struct GpsTrackPoint { // Timestamp of the point, seconds from 1st Jan 1970 @@ -19,5 +18,4 @@ struct GpsTrackPoint // Unique identifier of the point uint32_t m_id; }; - -} // namespace df +} // namespace df diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index e68ec70ec9..d2cfc42962 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -13,14 +13,12 @@ #include "base/logging.hpp" -#include "std/algorithm.hpp" +#include <algorithm> namespace df { - namespace { - //#define SHOW_RAW_POINTS df::ColorConstant const kTrackUnknownDistanceColor = "TrackUnknownDistance"; @@ -33,7 +31,7 @@ int const kMinVisibleZoomLevel = 5; size_t const kAveragePointsCount = 512; // Radius of circles depending on zoom levels. -float const kRadiusInPixel[] = +std::vector<float> const kRadiusInPixel = { // 1 2 3 4 5 6 7 8 9 10 0.8f, 0.8f, 0.8f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, @@ -49,13 +47,24 @@ uint8_t const kMinNightAlpha = 50; uint8_t const kMaxNightAlpha = 102; double const kUnknownDistanceTime = 5 * 60; // seconds +double const kDistanceScalar = 0.4; + +float CalculateRadius(ScreenBase const & screen) +{ + double zoom = 0.0; + int index = 0; + float lerpCoef = 0.0f; + ExtractZoomFactors(screen, zoom, index, lerpCoef); + float const radius = InterpolateByZoomLevels(index, lerpCoef, kRadiusInPixel); + return radius * static_cast<float>(VisualParams::Instance().GetVisualScale()); +} + #ifdef DEBUG bool GpsPointsSortPredicate(GpsTrackPoint const & pt1, GpsTrackPoint const & pt2) { return pt1.m_id < pt2.m_id; } #endif - } // namespace GpsTrackRenderer::GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn) @@ -69,30 +78,14 @@ GpsTrackRenderer::GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn) m_handlesCache.reserve(8); } -float GpsTrackRenderer::CalculateRadius(ScreenBase const & screen) const -{ - double const zoomLevel = GetZoomLevel(screen.GetScale()); - double zoom = trunc(zoomLevel); - int const index = zoom - 1.0; - float const lerpCoef = zoomLevel - zoom; - - float radius = 0.0f; - if (index < scales::UPPER_STYLE_SCALE) - radius = kRadiusInPixel[index] + lerpCoef * (kRadiusInPixel[index + 1] - kRadiusInPixel[index]); - else - radius = kRadiusInPixel[scales::UPPER_STYLE_SCALE]; - - return radius * VisualParams::Instance().GetVisualScale(); -} - void GpsTrackRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng, - drape_ptr<GpsTrackRenderData> && renderData) + drape_ptr<CirclesPackRenderData> && renderData) { - drape_ptr<GpsTrackRenderData> data = move(renderData); - ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM); + drape_ptr<CirclesPackRenderData> data = std::move(renderData); + ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM); program->Bind(); data->m_bucket->GetBuffer()->Build(program); - m_renderData.push_back(move(data)); + m_renderData.push_back(std::move(data)); m_waitForRenderData = false; } @@ -104,16 +97,18 @@ void GpsTrackRenderer::ClearRenderData() m_needUpdate = true; } -void GpsTrackRenderer::UpdatePoints(vector<GpsTrackPoint> const & toAdd, vector<uint32_t> const & toRemove) +void GpsTrackRenderer::UpdatePoints(std::vector<GpsTrackPoint> const & toAdd, + std::vector<uint32_t> const & toRemove) { bool wasChanged = false; if (!toRemove.empty()) { auto removePredicate = [&toRemove](GpsTrackPoint const & pt) { - return find(toRemove.begin(), toRemove.end(), pt.m_id) != toRemove.end(); + return std::find(toRemove.begin(), toRemove.end(), pt.m_id) != toRemove.end(); }; - m_points.erase(remove_if(m_points.begin(), m_points.end(), removePredicate), m_points.end()); + m_points.erase(std::remove_if(m_points.begin(), m_points.end(), removePredicate), + m_points.end()); wasChanged = true; } @@ -170,7 +165,8 @@ dp::Color GpsTrackRenderer::CalculatePointColor(size_t pointIndex, m2::PointD co if ((end.m_timestamp - start.m_timestamp) > kUnknownDistanceTime) { dp::Color const color = df::GetColorConstant(df::kTrackUnknownDistanceColor); - return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha); + return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), + static_cast<uint8_t>(alpha)); } double const length = (end.m_point - start.m_point).Length(); @@ -179,7 +175,8 @@ dp::Color GpsTrackRenderer::CalculatePointColor(size_t pointIndex, m2::PointD co double const speed = max(start.m_speedMPS * (1.0 - td) + end.m_speedMPS * td, 0.0); dp::Color const color = GetColorBySpeed(speed); - return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha); + return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), + static_cast<uint8_t>(alpha)); } dp::Color GpsTrackRenderer::GetColorBySpeed(double speed) const @@ -228,10 +225,11 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, m_handlesCache.clear(); for (size_t i = 0; i < m_renderData.size(); i++) { - ASSERT_EQUAL(m_renderData[i]->m_bucket->GetOverlayHandlesCount(), 1, ()); - GpsTrackHandle * handle = static_cast<GpsTrackHandle*>(m_renderData[i]->m_bucket->GetOverlayHandle(0).get()); + auto & bucket = m_renderData[i]->m_bucket; + ASSERT_EQUAL(bucket->GetOverlayHandlesCount(), 1, ()); + CirclesPackHandle * handle = static_cast<CirclesPackHandle *>(bucket->GetOverlayHandle(0).get()); handle->Clear(); - m_handlesCache.push_back(make_pair(handle, 0)); + m_handlesCache.push_back(std::make_pair(handle, 0)); } m_pivot = screen.GlobalRect().Center(); @@ -246,8 +244,6 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, } else { - double const kDistanceScalar = 0.4; - m2::Spline::iterator it; it.Attach(m_pointsSpline); while (!it.BeginAgain()) @@ -257,9 +253,11 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, pt.x + radiusMercator, pt.y + radiusMercator); if (screen.ClipRect().IsIntersect(pointRect)) { - dp::Color const color = CalculatePointColor(it.GetIndex(), pt, it.GetLength(), it.GetFullLength()); + dp::Color const color = CalculatePointColor(it.GetIndex(), pt, + it.GetLength(), it.GetFullLength()); 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].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++; @@ -278,7 +276,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, for (size_t i = 0; i < m_points.size(); i++) { 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].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++; @@ -305,7 +304,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, math::Matrix<float, 4, 4> mv = screen.GetModelView(m_pivot, kShapeCoordScalar); uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); - ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM); + ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM); program->Bind(); ASSERT_GREATER(m_renderData.size(), 0, ()); @@ -314,8 +313,10 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, dp::ApplyUniforms(uniforms, program); for (size_t i = 0; i < m_renderData.size(); i++) + { if (m_handlesCache[i].second != 0) m_renderData[i]->m_bucket->Render(state.GetDrawAsLine()); + } } void GpsTrackRenderer::Update() @@ -328,6 +329,4 @@ void GpsTrackRenderer::Clear() m_points.clear(); m_needUpdate = true; } - -} // namespace df - +} // namespace df diff --git a/drape_frontend/gps_track_renderer.hpp b/drape_frontend/gps_track_renderer.hpp index b9c67005ce..bf13acf107 100644 --- a/drape_frontend/gps_track_renderer.hpp +++ b/drape_frontend/gps_track_renderer.hpp @@ -1,7 +1,7 @@ #pragma once +#include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/gps_track_point.hpp" -#include "drape_frontend/gps_track_shape.hpp" #include "drape/gpu_program_manager.hpp" #include "drape/pointers.hpp" @@ -10,23 +10,23 @@ #include "geometry/screenbase.hpp" #include "geometry/spline.hpp" -#include "std/map.hpp" -#include "std/vector.hpp" +#include <functional> +#include <map> +#include <vector> namespace df { - class GpsTrackRenderer final { public: - using TRenderDataRequestFn = function<void(size_t)>; + using TRenderDataRequestFn = std::function<void(size_t)>; explicit GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn); void AddRenderData(ref_ptr<dp::GpuProgramManager> mng, - drape_ptr<GpsTrackRenderData> && renderData); + drape_ptr<CirclesPackRenderData> && renderData); - void UpdatePoints(vector<GpsTrackPoint> const & toAdd, - vector<uint32_t> const & toRemove); + void UpdatePoints(std::vector<GpsTrackPoint> const & toAdd, + std::vector<uint32_t> const & toRemove); void RenderTrack(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, @@ -37,21 +37,19 @@ public: void ClearRenderData(); private: - float CalculateRadius(ScreenBase const & screen) const; size_t GetAvailablePointsCount() const; dp::Color CalculatePointColor(size_t pointIndex, m2::PointD const & curPoint, double lengthFromStart, double fullLength) const; dp::Color GetColorBySpeed(double speed) const; TRenderDataRequestFn m_dataRequestFn; - vector<drape_ptr<GpsTrackRenderData>> m_renderData; - vector<GpsTrackPoint> m_points; + std::vector<drape_ptr<CirclesPackRenderData>> m_renderData; + std::vector<GpsTrackPoint> m_points; m2::Spline m_pointsSpline; bool m_needUpdate; bool m_waitForRenderData; - vector<pair<GpsTrackHandle*, size_t>> m_handlesCache; + std::vector<std::pair<CirclesPackHandle *, size_t>> m_handlesCache; float m_radius; m2::PointD m_pivot; }; - -} // namespace df +} // namespace df diff --git a/drape_frontend/gps_track_shape.cpp b/drape_frontend/gps_track_shape.cpp deleted file mode 100644 index c48b1f915d..0000000000 --- a/drape_frontend/gps_track_shape.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "drape_frontend/gps_track_shape.hpp" -#include "drape_frontend/shader_def.hpp" - -#include "drape/attribute_provider.hpp" -#include "drape/batcher.hpp" -#include "drape/glsl_func.hpp" -#include "drape/glsl_types.hpp" -#include "drape/texture_manager.hpp" - -#include "base/logging.hpp" - -namespace df -{ - -namespace -{ - -uint32_t const kDynamicStreamID = 0x7F; - -struct GpsTrackStaticVertex -{ - using TNormal = glsl::vec3; - - GpsTrackStaticVertex() = default; - GpsTrackStaticVertex(TNormal const & normal) : m_normal(normal) {} - - TNormal m_normal; -}; - -dp::GLState GetGpsTrackState(ref_ptr<dp::TextureManager> texMng) -{ - dp::GLState state(gpu::TRACK_POINT_PROGRAM, dp::GLState::OverlayLayer); - state.SetColorTexture(texMng->GetSymbolsTexture()); - return state; -} - -dp::BindingInfo const & GetGpsTrackStaticBindingInfo() -{ - static unique_ptr<dp::BindingInfo> s_info; - if (s_info == nullptr) - { - dp::BindingFiller<GpsTrackStaticVertex> filler(1); - filler.FillDecl<GpsTrackStaticVertex::TNormal>("a_normal"); - s_info.reset(new dp::BindingInfo(filler.m_info)); - } - return *s_info; -} - -dp::BindingInfo const & GetGpsTrackDynamicBindingInfo() -{ - static unique_ptr<dp::BindingInfo> s_info; - if (s_info == nullptr) - { - dp::BindingFiller<GpsTrackDynamicVertex> filler(2, kDynamicStreamID); - filler.FillDecl<GpsTrackDynamicVertex::TPosition>("a_position"); - filler.FillDecl<GpsTrackDynamicVertex::TColor>("a_color"); - s_info.reset(new dp::BindingInfo(filler.m_info)); - } - return *s_info; -} - -} // namespace - -GpsTrackHandle::GpsTrackHandle(size_t pointsCount) - : OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false) - , m_needUpdate(false) -{ - m_buffer.resize(pointsCount * dp::Batcher::VertexPerQuad); -} - -void GpsTrackHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const -{ - if (!m_needUpdate) - return; - - TOffsetNode const & node = GetOffsetNode(kDynamicStreamID); - ASSERT(node.first.GetElementSize() == sizeof(GpsTrackDynamicVertex), ()); - ASSERT(node.second.m_count == m_buffer.size(), ()); - - uint32_t const byteCount = static_cast<uint32_t>(m_buffer.size()) * sizeof(GpsTrackDynamicVertex); - void * buffer = mutator->AllocateMutationBuffer(byteCount); - memcpy(buffer, m_buffer.data(), byteCount); - - dp::MutateNode mutateNode; - mutateNode.m_region = node.second; - mutateNode.m_data = make_ref(buffer); - mutator->AddMutation(node.first, mutateNode); - - m_needUpdate = false; -} - -bool GpsTrackHandle::Update(ScreenBase const & screen) -{ - UNUSED_VALUE(screen); - return true; -} - -bool GpsTrackHandle::IndexesRequired() const -{ - return false; -} - -m2::RectD GpsTrackHandle::GetPixelRect(ScreenBase const & screen, bool perspective) const -{ - UNUSED_VALUE(screen); - UNUSED_VALUE(perspective); - return m2::RectD(); -} - -void GpsTrackHandle::GetPixelShape(ScreenBase const & screen, bool perspective, Rects & rects) const -{ - UNUSED_VALUE(screen); - UNUSED_VALUE(perspective); -} - -void GpsTrackHandle::SetPoint(size_t index, m2::PointD const & position, - float radius, dp::Color const & color) -{ - size_t bufferIndex = index * dp::Batcher::VertexPerQuad; - ASSERT_GREATER_OR_EQUAL(bufferIndex, 0, ()); - ASSERT_LESS(bufferIndex, m_buffer.size(), ()); - - for (size_t i = 0; i < dp::Batcher::VertexPerQuad; i++) - { - m_buffer[bufferIndex + i].m_position = glsl::vec3(position.x, position.y, radius); - m_buffer[bufferIndex + i].m_color = glsl::ToVec4(color); - } - m_needUpdate = true; -} - -void GpsTrackHandle::Clear() -{ - memset(m_buffer.data(), 0, m_buffer.size() * sizeof(GpsTrackDynamicVertex)); - m_needUpdate = true; -} - -size_t GpsTrackHandle::GetPointsCount() const -{ - return m_buffer.size() / dp::Batcher::VertexPerQuad; -} - -void GpsTrackShape::Draw(ref_ptr<dp::TextureManager> texMng, GpsTrackRenderData & data) -{ - ASSERT_NOT_EQUAL(data.m_pointsCount, 0, ()); - - size_t const kVerticesInPoint = dp::Batcher::VertexPerQuad; - size_t const kIndicesInPoint = dp::Batcher::IndexPerQuad; - vector<GpsTrackStaticVertex> staticVertexData; - staticVertexData.reserve(data.m_pointsCount * kVerticesInPoint); - for (size_t i = 0; i < data.m_pointsCount; i++) - { - staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(-1.0f, 1.0f, 1.0f))); - staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(-1.0f, -1.0f, 1.0f))); - staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(1.0f, 1.0f, 1.0f))); - staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(1.0f, -1.0f, 1.0f))); - } - - vector<GpsTrackDynamicVertex> dynamicVertexData; - dynamicVertexData.resize(data.m_pointsCount * kVerticesInPoint); - - dp::Batcher batcher(data.m_pointsCount * kIndicesInPoint, data.m_pointsCount * kVerticesInPoint); - dp::SessionGuard guard(batcher, [&data](dp::GLState const & state, drape_ptr<dp::RenderBucket> && b) - { - data.m_bucket = move(b); - data.m_state = state; - }); - - drape_ptr<dp::OverlayHandle> handle = make_unique_dp<GpsTrackHandle>(data.m_pointsCount); - - dp::AttributeProvider provider(2 /* stream count */, static_cast<uint32_t>(staticVertexData.size())); - provider.InitStream(0 /* stream index */, GetGpsTrackStaticBindingInfo(), make_ref(staticVertexData.data())); - provider.InitStream(1 /* stream index */, GetGpsTrackDynamicBindingInfo(), make_ref(dynamicVertexData.data())); - batcher.InsertListOfStrip(GetGpsTrackState(texMng), make_ref(&provider), move(handle), kVerticesInPoint); - - GLFunctions::glFlush(); -} - -} // namespace df diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index a18c6fa4ac..25e7159014 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -43,14 +43,17 @@ public: FlushRouteArrows, FollowRoute, DeactivateRouteFollowing, + SetRouteSegmentVisibility, + AddRoutePreviewSegment, + RemoveRoutePreviewSegment, UpdateMapStyle, SwitchMapStyle, Invalidate, Allow3dMode, Allow3dBuildings, EnablePerspective, - CacheGpsTrackPoints, - FlushGpsTrackPoints, + FlushCirclesPack, + CacheCirclesPack, UpdateGpsTrackPoints, ClearGpsTrackPoints, ShowChoosePositionMark, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index f9e7f2700a..c2cb3aba99 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -1,14 +1,13 @@ #pragma once -#include "drape_frontend/gui/layer_render.hpp" -#include "drape_frontend/gui/skin.hpp" - +#include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/color_constants.hpp" #include "drape_frontend/custom_symbol.hpp" #include "drape_frontend/drape_api.hpp" #include "drape_frontend/drape_api_builder.hpp" #include "drape_frontend/gps_track_point.hpp" -#include "drape_frontend/gps_track_shape.hpp" +#include "drape_frontend/gui/layer_render.hpp" +#include "drape_frontend/gui/skin.hpp" #include "drape_frontend/message.hpp" #include "drape_frontend/my_position.hpp" #include "drape_frontend/overlay_batcher.hpp" @@ -17,25 +16,25 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/traffic_generator.hpp" -#include "drape_frontend/user_marks_provider.hpp" #include "drape_frontend/user_mark_shapes.hpp" - -#include "geometry/polyline2d.hpp" -#include "geometry/rect2d.hpp" -#include "geometry/screenbase.hpp" -#include "geometry/triangle2d.hpp" +#include "drape_frontend/user_marks_provider.hpp" #include "drape/glstate.hpp" #include "drape/pointers.hpp" #include "drape/render_bucket.hpp" #include "drape/viewport.hpp" +#include "geometry/polyline2d.hpp" +#include "geometry/rect2d.hpp" +#include "geometry/screenbase.hpp" +#include "geometry/triangle2d.hpp" + #include "platform/location.hpp" #include "std/condition_variable.hpp" -#include "std/shared_ptr.hpp" -#include "std/set.hpp" #include "std/function.hpp" +#include "std/set.hpp" +#include "std/shared_ptr.hpp" #include "std/utility.hpp" namespace df @@ -702,6 +701,68 @@ private: drape_ptr<RouteArrowsData> m_routeArrowsData; }; +class AddRoutePreviewSegmentMessage : public Message +{ +public: + AddRoutePreviewSegmentMessage(dp::DrapeID segmentId, m2::PointD const & startPt, + m2::PointD const & finishPt) + : m_segmentId(segmentId) + , m_startPoint(startPt) + , m_finishPoint(finishPt) + {} + + Type GetType() const override { return Message::AddRoutePreviewSegment; } + + dp::DrapeID GetSegmentId() const { return m_segmentId; }; + m2::PointD const & GetStartPoint() const { return m_startPoint; } + m2::PointD const & GetFinishPoint() const { return m_finishPoint; } + +private: + dp::DrapeID m_segmentId; + m2::PointD m_startPoint; + m2::PointD m_finishPoint; +}; + +class RemoveRoutePreviewSegmentMessage : public Message +{ +public: + RemoveRoutePreviewSegmentMessage() + : m_needRemoveAll(true) + {} + + explicit RemoveRoutePreviewSegmentMessage(dp::DrapeID segmentId) + : m_segmentId(segmentId) + , m_needRemoveAll(false) + {} + + Type GetType() const override { return Message::RemoveRoutePreviewSegment; } + + dp::DrapeID GetSegmentId() const { return m_segmentId; } + bool NeedRemoveAll() const { return m_needRemoveAll; } + +private: + dp::DrapeID m_segmentId; + bool m_needRemoveAll; +}; + +class SetRouteSegmentVisibilityMessage : public Message +{ +public: + SetRouteSegmentVisibilityMessage(dp::DrapeID segmentId, bool isVisible) + : m_segmentId(segmentId) + , m_isVisible(isVisible) + {} + + Type GetType() const override { return Message::SetRouteSegmentVisibility; } + + dp::DrapeID GetSegmentId() const { return m_segmentId; } + bool IsVisible() const { return m_isVisible; } + +private: + dp::DrapeID m_segmentId; + bool m_isVisible; +}; + class UpdateMapStyleMessage : public BaseBlockingMessage { public: @@ -839,51 +900,68 @@ public: Type GetType() const override { return Message::EnablePerspective; } }; -class CacheGpsTrackPointsMessage : public Message +class CacheCirclesPackMessage : public Message { public: - CacheGpsTrackPointsMessage(uint32_t pointsCount) : m_pointsCount(pointsCount) {} + enum Destination + { + GpsTrack, + RoutePreview + }; - Type GetType() const override { return Message::CacheGpsTrackPoints; } + CacheCirclesPackMessage(uint32_t pointsCount, Destination dest) + : m_pointsCount(pointsCount) + , m_destination(dest) + {} + + Type GetType() const override { return Message::CacheCirclesPack; } uint32_t GetPointsCount() const { return m_pointsCount; } + Destination GetDestination() const { return m_destination; } private: uint32_t m_pointsCount; + Destination m_destination; }; -class FlushGpsTrackPointsMessage : public Message +class FlushCirclesPackMessage : public Message { public: - FlushGpsTrackPointsMessage(drape_ptr<GpsTrackRenderData> && renderData) - : m_renderData(move(renderData)) + + FlushCirclesPackMessage(drape_ptr<CirclesPackRenderData> && renderData, + CacheCirclesPackMessage::Destination dest) + : m_renderData(std::move(renderData)) + , m_destination(dest) {} - Type GetType() const override { return Message::FlushGpsTrackPoints; } + Type GetType() const override { return Message::FlushCirclesPack; } bool IsGLContextDependent() const override { return true; } - drape_ptr<GpsTrackRenderData> && AcceptRenderData() { return move(m_renderData); } + drape_ptr<CirclesPackRenderData> && AcceptRenderData() { return std::move(m_renderData); } + CacheCirclesPackMessage::Destination GetDestination() const { return m_destination; } private: - drape_ptr<GpsTrackRenderData> m_renderData; + drape_ptr<CirclesPackRenderData> m_renderData; + CacheCirclesPackMessage::Destination m_destination; }; class UpdateGpsTrackPointsMessage : public Message { public: - UpdateGpsTrackPointsMessage(vector<GpsTrackPoint> && toAdd, vector<uint32_t> && toRemove) - : m_pointsToAdd(move(toAdd)) - , m_pointsToRemove(move(toRemove)) + UpdateGpsTrackPointsMessage(std::vector<GpsTrackPoint> && toAdd, + std::vector<uint32_t> && toRemove) + : m_pointsToAdd(std::move(toAdd)) + , m_pointsToRemove(std::move(toRemove)) {} Type GetType() const override { return Message::UpdateGpsTrackPoints; } - vector<GpsTrackPoint> const & GetPointsToAdd() { return m_pointsToAdd; } - vector<uint32_t> const & GetPointsToRemove() { return m_pointsToRemove; } + std::vector<GpsTrackPoint> const & GetPointsToAdd() { return m_pointsToAdd; } + std::vector<uint32_t> const & GetPointsToRemove() { return m_pointsToRemove; } private: - vector<GpsTrackPoint> m_pointsToAdd; - vector<uint32_t> m_pointsToRemove; + std::vector<GpsTrackPoint> m_pointsToAdd; + std::vector<uint32_t> m_pointsToRemove; }; class ClearGpsTrackPointsMessage : public Message @@ -892,7 +970,6 @@ public: ClearGpsTrackPointsMessage() = default; Type GetType() const override { return Message::ClearGpsTrackPoints; } - }; class SetTimeInBackgroundMessage : public Message diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 872cdfd034..438372544a 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -13,6 +13,7 @@ #include "base/logging.hpp" #include <algorithm> +#include <cmath> namespace df { @@ -20,10 +21,11 @@ std::string const kRouteColor = "Route"; std::string const kRouteOutlineColor = "RouteOutline"; std::string const kRoutePedestrian = "RoutePedestrian"; std::string const kRouteBicycle = "RouteBicycle"; +std::string const kRoutePreview = "RoutePreview"; namespace { -float const kHalfWidthInPixelCar[] = +std::vector<float> const kHalfWidthInPixelCar = { // 1 2 3 4 5 6 7 8 9 10 1.0f, 1.0f, 1.5f, 1.5f, 1.5f, 2.0f, 2.0f, 2.0f, 2.5f, 2.5f, @@ -31,7 +33,7 @@ float const kHalfWidthInPixelCar[] = 3.0f, 3.0f, 4.0f, 5.0f, 6.0, 8.0f, 10.0f, 10.0f, 18.0f, 27.0f }; -float const kHalfWidthInPixelOthers[] = +std::vector<float> const kHalfWidthInPixelOthers = { // 1 2 3 4 5 6 7 8 9 10 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.2f, 1.2f, @@ -39,9 +41,46 @@ float const kHalfWidthInPixelOthers[] = 1.5f, 1.5f, 2.0f, 2.5f, 3.0, 4.0f, 5.0f, 5.0f, 9.0f, 13.0f }; +std::vector<float> const kPreviewPointRadiusInPixel = +{ + // 1 2 3 4 5 6 7 8 9 10 + 0.8f, 0.8f, 0.8f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, + //11 12 13 14 15 16 17 18 19 20 + 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 3.5f, 4.5f, 4.5f, 4.5f, 5.5f +}; + int const kArrowAppearingZoomLevel = 14; int const kInvalidGroup = -1; +size_t const kPreviewPointsCount = 512; +double const kPreviewAnimationSpeed = 3.0; +double const kPreviewAnimationScale = 0.3; + +void InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen, + float & halfWidth, double & zoom) +{ + int index = 0; + float lerpCoef = 0.0f; + ExtractZoomFactors(screen, zoom, index, lerpCoef); + + std::vector<float> const * halfWidthInPixel = &kHalfWidthInPixelOthers; + if (routeSegment->m_routeType == RouteType::Car || routeSegment->m_routeType == RouteType::Taxi) + halfWidthInPixel = &kHalfWidthInPixelCar; + + halfWidth = InterpolateByZoomLevels(index, lerpCoef, *halfWidthInPixel); + halfWidth *= static_cast<float>(df::VisualParams::Instance().GetVisualScale()); +} + +float CalculateRadius(ScreenBase const & screen) +{ + double zoom = 0.0; + int index = 0; + float lerpCoef = 0.0f; + ExtractZoomFactors(screen, zoom, index, lerpCoef); + float const radius = InterpolateByZoomLevels(index, lerpCoef, kPreviewPointRadiusInPixel); + return radius * static_cast<float>(VisualParams::Instance().GetVisualScale()); +} + void ClipBorders(std::vector<ArrowBorders> & borders) { auto invalidBorders = [](ArrowBorders const & borders) @@ -196,32 +235,16 @@ dp::Color GetOutlineColor(drape_ptr<RouteSegment> const & routeSegment) } } // namespace -RouteRenderer::RouteRenderer() +RouteRenderer::RouteRenderer(PreviewPointsRequestCallback && previewPointsRequest) : m_distanceFromBegin(0.0) , m_followingEnabled(false) -{} - -void RouteRenderer::InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen, - float & halfWidth, double & zoom) const + , m_previewPointsRequest(std::move(previewPointsRequest)) + , m_waitForPreviewRenderData(false) { - double const zoomLevel = GetZoomLevel(screen.GetScale()); - zoom = trunc(zoomLevel); - int const index = static_cast<int>(zoom - 1.0); - float const lerpCoef = static_cast<float>(zoomLevel - zoom); - - float const * halfWidthInPixel = kHalfWidthInPixelOthers; - if (routeSegment->m_routeType == RouteType::Car || routeSegment->m_routeType == RouteType::Taxi) - halfWidthInPixel = kHalfWidthInPixelCar; - - if (index < scales::UPPER_STYLE_SCALE) - halfWidth = halfWidthInPixel[index] + lerpCoef * (halfWidthInPixel[index + 1] - halfWidthInPixel[index]); - else - halfWidth = halfWidthInPixel[scales::UPPER_STYLE_SCALE]; - - halfWidth *= df::VisualParams::Instance().GetVisualScale(); + ASSERT(m_previewPointsRequest != nullptr, ()); } -void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCallback const & callback) +void RouteRenderer::UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback) { ASSERT(callback != nullptr, ()); for (auto const & routeData : m_routeData) @@ -258,6 +281,94 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCall } } +bool RouteRenderer::UpdatePreview(ScreenBase const & screen) +{ + // Check if there are preview render data. + if (m_previewRenderData.empty() && !m_waitForPreviewRenderData) + { + m_previewPointsRequest(kPreviewPointsCount); + m_waitForPreviewRenderData = true; + } + if (m_waitForPreviewRenderData) + return false; + + float scale = 1.0f; + float previewCircleRadius = 0.0; + if (!m_previewSegments.empty()) + { + ClearPreviewHandles(); + m_previewPivot = screen.GlobalRect().Center(); + previewCircleRadius = CalculateRadius(screen); + + using namespace std::chrono; + auto dt = steady_clock::now() - m_showPreviewTimestamp; + double const seconds = duration_cast<duration<double>>(dt).count(); + scale = static_cast<float>(1.0 + kPreviewAnimationScale * + abs(sin(kPreviewAnimationSpeed * seconds))); + } + double const currentScaleGtoP = 1.0 / screen.GetScale(); + double const radiusMercator = previewCircleRadius / currentScaleGtoP; + double const diameterMercator = 2.0 * radiusMercator; + double const gapMercator = diameterMercator; + dp::Color const circleColor = df::GetColorConstant(kRoutePreview); + + for (auto const & previewSegment : m_previewSegments) + { + auto const & info = previewSegment.second; + m2::PolylineD polyline = {info.m_startPoint, info.m_finishPoint}; + double const segmentLen = polyline.GetLength(); + size_t circlesCount = static_cast<size_t>(segmentLen / (diameterMercator + gapMercator)); + if (circlesCount == 0) + circlesCount = 1; + double const distDelta = segmentLen / circlesCount; + for (double d = distDelta * 0.5; d < segmentLen; d += distDelta) + { + float const r = scale * static_cast<float>(radiusMercator); + m2::PointD const pt = polyline.GetPointByDistance(d); + m2::RectD const circleRect(pt.x - r, pt.y - r, pt.x + r, pt.y + r); + if (!screen.ClipRect().IsIntersect(circleRect)) + continue; + + size_t pointIndex; + CirclesPackHandle * h = GetPreviewHandle(pointIndex); + if (h == nullptr) + { + // There is no any available handle. + m_previewPointsRequest(kPreviewPointsCount); + m_waitForPreviewRenderData = true; + return true; + } + + m2::PointD const convertedPt = MapShape::ConvertToLocal(pt, m_previewPivot, kShapeCoordScalar); + h->SetPoint(pointIndex, convertedPt, scale * previewCircleRadius, circleColor); + } + } + return !m_previewSegments.empty(); +} + +void RouteRenderer::ClearPreviewHandles() +{ + for (auto & handle : m_previewHandlesCache) + { + handle.first->Clear(); + handle.second = 0; + } +} + +CirclesPackHandle * RouteRenderer::GetPreviewHandle(size_t & index) +{ + for (auto & handle : m_previewHandlesCache) + { + if (handle.second < handle.first->GetPointsCount()) + { + index = handle.second++; + return handle.first; + } + } + index = 0; + return nullptr; +} + void RouteRenderer::RenderRouteData(drape_ptr<RouteData> const & routeData, ScreenBase const & screen, bool trafficShown, ref_ptr<dp::GpuProgramManager> mng, @@ -266,6 +377,10 @@ void RouteRenderer::RenderRouteData(drape_ptr<RouteData> const & routeData, if (routeData->m_renderProperty.m_buckets.empty()) return; + // Skip rendering of hidden segments. + if (m_hiddenSegments.find(routeData->m_segmentId) != m_hiddenSegments.end()) + return; + float const currentHalfWidth = m_routeAdditional[routeData->m_segmentId].m_currentHalfWidth; float const screenHalfWidth = static_cast<float>(currentHalfWidth * screen.GetScale()); float const dist = m_followingEnabled ? static_cast<float>(m_distanceFromBegin) : -1.0f; @@ -338,20 +453,48 @@ void RouteRenderer::RenderRouteArrowData(dp::DrapeID segmentId, RouteAdditional bucket->Render(state.GetDrawAsLine()); } +void RouteRenderer::RenderPreviewData(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, + dp::UniformValuesStorage const & commonUniforms) +{ + if (m_waitForPreviewRenderData || m_previewSegments.empty() || m_previewRenderData.empty()) + return; + + dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix<float, 4, 4> mv = screen.GetModelView(m_previewPivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + uniforms.SetFloatValue("u_opacity", 1.0f); + ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM); + program->Bind(); + + dp::GLState const & state = m_previewRenderData.front()->m_state; + dp::ApplyState(state, program); + dp::ApplyUniforms(uniforms, program); + + ASSERT_EQUAL(m_previewRenderData.size(), m_previewHandlesCache.size(), ()); + for (size_t i = 0; i < m_previewRenderData.size(); i++) + { + if (m_previewHandlesCache[i].second != 0) + m_previewRenderData[i]->m_bucket->Render(state.GetDrawAsLine()); + } +} + void RouteRenderer::RenderRoute(ScreenBase const & screen, bool trafficShown, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { - if (m_routeData.empty()) - return; + if (!m_routeData.empty()) + { + // Render route. + for (auto const & routeData : m_routeData) + RenderRouteData(routeData, screen, trafficShown, mng, commonUniforms); - // Render route. - for (auto const & routeData : m_routeData) - RenderRouteData(routeData, screen, trafficShown, mng, commonUniforms); + // Render arrows. + for (auto const & p : m_routeAdditional) + RenderRouteArrowData(p.first, p.second, screen, mng, commonUniforms); + } - // Render arrows. - for (auto const & p : m_routeAdditional) - RenderRouteArrowData(p.first, p.second, screen, mng, commonUniforms); + // Render preview. + RenderPreviewData(screen, mng, commonUniforms); } void RouteRenderer::AddRouteData(drape_ptr<RouteData> && routeData, @@ -390,10 +533,29 @@ void RouteRenderer::AddRouteArrowsData(drape_ptr<RouteArrowsData> && routeArrows BuildBuckets(additional.m_arrowsData->m_renderProperty, mng); } +void RouteRenderer::AddPreviewRenderData(drape_ptr<CirclesPackRenderData> && renderData, + ref_ptr<dp::GpuProgramManager> mng) +{ + drape_ptr<CirclesPackRenderData> data = std::move(renderData); + ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM); + program->Bind(); + data->m_bucket->GetBuffer()->Build(program); + m_previewRenderData.push_back(std::move(data)); + m_waitForPreviewRenderData = false; + + // Save handle in the cache. + auto & bucket = m_previewRenderData.back()->m_bucket; + ASSERT_EQUAL(bucket->GetOverlayHandlesCount(), 1, ()); + CirclesPackHandle * handle = static_cast<CirclesPackHandle *>(bucket->GetOverlayHandle(0).get()); + handle->Clear(); + m_previewHandlesCache.push_back(std::make_pair(handle, 0)); +} + void RouteRenderer::ClearRouteData() { m_routeData.clear(); m_routeAdditional.clear(); + m_hiddenSegments.clear(); } void RouteRenderer::Clear() @@ -410,6 +572,10 @@ void RouteRenderer::ClearGLDependentResources() // All additional data (like arrows) will be regenerated, so clear them all. m_routeAdditional.clear(); + + m_previewRenderData.clear(); + m_previewHandlesCache.clear(); + m_waitForPreviewRenderData = false; } void RouteRenderer::UpdateDistanceFromBegin(double distanceFromBegin) @@ -421,4 +587,29 @@ void RouteRenderer::SetFollowingEnabled(bool enabled) { m_followingEnabled = enabled; } + +void RouteRenderer::AddPreviewSegment(dp::DrapeID id, PreviewInfo && info) +{ + if (m_previewSegments.empty()) + m_showPreviewTimestamp = std::chrono::steady_clock::now(); + m_previewSegments.insert(std::make_pair(id, std::move(info))); +} + +void RouteRenderer::RemovePreviewSegment(dp::DrapeID id) +{ + m_previewSegments.erase(id); +} + +void RouteRenderer::RemoveAllPreviewSegments() +{ + m_previewSegments.clear(); +} + +void RouteRenderer::SetRouteSegmentVisibility(dp::DrapeID id, bool isVisible) +{ + if (isVisible) + m_hiddenSegments.erase(id); + else + m_hiddenSegments.insert(id); +} } // namespace df diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index 2a0ff6167f..7ca388d9ee 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -1,5 +1,6 @@ #pragma once +#include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/route_builder.hpp" #include "drape/drape_global.hpp" @@ -8,10 +9,12 @@ #include "geometry/screenbase.hpp" +#include <chrono> #include <functional> #include <string> #include <vector> #include <unordered_map> +#include <unordered_set> namespace df { @@ -23,11 +26,18 @@ extern std::string const kRouteBicycle; class RouteRenderer final { public: - using TCacheRouteArrowsCallback = std::function<void(dp::DrapeID, std::vector<ArrowBorders> const &)>; + using CacheRouteArrowsCallback = std::function<void(dp::DrapeID, std::vector<ArrowBorders> const &)>; + using PreviewPointsRequestCallback = std::function<void(size_t)>; - RouteRenderer(); + struct PreviewInfo + { + m2::PointD m_startPoint; + m2::PointD m_finishPoint; + }; - void UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCallback const & callback); + RouteRenderer(PreviewPointsRequestCallback && previewPointsRequest); + + void UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback); void RenderRoute(ScreenBase const & screen, bool trafficShown, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); @@ -40,6 +50,11 @@ public: void AddRouteArrowsData(drape_ptr<RouteArrowsData> && routeArrowsData, ref_ptr<dp::GpuProgramManager> mng); + void AddPreviewRenderData(drape_ptr<CirclesPackRenderData> && renderData, + ref_ptr<dp::GpuProgramManager> mng); + + bool UpdatePreview(ScreenBase const & screen); + void Clear(); void ClearRouteData(); void ClearGLDependentResources(); @@ -47,6 +62,12 @@ public: void UpdateDistanceFromBegin(double distanceFromBegin); void SetFollowingEnabled(bool enabled); + void AddPreviewSegment(dp::DrapeID id, PreviewInfo && info); + void RemovePreviewSegment(dp::DrapeID id); + void RemoveAllPreviewSegments(); + + void SetRouteSegmentVisibility(dp::DrapeID id, bool isVisible); + private: struct RouteAdditional { @@ -55,18 +76,29 @@ private: float m_currentHalfWidth = 0.0f; }; - void InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen, - float & halfWidth, double & zoom) const; void RenderRouteData(drape_ptr<RouteData> const & routeData, ScreenBase const & screen, bool trafficShown, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); void RenderRouteArrowData(dp::DrapeID segmentId, RouteAdditional const & routeAdditional, ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms); + void RenderPreviewData(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, + dp::UniformValuesStorage const & commonUniforms); + void ClearPreviewHandles(); + CirclesPackHandle * GetPreviewHandle(size_t & index); double m_distanceFromBegin; std::vector<drape_ptr<RouteData>> m_routeData; std::unordered_map<dp::DrapeID, RouteAdditional> m_routeAdditional; bool m_followingEnabled; + std::unordered_set<dp::DrapeID> m_hiddenSegments; + + PreviewPointsRequestCallback m_previewPointsRequest; + std::vector<drape_ptr<CirclesPackRenderData>> m_previewRenderData; + std::vector<std::pair<CirclesPackHandle *, size_t>> m_previewHandlesCache; + bool m_waitForPreviewRenderData; + std::unordered_map<dp::DrapeID, PreviewInfo> m_previewSegments; + m2::PointD m_previewPivot = m2::PointD::Zero(); + std::chrono::steady_clock::time_point m_showPreviewTimestamp; }; } // namespace df diff --git a/drape_frontend/shaders/trackpoint.fsh.glsl b/drape_frontend/shaders/circle_point.fsh.glsl index f96beba503..f96beba503 100644 --- a/drape_frontend/shaders/trackpoint.fsh.glsl +++ b/drape_frontend/shaders/circle_point.fsh.glsl diff --git a/drape_frontend/shaders/trackpoint.vsh.glsl b/drape_frontend/shaders/circle_point.vsh.glsl index 7d658bc5ed..7d658bc5ed 100644 --- a/drape_frontend/shaders/trackpoint.vsh.glsl +++ b/drape_frontend/shaders/circle_point.vsh.glsl diff --git a/drape_frontend/shaders/shader_index.txt b/drape_frontend/shaders/shader_index.txt index 1abb3719a7..66558f9808 100644 --- a/drape_frontend/shaders/shader_index.txt +++ b/drape_frontend/shaders/shader_index.txt @@ -22,7 +22,7 @@ BOOKMARK_PROGRAM user_mark.vsh.glsl texturing.fsh.glsl ROUTE_PROGRAM route.vsh.glsl route.fsh.glsl ROUTE_DASH_PROGRAM route.vsh.glsl route_dash.fsh.glsl ROUTE_ARROW_PROGRAM route_arrow.vsh.glsl discarded_texturing.fsh.glsl -TRACK_POINT_PROGRAM trackpoint.vsh.glsl trackpoint.fsh.glsl +CIRCLE_POINT_PROGRAM circle_point.vsh.glsl circle_point.fsh.glsl DEBUG_RECT_PROGRAM debug_rect.vsh.glsl debug_rect.fsh.glsl SCREEN_QUAD_PROGRAM screen_quad.vsh.glsl texturing.fsh.glsl ARROW_3D_PROGRAM arrow3d.vsh.glsl arrow3d.fsh.glsl diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp index edd71a5821..0270e324b6 100644 --- a/drape_frontend/traffic_renderer.cpp +++ b/drape_frontend/traffic_renderer.cpp @@ -12,7 +12,7 @@ #include "base/logging.hpp" -#include "std/algorithm.hpp" +#include <algorithm> namespace df { @@ -28,7 +28,7 @@ int constexpr kOutlineMinZoomLevel = 14; float const kTrafficArrowAspect = 128.0f / 8.0f; -float const kLeftWidthInPixel[] = +std::vector<float> const kLeftWidthInPixel = { // 1 2 3 4 5 6 7 8 9 10 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, @@ -36,7 +36,7 @@ float const kLeftWidthInPixel[] = 0.5f, 0.5f, 0.5f, 0.5f, 0.7f, 2.5f, 3.0f, 4.0f, 4.0f, 4.0f }; -float const kRightWidthInPixel[] = +std::vector<float> const kRightWidthInPixel = { // 1 2 3 4 5 6 7 8 9 10 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, @@ -44,7 +44,7 @@ float const kRightWidthInPixel[] = 3.0f, 3.0f, 4.0f, 4.0f, 3.8f, 2.5f, 3.0f, 4.0f, 4.0f, 4.0f }; -float const kRoadClass1WidthScalar[] = +std::vector<float> const kRoadClass1WidthScalar = { // 1 2 3 4 5 6 7 8 9 10 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3, @@ -52,7 +52,7 @@ float const kRoadClass1WidthScalar[] = 0.3, 0.3f, 0.4f, 0.5f, 0.6f, 0.6f, 1.0f, 1.0f, 1.0f, 1.0f }; -float const kRoadClass2WidthScalar[] = +std::vector<float> const kRoadClass2WidthScalar = { // 1 2 3 4 5 6 7 8 9 10 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3f, @@ -60,7 +60,7 @@ float const kRoadClass2WidthScalar[] = 0.3f, 0.3f, 0.3f, 0.3f, 0.5f, 0.5f, 0.5f, 0.8f, 0.9f, 1.0f }; -float const kTwoWayOffsetInPixel[] = +std::vector<float> const kTwoWayOffsetInPixel = { // 1 2 3 4 5 6 7 8 9 10 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, @@ -68,41 +68,27 @@ float const kTwoWayOffsetInPixel[] = 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f }; -vector<int> const kLineDrawerRoadClass1 = {12, 13, 14}; +std::vector<int> const kLineDrawerRoadClass1 = {12, 13, 14}; -vector<int> const kLineDrawerRoadClass2 = {15, 16}; +std::vector<int> const kLineDrawerRoadClass2 = {15, 16}; float CalculateHalfWidth(ScreenBase const & screen, RoadClass const & roadClass, bool left) { - double const zoomLevel = GetZoomLevel(screen.GetScale()); - double zoom = trunc(zoomLevel); - int const index = static_cast<int>(zoom - 1.0); - float const lerpCoef = static_cast<float>(zoomLevel - zoom); + double zoom = 0.0; + int index = 0; + float lerpCoef = 0.0f; + ExtractZoomFactors(screen, zoom, index, lerpCoef); - float const * widthScalar = nullptr; + std::vector<float> const * halfWidth = left ? &kLeftWidthInPixel : &kRightWidthInPixel; + float radius = InterpolateByZoomLevels(index, lerpCoef, *halfWidth); if (roadClass == RoadClass::Class1) - widthScalar = kRoadClass1WidthScalar; + radius *= InterpolateByZoomLevels(index, lerpCoef, kRoadClass1WidthScalar); else if (roadClass == RoadClass::Class2) - widthScalar = kRoadClass2WidthScalar; - - float const * halfWidth = left ? kLeftWidthInPixel : kRightWidthInPixel; - float radius = 0.0f; - if (index < scales::UPPER_STYLE_SCALE) - { - radius = halfWidth[index] + lerpCoef * (halfWidth[index + 1] - halfWidth[index]); - if (widthScalar != nullptr) - radius *= (widthScalar[index] + lerpCoef * (widthScalar[index + 1] - widthScalar[index])); - } - else - { - radius = halfWidth[scales::UPPER_STYLE_SCALE]; - if (widthScalar != nullptr) - radius *= widthScalar[scales::UPPER_STYLE_SCALE]; - } + radius *= InterpolateByZoomLevels(index, lerpCoef, kRoadClass2WidthScalar); return radius * static_cast<float>(VisualParams::Instance().GetVisualScale()); } -} // namespace +} // namespace void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng, TrafficRenderData && renderData) { @@ -275,16 +261,16 @@ float TrafficRenderer::GetPixelWidthInternal(RoadClass const & roadClass, int zo { ASSERT_GREATER(zoomLevel, 1, ()); ASSERT_LESS_OR_EQUAL(zoomLevel, scales::GetUpperStyleScale(), ()); - float const * widthScalar = nullptr; + std::vector<float> const * widthScalar = nullptr; if (roadClass == RoadClass::Class1) - widthScalar = kRoadClass1WidthScalar; + widthScalar = &kRoadClass1WidthScalar; else if (roadClass == RoadClass::Class2) - widthScalar = kRoadClass2WidthScalar; + widthScalar = &kRoadClass2WidthScalar; int const index = zoomLevel - 1; float const baseWidth = (kLeftWidthInPixel[index] + kRightWidthInPixel[index]) * static_cast<float>(df::VisualParams::Instance().GetVisualScale()); - return (widthScalar != nullptr) ? (baseWidth * widthScalar[index]) : baseWidth; + return (widthScalar != nullptr) ? (baseWidth * (*widthScalar)[index]) : baseWidth; } // static @@ -293,7 +279,7 @@ bool TrafficRenderer::CanBeRendereredAsLine(RoadClass const & roadClass, int zoo if (roadClass == RoadClass::Class0) return false; - vector<int> const * lineDrawer = nullptr; + std::vector<int> const * lineDrawer = nullptr; if (roadClass == RoadClass::Class1) lineDrawer = &kLineDrawerRoadClass1; else if (roadClass == RoadClass::Class2) @@ -307,5 +293,4 @@ bool TrafficRenderer::CanBeRendereredAsLine(RoadClass const & roadClass, int zoo width = max(1, my::rounds(TrafficRenderer::GetPixelWidthInternal(roadClass, zoomLevel))); return width <= dp::SupportManager::Instance().GetMaxLineWidth(); } -} // namespace df - +} // namespace df diff --git a/drape_frontend/traffic_renderer.hpp b/drape_frontend/traffic_renderer.hpp index 222a271538..e79aa65e25 100644 --- a/drape_frontend/traffic_renderer.hpp +++ b/drape_frontend/traffic_renderer.hpp @@ -10,11 +10,10 @@ #include "geometry/screenbase.hpp" #include "geometry/spline.hpp" -#include "std/vector.hpp" +#include <vector> namespace df { - class TrafficRenderer final { public: @@ -43,7 +42,6 @@ private: static float GetPixelWidth(RoadClass const & roadClass, int zoomLevel); static float GetPixelWidthInternal(RoadClass const & roadClass, int zoomLevel); - vector<TrafficRenderData> m_renderData; + std::vector<TrafficRenderData> m_renderData; }; - -} // namespace df +} // namespace df diff --git a/drape_frontend/visual_params.cpp b/drape_frontend/visual_params.cpp index e258dadfd9..2ba044fa8f 100644 --- a/drape_frontend/visual_params.cpp +++ b/drape_frontend/visual_params.cpp @@ -296,6 +296,23 @@ double GetZoomLevel(double scale) return my::clamp(fabs(log(scale) / kLog2), 1.0, scales::GetUpperStyleScale() + 1.0); } +void ExtractZoomFactors(ScreenBase const & s, double & zoom, int & index, float & lerpCoef) +{ + double const zoomLevel = GetZoomLevel(s.GetScale()); + zoom = trunc(zoomLevel); + index = static_cast<int>(zoom - 1.0); + lerpCoef = static_cast<float>(zoomLevel - zoom); +} + +float InterpolateByZoomLevels(int index, float lerpCoef, std::vector<float> const & values) +{ + ASSERT_GREATER_OR_EQUAL(index, 0, ()); + ASSERT_GREATER(values.size(), scales::UPPER_STYLE_SCALE, ()); + if (index < scales::UPPER_STYLE_SCALE) + return values[index] + lerpCoef * (values[index + 1] - values[index]); + return values[scales::UPPER_STYLE_SCALE]; +} + double GetNormalizedZoomLevel(double scale, int minZoom) { double const kMaxZoom = scales::GetUpperStyleScale() + 1.0; diff --git a/drape_frontend/visual_params.hpp b/drape_frontend/visual_params.hpp index 7f2320b3a5..eb32f284ee 100644 --- a/drape_frontend/visual_params.hpp +++ b/drape_frontend/visual_params.hpp @@ -85,6 +85,8 @@ m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center); uint32_t CalculateTileSize(uint32_t screenWidth, uint32_t screenHeight); double GetZoomLevel(double scale); +void ExtractZoomFactors(ScreenBase const & s, double & zoom, int & index, float & lerpCoef); +float InterpolateByZoomLevels(int index, float lerpCoef, std::vector<float> const & values); double GetNormalizedZoomLevel(double scale, int minZoom = 1); double GetScale(double zoomLevel); |