forked from organicmaps/organicmaps
User marks generator fixes.
This commit is contained in:
parent
85a5f9996e
commit
891bcaa629
14 changed files with 287 additions and 339 deletions
|
@ -32,6 +32,7 @@ BackendRenderer::BackendRenderer(Params && params)
|
|||
, m_readManager(make_unique_dp<ReadManager>(params.m_commutator, m_model,
|
||||
params.m_allow3dBuildings, params.m_trafficEnabled))
|
||||
, m_trafficGenerator(make_unique_dp<TrafficGenerator>(bind(&BackendRenderer::FlushTrafficRenderData, this, _1)))
|
||||
, m_userMarkGenerator(make_unique_dp<UserMarkGenerator>(bind(&BackendRenderer::FlushUserMarksRenderData, this, _1, _2)))
|
||||
, m_requestedTiles(params.m_requestedTiles)
|
||||
, m_updateCurrentCountryFn(params.m_updateCurrentCountryFn)
|
||||
, m_metalineManager(make_unique_dp<MetalineManager>(params.m_commutator, m_model))
|
||||
|
@ -167,6 +168,7 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
{
|
||||
ref_ptr<TileReadEndMessage> msg = message;
|
||||
m_batchersPool->ReleaseBatcher(msg->GetKey());
|
||||
m_userMarkGenerator->GenerateUserMarksGeometry(msg->GetKey(), m_texMng);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -251,21 +253,11 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
case Message::UpdateUserMarkLayer:
|
||||
{
|
||||
ref_ptr<UpdateUserMarkLayerMessage> msg = message;
|
||||
|
||||
UserMarksProvider const * marksProvider = msg->StartProcess();
|
||||
if (marksProvider->IsDirty())
|
||||
{
|
||||
size_t const layerId = msg->GetLayerId();
|
||||
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<ClearUserMarkLayerMessage>(layerId),
|
||||
MessagePriority::Normal);
|
||||
|
||||
TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng);
|
||||
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<FlushUserMarksMessage>(layerId, move(shapes)),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
msg->EndProcess();
|
||||
size_t const layerId = msg->GetLayerId();
|
||||
m_userMarkGenerator->SetUserMarks(static_cast<GroupID>(layerId), msg->AcceptRenderParams());
|
||||
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<InvalidateUserMarksMessage>(layerId),
|
||||
MessagePriority::Normal);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -579,6 +571,13 @@ void BackendRenderer::FlushTrafficRenderData(TrafficRenderData && renderData)
|
|||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void BackendRenderer::FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData)
|
||||
{
|
||||
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<FlushUserMarksMessage>(groupId, std::move(renderData)),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void BackendRenderer::CleanupOverlays(TileKey const & tileKey)
|
||||
{
|
||||
auto const functor = [&tileKey](OverlayRenderData const & data)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "drape_frontend/overlay_batcher.hpp"
|
||||
#include "drape_frontend/requested_tiles.hpp"
|
||||
#include "drape_frontend/traffic_generator.hpp"
|
||||
#include "drape_frontend/user_mark_generator.hpp"
|
||||
|
||||
#include "drape/pointers.hpp"
|
||||
#include "drape/viewport.hpp"
|
||||
|
@ -95,6 +96,7 @@ private:
|
|||
void FlushGeometry(TileKey const & key, dp::GLState const & state, drape_ptr<dp::RenderBucket> && buffer);
|
||||
|
||||
void FlushTrafficRenderData(TrafficRenderData && renderData);
|
||||
void FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData);
|
||||
|
||||
void CleanupOverlays(TileKey const & tileKey);
|
||||
|
||||
|
@ -103,6 +105,7 @@ private:
|
|||
drape_ptr<ReadManager> m_readManager;
|
||||
drape_ptr<RouteBuilder> m_routeBuilder;
|
||||
drape_ptr<TrafficGenerator> m_trafficGenerator;
|
||||
drape_ptr<UserMarkGenerator> m_userMarkGenerator;
|
||||
drape_ptr<DrapeApiBuilder> m_drapeApiBuilder;
|
||||
gui::LayerCacher m_guiCacher;
|
||||
|
||||
|
|
|
@ -209,8 +209,23 @@ void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible)
|
|||
|
||||
void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider)
|
||||
{
|
||||
auto renderCollection = make_unique_dp<UserMarksRenderCollection>();
|
||||
renderCollection->reserve(provider->GetUserPointCount());
|
||||
for (size_t i = 0, sz = provider->GetUserPointCount(); i < sz; ++i)
|
||||
{
|
||||
UserPointMark const * mark = provider->GetUserPointMark(i);
|
||||
UserMarkRenderParams renderInfo;
|
||||
renderInfo.m_anchor = mark->GetAnchor();
|
||||
renderInfo.m_depth = mark->GetDepth();
|
||||
renderInfo.m_isVisible = mark->IsVisible();
|
||||
renderInfo.m_pivot = mark->GetPivot();
|
||||
renderInfo.m_pixelOffset = mark->GetPixelOffset();
|
||||
renderInfo.m_runCreationAnim = mark->RunCreationAnim();
|
||||
renderInfo.m_symbolName = mark->GetSymbolName();
|
||||
renderCollection->emplace_back(std::move(renderInfo));
|
||||
}
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<UpdateUserMarkLayerMessage>(layerId, provider),
|
||||
make_unique_dp<UpdateUserMarkLayerMessage>(layerId, std::move(renderCollection)),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ SOURCES += \
|
|||
watch/geometry_processors.cpp \
|
||||
watch/feature_processor.cpp \
|
||||
watch/default_font.cpp \
|
||||
user_mark_builder.cpp \
|
||||
user_mark_generator.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
@ -237,7 +236,6 @@ HEADERS += \
|
|||
watch/brush_info.hpp \
|
||||
watch/geometry_processors.hpp \
|
||||
watch/feature_processor.hpp \
|
||||
user_mark_builder.hpp \
|
||||
user_mark_generator.hpp
|
||||
|
||||
OTHER_FILES += \
|
||||
|
|
|
@ -298,13 +298,14 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
{
|
||||
ref_ptr<FlushUserMarksMessage> msg = message;
|
||||
size_t const layerId = msg->GetLayerId();
|
||||
for (UserMarkShape & shape : msg->GetShapes())
|
||||
TUserMarksRenderData marksRenderData = msg->AcceptRenderData();
|
||||
for (UserMarkRenderData & renderData : marksRenderData)
|
||||
{
|
||||
PrepareBucket(shape.m_state, shape.m_bucket);
|
||||
auto program = m_gpuProgramManager->GetProgram(shape.m_state.GetProgramIndex());
|
||||
auto program3d = m_gpuProgramManager->GetProgram(shape.m_state.GetProgram3dIndex());
|
||||
auto group = make_unique_dp<UserMarkRenderGroup>(layerId, shape.m_state, shape.m_tileKey,
|
||||
std::move(shape.m_bucket));
|
||||
PrepareBucket(renderData.m_state, renderData.m_bucket);
|
||||
auto program = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgramIndex());
|
||||
auto program3d = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgram3dIndex());
|
||||
auto group = make_unique_dp<UserMarkRenderGroup>(layerId, renderData.m_state, renderData.m_tileKey,
|
||||
std::move(renderData.m_bucket));
|
||||
m_userMarkRenderGroups.push_back(std::move(group));
|
||||
m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms));
|
||||
}
|
||||
|
@ -1302,7 +1303,7 @@ void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView)
|
|||
for (auto const & group : m_userMarkRenderGroups)
|
||||
{
|
||||
ASSERT(group.get() != nullptr, ());
|
||||
if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end())
|
||||
//if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end())
|
||||
{
|
||||
if (!group->CanBeClipped() || screenRect.IsIntersect(group->GetTileKey().GetGlobalRect()))
|
||||
RenderSingleGroup(modelView, make_ref(group));
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
ClearUserMarkLayer,
|
||||
ChangeUserMarkLayerVisibility,
|
||||
UpdateUserMarkLayer,
|
||||
InvalidateUserMarks,
|
||||
FlushUserMarks,
|
||||
GuiLayerRecached,
|
||||
GuiRecache,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "drape_frontend/selection_shape.hpp"
|
||||
#include "drape_frontend/tile_utils.hpp"
|
||||
#include "drape_frontend/traffic_generator.hpp"
|
||||
#include "drape_frontend/user_mark_generator.hpp"
|
||||
#include "drape_frontend/user_mark_shapes.hpp"
|
||||
#include "drape_frontend/user_marks_provider.hpp"
|
||||
|
||||
|
@ -237,62 +238,47 @@ private:
|
|||
class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage
|
||||
{
|
||||
public:
|
||||
UpdateUserMarkLayerMessage(size_t layerId, UserMarksProvider * provider)
|
||||
UpdateUserMarkLayerMessage(size_t layerId, drape_ptr<UserMarksRenderCollection> && renderParams)
|
||||
: BaseUserMarkLayerMessage(layerId)
|
||||
, m_provider(provider)
|
||||
{
|
||||
m_provider->IncrementCounter();
|
||||
}
|
||||
, m_renderParams(std::move(renderParams))
|
||||
{}
|
||||
|
||||
~UpdateUserMarkLayerMessage() override
|
||||
{
|
||||
ASSERT(m_inProcess == false, ());
|
||||
m_provider->DecrementCounter();
|
||||
if (m_provider->IsPendingOnDelete() && m_provider->CanBeDeleted())
|
||||
delete m_provider;
|
||||
}
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::UpdateUserMarkLayer; }
|
||||
|
||||
UserMarksProvider const * StartProcess()
|
||||
{
|
||||
m_provider->BeginRead();
|
||||
#ifdef DEBUG
|
||||
m_inProcess = true;
|
||||
#endif
|
||||
return m_provider;
|
||||
}
|
||||
|
||||
void EndProcess()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_inProcess = false;
|
||||
#endif
|
||||
m_provider->EndRead();
|
||||
}
|
||||
drape_ptr<UserMarksRenderCollection> && AcceptRenderParams() { return std::move(m_renderParams); }
|
||||
|
||||
private:
|
||||
UserMarksProvider * m_provider;
|
||||
#ifdef DEBUG
|
||||
bool m_inProcess;
|
||||
#endif
|
||||
drape_ptr<UserMarksRenderCollection> m_renderParams;
|
||||
};
|
||||
|
||||
class FlushUserMarksMessage : public BaseUserMarkLayerMessage
|
||||
{
|
||||
public:
|
||||
FlushUserMarksMessage(size_t layerId, TUserMarkShapes && shapes)
|
||||
FlushUserMarksMessage(size_t layerId, TUserMarksRenderData && renderData)
|
||||
: BaseUserMarkLayerMessage(layerId)
|
||||
, m_shapes(move(shapes))
|
||||
, m_renderData(move(renderData))
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::FlushUserMarks; }
|
||||
bool IsGLContextDependent() const override { return true; }
|
||||
|
||||
TUserMarkShapes & GetShapes() { return m_shapes; }
|
||||
TUserMarksRenderData && AcceptRenderData() { return std::move(m_renderData); }
|
||||
|
||||
private:
|
||||
TUserMarkShapes m_shapes;
|
||||
TUserMarksRenderData m_renderData;
|
||||
};
|
||||
|
||||
class InvalidateUserMarksMessage : public BaseUserMarkLayerMessage
|
||||
{
|
||||
public:
|
||||
InvalidateUserMarksMessage(size_t layerId)
|
||||
: BaseUserMarkLayerMessage(layerId)
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::InvalidateUserMarks; }
|
||||
};
|
||||
|
||||
class GuiLayerRecachedMessage : public Message
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#include "drape_frontend/user_mark_builder.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
UserMarkBuilder::UserMarkBuilder(TFlushFn const & flushFn)
|
||||
: m_flushFn(flushFn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UserMarkBuilder::BuildUserMarks(UserMarksRenderCollection const & marks, MarkIndexesCollection && indexes,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
|
||||
}
|
||||
} // namespace df
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "drape_frontend/user_mark_shapes.hpp"
|
||||
#include "drape_frontend/user_mark_generator.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
class UserMarkBuilder
|
||||
{
|
||||
public:
|
||||
using TFlushFn = function<void(TUserMarkShapes && shapes)>;
|
||||
|
||||
UserMarkBuilder(TFlushFn const & flushFn);
|
||||
|
||||
void BuildUserMarks(MarkGroups const & marks, MarkIndexesGroups && indexes,
|
||||
ref_ptr<dp::TextureManager> textures);
|
||||
private:
|
||||
TFlushFn m_flushFn;
|
||||
};
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
#include "drape_frontend/user_mark_generator.hpp"
|
||||
#include "drape_frontend/map_shape.hpp"
|
||||
#include "drape_frontend/shader_def.hpp"
|
||||
#include "drape_frontend/shape_view_params.hpp"
|
||||
|
||||
#include "drape/utils/vertex_decl.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
UserMarkGenerator::UserMarkGenerator()
|
||||
UserMarkGenerator::UserMarkGenerator(TFlushFn const & flushFn)
|
||||
: m_flushFn(flushFn)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -24,46 +30,91 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId)
|
|||
{
|
||||
auto itGroupIndexes = tileGroups.second->find(groupId);
|
||||
if (itGroupIndexes != tileGroups.second->end())
|
||||
itGroupIndexes->second->clear();
|
||||
{
|
||||
itGroupIndexes->second->m_markIndexes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
UserMarksRenderCollection & marks = *m_marks[groupId];
|
||||
for (size_t markIndex = 0; markIndex < marks.size(); ++markIndex)
|
||||
{
|
||||
for (size_t zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
|
||||
for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
|
||||
{
|
||||
TileKey const tileKey = GetTileKeyByPoint(marks[markIndex].m_pivot, zoomLevel);
|
||||
|
||||
ref_ptr<MarkIndexesGroups> tileGroups;
|
||||
auto itTileGroups = m_marksIndex.find(tileKey);
|
||||
if (itTileGroups == m_marksIndex.end())
|
||||
{
|
||||
auto tileIndexesGroups = make_unique_dp<MarkIndexesGroups>();
|
||||
tileGroups = make_ref(tileIndexesGroups);
|
||||
m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups)));
|
||||
}
|
||||
else
|
||||
{
|
||||
tileGroups = make_ref(itTileGroups->second);
|
||||
}
|
||||
|
||||
ref_ptr<MarkIndexesCollection> groupIndexes;
|
||||
auto itGroupIndexes = tileGroups->find(groupId);
|
||||
if (itGroupIndexes == tileGroups->end())
|
||||
{
|
||||
auto groupMarkIndexes = make_unique_dp<MarkIndexesCollection>();
|
||||
groupIndexes = make_ref(groupMarkIndexes);
|
||||
tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes)));
|
||||
}
|
||||
else
|
||||
{
|
||||
groupIndexes = make_ref(itGroupIndexes->second);
|
||||
}
|
||||
|
||||
groupIndexes->push_back(static_cast<uint32_t>(markIndex));
|
||||
ref_ptr<IndexesCollection> groupIndexes = GetIndexesCollection(tileKey, groupId);
|
||||
groupIndexes->m_markIndexes.push_back(static_cast<uint32_t>(markIndex));
|
||||
}
|
||||
}
|
||||
|
||||
CleanIndex();
|
||||
}
|
||||
|
||||
void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId)
|
||||
{
|
||||
for (auto & tileGroups : m_marksIndex)
|
||||
{
|
||||
auto itGroupIndexes = tileGroups.second->find(groupId);
|
||||
if (itGroupIndexes != tileGroups.second->end())
|
||||
{
|
||||
itGroupIndexes->second->m_lineIndexes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
UserLinesRenderCollection & lines = *m_lines[groupId];
|
||||
for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex)
|
||||
{
|
||||
for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
|
||||
{
|
||||
// TODO: Calculate tiles for the line.
|
||||
std::set<TileKey> tiles;
|
||||
for (size_t i = 0, sz = lines[lineIndex].m_points.size(); i < sz; ++i)
|
||||
{
|
||||
tiles.insert(GetTileKeyByPoint(lines[lineIndex].m_points[i], zoomLevel));
|
||||
}
|
||||
for (auto const & tileKey : tiles)
|
||||
{
|
||||
ref_ptr<IndexesCollection> groupIndexes = GetIndexesCollection(tileKey, groupId);
|
||||
groupIndexes->m_lineIndexes.push_back(static_cast<uint32_t>(lineIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CleanIndex();
|
||||
}
|
||||
|
||||
ref_ptr<IndexesCollection> UserMarkGenerator::GetIndexesCollection(TileKey const & tileKey, GroupID groupId)
|
||||
{
|
||||
ref_ptr<MarkIndexesGroups> tileGroups;
|
||||
auto itTileGroups = m_marksIndex.find(tileKey);
|
||||
if (itTileGroups == m_marksIndex.end())
|
||||
{
|
||||
auto tileIndexesGroups = make_unique_dp<MarkIndexesGroups>();
|
||||
tileGroups = make_ref(tileIndexesGroups);
|
||||
m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups)));
|
||||
}
|
||||
else
|
||||
{
|
||||
tileGroups = make_ref(itTileGroups->second);
|
||||
}
|
||||
|
||||
ref_ptr<IndexesCollection> groupIndexes;
|
||||
auto itGroupIndexes = tileGroups->find(groupId);
|
||||
if (itGroupIndexes == tileGroups->end())
|
||||
{
|
||||
auto groupMarkIndexes = make_unique_dp<IndexesCollection>();
|
||||
groupIndexes = make_ref(groupMarkIndexes);
|
||||
tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes)));
|
||||
}
|
||||
else
|
||||
{
|
||||
groupIndexes = make_ref(itGroupIndexes->second);
|
||||
}
|
||||
|
||||
return groupIndexes;
|
||||
}
|
||||
|
||||
void UserMarkGenerator::CleanIndex()
|
||||
{
|
||||
for (auto tileIt = m_marksIndex.begin(); tileIt != m_marksIndex.end();)
|
||||
{
|
||||
if (tileIt->second->empty())
|
||||
|
@ -73,11 +124,6 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId)
|
|||
}
|
||||
}
|
||||
|
||||
void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UserMarkGenerator::SetGroupVisibility(GroupID groupId, bool isVisible)
|
||||
{
|
||||
m_groupsVisibility[groupId] = isVisible;
|
||||
|
@ -93,63 +139,18 @@ void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_p
|
|||
for (auto & groupPair : indexesGroups)
|
||||
{
|
||||
GroupID groupId = groupPair.first;
|
||||
MarkIndexesCollection & indexes = *groupPair.second;
|
||||
UserMarksRenderCollection const & renderParams = *m_marks[groupId];
|
||||
MarkIndexesCollection const & indexes = groupPair.second->m_markIndexes;
|
||||
|
||||
if (!m_groupsVisibility[groupId])
|
||||
continue;
|
||||
//if (!m_groupsVisibility[groupId])
|
||||
// continue;
|
||||
|
||||
UserMarkBatcherKey batcherKey(tileKey, groupId);
|
||||
m_batchersPool->ReserveBatcher(batcherKey);
|
||||
ref_ptr<dp::Batcher> batcher = m_batchersPool->GetBatcher(batcherKey);
|
||||
TUserMarksRenderData renderData;
|
||||
UserMarkShape::Draw(tileKey, textures, renderParams, indexes, renderData);
|
||||
|
||||
dp::TextureManager::SymbolRegion region;
|
||||
|
||||
uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad;
|
||||
uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad;
|
||||
buffer_vector<UPV, 128> buffer;
|
||||
buffer.reserve(vertexCount);
|
||||
|
||||
for (auto const markIndex : indexes)
|
||||
{
|
||||
UserMarkRenderInfo const & renderInfo = m_marks[markIndex];
|
||||
if (!renderInfo.m_isVisible)
|
||||
continue;
|
||||
textures->GetSymbolRegion(renderInfo.m_symbolName, region);
|
||||
m2::RectF const & texRect = region.GetTexRect();
|
||||
m2::PointF const pxSize = region.GetPixelSize();
|
||||
dp::Anchor const anchor = renderInfo.m_anchor;
|
||||
m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar);
|
||||
glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth);
|
||||
bool const runAnim = renderInfo.m_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);
|
||||
|
||||
uint32_t const kMaxSize = 65000;
|
||||
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
|
||||
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
{
|
||||
outShapes.emplace_back(UserMarkShape(state, move(b), key));
|
||||
});
|
||||
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
|
||||
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
|
||||
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
|
||||
m_flushFn(groupId, std::move(renderData));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -16,47 +16,24 @@
|
|||
|
||||
namespace df
|
||||
{
|
||||
struct UserMarkRenderInfo
|
||||
{
|
||||
m2::PointD m_pivot;
|
||||
m2::PointD m_pixelOffset;
|
||||
std::string m_symbolName;
|
||||
dp::Anchor m_anchor;
|
||||
float m_depth;
|
||||
bool m_runCreationAnim;
|
||||
bool m_isVisible;
|
||||
};
|
||||
|
||||
struct LineLayer
|
||||
{
|
||||
dp::Color m_color;
|
||||
float m_width;
|
||||
float m_depth;
|
||||
};
|
||||
|
||||
struct UserLineRenderInfo
|
||||
{
|
||||
std::vector<LineLayer> m_layers;
|
||||
std::vector<m2::PointD> m_points;
|
||||
};
|
||||
|
||||
using UserMarksRenderCollection = std::vector<UserMarkRenderInfo>;
|
||||
using UserLinesRenderCollection = std::vector<UserLineRenderInfo>;
|
||||
|
||||
using GroupID = uint32_t;
|
||||
|
||||
using MarkGroups = std::map<GroupID, drape_ptr<UserMarksRenderCollection>>;
|
||||
using LineGroups = std::map<GroupID, drape_ptr<UserLinesRenderCollection>>;
|
||||
|
||||
using MarkIndexesCollection = std::vector<uint32_t>;
|
||||
using MarkIndexesGroups = std::map<GroupID, drape_ptr<MarkIndexesCollection>>;
|
||||
struct IndexesCollection
|
||||
{
|
||||
MarkIndexesCollection m_markIndexes;
|
||||
LineIndexesCollection m_lineIndexes;
|
||||
};
|
||||
|
||||
using MarkIndexesGroups = std::map<GroupID, drape_ptr<IndexesCollection>>;
|
||||
using MarksIndex = std::map<TileKey, drape_ptr<MarkIndexesGroups>>;
|
||||
|
||||
class UserMarkGenerator
|
||||
{
|
||||
public:
|
||||
using TFlushFn = function<void(TUserMarkShapes && shapes)>;
|
||||
using TFlushFn = function<void(GroupID, TUserMarksRenderData && renderData)>;
|
||||
|
||||
UserMarkGenerator(TFlushFn const & flushFn);
|
||||
|
||||
|
@ -67,38 +44,12 @@ public:
|
|||
|
||||
void GenerateUserMarksGeometry(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures);
|
||||
|
||||
private:
|
||||
TFlushFn m_flushFn;
|
||||
private:
|
||||
void UpdateMarksIndex(GroupID groupId);
|
||||
void UpdateLinesIndex(GroupID groupId);
|
||||
|
||||
struct UserMarkBatcherKey
|
||||
{
|
||||
UserMarkBatcherKey() = default;
|
||||
UserMarkBatcherKey(TileKey const & tileKey, GroupID groupId)
|
||||
: m_tileKey(tileKey)
|
||||
, m_groupId(groupId)
|
||||
{}
|
||||
GroupID m_groupId;
|
||||
TileKey m_tileKey;
|
||||
};
|
||||
|
||||
struct UserMarkBatcherKeyComparator
|
||||
{
|
||||
bool operator() (UserMarkBatcherKey const & lhs, UserMarkBatcherKey const & rhs) const
|
||||
{
|
||||
if (lhs.m_groupId == rhs.m_groupId)
|
||||
return lhs.m_tileKey.LessStrict(rhs.m_tileKey);
|
||||
return lhs.m_groupId < rhs.m_groupId;
|
||||
}
|
||||
};
|
||||
|
||||
void FlushGeometry(UserMarkBatcherKey const & key, dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && buffer);
|
||||
|
||||
drape_ptr<BatchersPool<UserMarkBatcherKey, UserMarkBatcherKeyComparator>> m_batchersPool;
|
||||
TFlushFn m_flushRenderDataFn;
|
||||
ref_ptr<IndexesCollection> GetIndexesCollection(TileKey const & tileKey, GroupID groupId);
|
||||
void CleanIndex();
|
||||
|
||||
std::map<GroupID, bool> m_groupsVisibility;
|
||||
|
||||
|
@ -106,6 +57,8 @@ private:
|
|||
LineGroups m_lines;
|
||||
|
||||
MarksIndex m_marksIndex;
|
||||
|
||||
TFlushFn m_flushFn;
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -77,84 +77,7 @@ struct UserPointVertex : gpu::BaseVertex
|
|||
};
|
||||
|
||||
using UPV = UserPointVertex;
|
||||
|
||||
void CacheUserPoints(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures,
|
||||
TUserMarkShapes & outShapes)
|
||||
{
|
||||
size_t markCount = provider->GetUserPointCount();
|
||||
if (markCount == 0)
|
||||
return;
|
||||
|
||||
int const kZoomLevel = 10;
|
||||
map<TileKey, vector<UserPointMark const *>> marks;
|
||||
for (size_t i = 0; i < markCount; ++i)
|
||||
{
|
||||
UserPointMark const * userMark = provider->GetUserPointMark(i);
|
||||
if (!userMark->IsVisible())
|
||||
continue;
|
||||
TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel);
|
||||
marks[tileKey].push_back(userMark);
|
||||
}
|
||||
|
||||
for (auto it = marks.begin(); it != marks.end(); ++it)
|
||||
{
|
||||
TileKey const & key = it->first;
|
||||
m2::PointD const tileCenter = key.GetGlobalRect().Center();
|
||||
|
||||
sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2)
|
||||
{
|
||||
return v1->GetPivot().y < v2->GetPivot().y;
|
||||
});
|
||||
|
||||
dp::TextureManager::SymbolRegion region;
|
||||
|
||||
uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad;
|
||||
uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad;
|
||||
buffer_vector<UPV, 128> buffer;
|
||||
buffer.reserve(vertexCount);
|
||||
|
||||
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);
|
||||
|
||||
uint32_t const kMaxSize = 65000;
|
||||
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
|
||||
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
{
|
||||
outShapes.emplace_back(UserMarkShape(state, move(b), key));
|
||||
});
|
||||
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
|
||||
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
|
||||
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures,
|
||||
TUserMarkShapes & outShapes)
|
||||
{
|
||||
|
@ -186,7 +109,7 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManag
|
|||
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
{
|
||||
outShapes.emplace_back(UserMarkShape(state, move(b), key));
|
||||
outShapes.emplace_back(UserMarksRenderData(state, move(b), key));
|
||||
});
|
||||
for (auto const & lineData : it->second)
|
||||
{
|
||||
|
@ -209,15 +132,77 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManag
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
} // namespace
|
||||
|
||||
TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures)
|
||||
// static
|
||||
void UserMarkShape::Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
|
||||
UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes,
|
||||
TUserMarksRenderData & renderData)
|
||||
{
|
||||
uint32_t const vertexCount = static_cast<uint32_t>(indexes.size()) * dp::Batcher::VertexPerQuad;
|
||||
uint32_t const indicesCount = static_cast<uint32_t>(indexes.size()) * dp::Batcher::IndexPerQuad;
|
||||
buffer_vector<UPV, 128> buffer;
|
||||
buffer.reserve(vertexCount);
|
||||
|
||||
// TODO: Sort once on render params receiving.
|
||||
MarkIndexesCollection sortedIndexes = indexes;
|
||||
sort(sortedIndexes.begin(), sortedIndexes.end(), [&renderParams](uint32_t ind1, uint32_t ind2)
|
||||
{
|
||||
return renderParams[ind1].m_pivot.y > renderParams[ind2].m_pivot.y;
|
||||
});
|
||||
|
||||
dp::TextureManager::SymbolRegion region;
|
||||
for (auto const markIndex : sortedIndexes)
|
||||
{
|
||||
UserMarkRenderParams const & renderInfo = renderParams[markIndex];
|
||||
if (!renderInfo.m_isVisible)
|
||||
continue;
|
||||
textures->GetSymbolRegion(renderInfo.m_symbolName, region);
|
||||
m2::RectF const & texRect = region.GetTexRect();
|
||||
m2::PointF const pxSize = region.GetPixelSize();
|
||||
dp::Anchor const anchor = renderInfo.m_anchor;
|
||||
m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar);
|
||||
glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth);
|
||||
bool const runAnim = renderInfo.m_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 = renderInfo.m_pixelOffset;
|
||||
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);
|
||||
|
||||
uint32_t const kMaxSize = 65000;
|
||||
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
|
||||
dp::SessionGuard guard(batcher, [&tileKey, &renderData](dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
{
|
||||
renderData.emplace_back(UserMarkRenderData(state, move(b), tileKey));
|
||||
});
|
||||
|
||||
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
|
||||
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
|
||||
|
||||
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
|
||||
}
|
||||
|
||||
// static
|
||||
void UserLineShape::Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
|
||||
UserLinesRenderCollection const & renderParams, LineIndexesCollection const & indexes,
|
||||
TUserMarksRenderData & renderData)
|
||||
{
|
||||
TUserMarkShapes shapes;
|
||||
CacheUserPoints(provider, textures, shapes);
|
||||
CacheUserLines(provider, textures, shapes);
|
||||
return shapes;
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -13,21 +13,64 @@
|
|||
namespace df
|
||||
{
|
||||
|
||||
struct UserMarkShape
|
||||
struct UserMarkRenderParams
|
||||
{
|
||||
m2::PointD m_pivot;
|
||||
m2::PointD m_pixelOffset;
|
||||
std::string m_symbolName;
|
||||
dp::Anchor m_anchor;
|
||||
float m_depth;
|
||||
bool m_runCreationAnim;
|
||||
bool m_isVisible;
|
||||
};
|
||||
|
||||
struct LineLayer
|
||||
{
|
||||
dp::Color m_color;
|
||||
float m_width;
|
||||
float m_depth;
|
||||
};
|
||||
|
||||
struct UserLineRenderParams
|
||||
{
|
||||
std::vector<LineLayer> m_layers;
|
||||
std::vector<m2::PointD> m_points;
|
||||
};
|
||||
|
||||
using UserMarksRenderCollection = std::vector<UserMarkRenderParams>;
|
||||
using UserLinesRenderCollection = std::vector<UserLineRenderParams>;
|
||||
|
||||
using MarkIndexesCollection = std::vector<uint32_t>;
|
||||
using LineIndexesCollection = std::vector<uint32_t>;
|
||||
|
||||
struct UserMarkRenderData
|
||||
{
|
||||
UserMarkRenderData(dp::GLState const & state,
|
||||
drape_ptr<dp::RenderBucket> && bucket,
|
||||
TileKey const & tileKey)
|
||||
: m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey)
|
||||
{}
|
||||
|
||||
dp::GLState m_state;
|
||||
drape_ptr<dp::RenderBucket> m_bucket;
|
||||
TileKey m_tileKey;
|
||||
|
||||
UserMarkShape(dp::GLState const & state, drape_ptr<dp::RenderBucket> && bucket,
|
||||
TileKey const & tileKey)
|
||||
: m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey)
|
||||
{}
|
||||
};
|
||||
|
||||
using TUserMarkShapes = vector<UserMarkShape>;
|
||||
using TUserMarksRenderData = std::vector<UserMarkRenderData>;
|
||||
|
||||
TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider,
|
||||
ref_ptr<dp::TextureManager> textures);
|
||||
class UserMarkShape
|
||||
{
|
||||
public:
|
||||
static void Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
|
||||
UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes,
|
||||
TUserMarksRenderData & renderData);
|
||||
};
|
||||
|
||||
class UserLineShape
|
||||
{
|
||||
public:
|
||||
static void Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures, UserLinesRenderCollection const & renderParams,
|
||||
LineIndexesCollection const & indexes, TUserMarksRenderData & renderData);
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "drape_frontend/drape_engine.hpp"
|
||||
#include "drape_frontend/tile_key.hpp"
|
||||
#include "drape_frontend/user_mark_shapes.hpp"
|
||||
|
||||
#include "base/scope_guard.hpp"
|
||||
#include "base/macros.hpp"
|
||||
|
|
Loading…
Add table
Reference in a new issue