forked from organicmaps/organicmaps
[drape] Optimized route rendering
This commit is contained in:
parent
d882030a9b
commit
e0ff5564b8
3 changed files with 163 additions and 95 deletions
|
@ -435,8 +435,14 @@ void RouteRenderer::RenderSubroute(ref_ptr<dp::GraphicsContext> context, ref_ptr
|
|||
mng->GetParamsSetter()->Apply(context, prg, params);
|
||||
|
||||
// Render buckets.
|
||||
for (auto const & bucket : subrouteData->m_renderProperty.m_buckets)
|
||||
bucket->Render(context, state.GetDrawAsLine());
|
||||
auto const & clipRect = screen.ClipRect();
|
||||
CHECK_EQUAL(subrouteData->m_renderProperty.m_buckets.size(),
|
||||
subrouteData->m_renderProperty.m_boundingBoxes.size(), ());
|
||||
for (size_t i = 0; i < subrouteData->m_renderProperty.m_buckets.size(); ++i)
|
||||
{
|
||||
if (subrouteData->m_renderProperty.m_boundingBoxes[i].IsIntersect(clipRect))
|
||||
subrouteData->m_renderProperty.m_buckets[i]->Render(context, state.GetDrawAsLine());
|
||||
}
|
||||
}
|
||||
|
||||
void RouteRenderer::RenderSubrouteArrows(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
|
@ -470,8 +476,15 @@ void RouteRenderer::RenderSubrouteArrows(ref_ptr<dp::GraphicsContext> context, r
|
|||
prg->Bind();
|
||||
dp::ApplyState(context, prg, state);
|
||||
mng->GetParamsSetter()->Apply(context, prg, params);
|
||||
for (auto const & bucket : subrouteInfo.m_arrowsData->m_renderProperty.m_buckets)
|
||||
bucket->Render(context, state.GetDrawAsLine());
|
||||
|
||||
auto const & clipRect = screen.ClipRect();
|
||||
CHECK_EQUAL(subrouteInfo.m_arrowsData->m_renderProperty.m_buckets.size(),
|
||||
subrouteInfo.m_arrowsData->m_renderProperty.m_boundingBoxes.size(), ());
|
||||
for (size_t i = 0; i < subrouteInfo.m_arrowsData->m_renderProperty.m_buckets.size(); ++i)
|
||||
{
|
||||
if (subrouteInfo.m_arrowsData->m_renderProperty.m_boundingBoxes[i].IsIntersect(clipRect))
|
||||
subrouteInfo.m_arrowsData->m_renderProperty.m_buckets[i]->Render(context, state.GetDrawAsLine());
|
||||
}
|
||||
}
|
||||
|
||||
void RouteRenderer::RenderSubrouteMarkers(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
#include "drape/glsl_types.hpp"
|
||||
#include "drape/texture_manager.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/math.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
|
@ -116,7 +119,7 @@ float SideByNormal(glsl::vec2 const & normal, bool isLeft)
|
|||
|
||||
void GenerateJoinsTriangles(glsl::vec3 const & pivot, std::vector<glsl::vec2> const & normals,
|
||||
glsl::vec4 const & color, glsl::vec2 const & length, bool isLeft,
|
||||
RouteShape::TGeometryBuffer & joinsGeometry)
|
||||
RouteShape::GeometryBuffer & joinsGeometry)
|
||||
{
|
||||
size_t const trianglesCount = normals.size() / 3;
|
||||
for (size_t j = 0; j < trianglesCount; j++)
|
||||
|
@ -125,9 +128,9 @@ void GenerateJoinsTriangles(glsl::vec3 const & pivot, std::vector<glsl::vec2> co
|
|||
glsl::vec3 const len2 = glsl::vec3(length.x, length.y, SideByNormal(normals[3 * j + 1], isLeft));
|
||||
glsl::vec3 const len3 = glsl::vec3(length.x, length.y, SideByNormal(normals[3 * j + 2], isLeft));
|
||||
|
||||
joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j], len1, color));
|
||||
joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 1], len2, color));
|
||||
joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 2], len3, color));
|
||||
joinsGeometry.emplace_back(RouteShape::RV(pivot, normals[3 * j], len1, color));
|
||||
joinsGeometry.emplace_back(RouteShape::RV(pivot, normals[3 * j + 1], len2, color));
|
||||
joinsGeometry.emplace_back(RouteShape::RV(pivot, normals[3 * j + 2], len3, color));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,17 +147,17 @@ glsl::vec2 GetUV(m2::RectF const & texRect, glsl::vec2 const & uv)
|
|||
|
||||
void GenerateArrowsTriangles(glsl::vec4 const & pivot, std::vector<glsl::vec2> const & normals,
|
||||
m2::RectF const & texRect, std::vector<glsl::vec2> const & uv,
|
||||
bool normalizedUV, RouteShape::TArrowGeometryBuffer & joinsGeometry)
|
||||
bool normalizedUV, RouteShape::ArrowGeometryBuffer & joinsGeometry)
|
||||
{
|
||||
size_t const trianglesCount = normals.size() / 3;
|
||||
for (size_t j = 0; j < trianglesCount; j++)
|
||||
{
|
||||
joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j]) : uv[3 * j]));
|
||||
joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j + 1],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j + 1]) : uv[3 * j + 1]));
|
||||
joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j + 2],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j + 2]) : uv[3 * j + 2]));
|
||||
joinsGeometry.emplace_back(RouteShape::AV(pivot, normals[3 * j],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j]) : uv[3 * j]));
|
||||
joinsGeometry.emplace_back(RouteShape::AV(pivot, normals[3 * j + 1],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j + 1]) : uv[3 * j + 1]));
|
||||
joinsGeometry.emplace_back(RouteShape::AV(pivot, normals[3 * j + 2],
|
||||
normalizedUV ? GetUV(texRect, uv[3 * j + 2]) : uv[3 * j + 2]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +181,7 @@ void Subroute::AddStyle(SubrouteStyle const & style)
|
|||
|
||||
void RouteShape::PrepareGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
||||
std::vector<glsl::vec4> const & segmentsColors, float baseDepth,
|
||||
TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry)
|
||||
std::vector<GeometryBufferData<GeometryBuffer>> & geometryBufferData)
|
||||
{
|
||||
ASSERT(path.size() > 1, ());
|
||||
|
||||
|
@ -195,13 +198,24 @@ void RouteShape::PrepareGeometry(std::vector<m2::PointD> const & path, m2::Point
|
|||
for (auto const & segment : segments)
|
||||
length += glsl::length(segment.m_points[EndPoint] - segment.m_points[StartPoint]);
|
||||
|
||||
geometryBufferData.emplace_back(GeometryBufferData<GeometryBuffer>());
|
||||
|
||||
uint32_t constexpr kMinVertices = 5000;
|
||||
double constexpr kMinExtent = MercatorBounds::kRangeX / (1 << 10);
|
||||
|
||||
float depth = baseDepth;
|
||||
float const depthStep = kRouteDepth / (1 + segments.size());
|
||||
for (auto i = static_cast<int>(segments.size() - 1); i >= 0; i--)
|
||||
{
|
||||
auto & geomBufferData = geometryBufferData.back();
|
||||
auto & geometry = geomBufferData.m_geometry;
|
||||
|
||||
UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr,
|
||||
(i < static_cast<int>(segments.size()) - 1) ? &segments[i + 1] : nullptr);
|
||||
|
||||
geomBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[StartPoint]));
|
||||
geomBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[EndPoint]));
|
||||
|
||||
// Generate main geometry.
|
||||
m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]),
|
||||
pivot, kShapeCoordScalar);
|
||||
|
@ -224,23 +238,25 @@ void RouteShape::PrepareGeometry(std::vector<m2::PointD> const & path, m2::Point
|
|||
float const projRightStart = -segments[i].m_rightWidthScalar[StartPoint].y;
|
||||
float const projRightEnd = segments[i].m_rightWidthScalar[EndPoint].y;
|
||||
|
||||
geometry.push_back(RV(startPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(startLength, 0, kCenter), segments[i].m_color));
|
||||
geometry.push_back(RV(startPivot, leftNormalStart,
|
||||
glsl::vec3(startLength, projLeftStart, kLeftSide), segments[i].m_color));
|
||||
geometry.push_back(RV(endPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(length, 0, kCenter), segments[i].m_color));
|
||||
geometry.push_back(RV(endPivot, leftNormalEnd,
|
||||
glsl::vec3(length, projLeftEnd, kLeftSide), segments[i].m_color));
|
||||
geometry.emplace_back(RV(startPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(startLength, 0, kCenter), segments[i].m_color));
|
||||
geometry.emplace_back(RV(startPivot, leftNormalStart,
|
||||
glsl::vec3(startLength, projLeftStart, kLeftSide), segments[i].m_color));
|
||||
geometry.emplace_back(RV(endPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(length, 0, kCenter), segments[i].m_color));
|
||||
geometry.emplace_back(RV(endPivot, leftNormalEnd,
|
||||
glsl::vec3(length, projLeftEnd, kLeftSide), segments[i].m_color));
|
||||
|
||||
geometry.push_back(RV(startPivot, rightNormalStart,
|
||||
glsl::vec3(startLength, projRightStart, kRightSide), segments[i].m_color));
|
||||
geometry.push_back(RV(startPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(startLength, 0, kCenter), segments[i].m_color));
|
||||
geometry.push_back(RV(endPivot, rightNormalEnd,
|
||||
glsl::vec3(length, projRightEnd, kRightSide), segments[i].m_color));
|
||||
geometry.push_back(RV(endPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(length, 0, kCenter), segments[i].m_color));
|
||||
geometry.emplace_back(RV(startPivot, rightNormalStart,
|
||||
glsl::vec3(startLength, projRightStart, kRightSide), segments[i].m_color));
|
||||
geometry.emplace_back(RV(startPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(startLength, 0, kCenter), segments[i].m_color));
|
||||
geometry.emplace_back(RV(endPivot, rightNormalEnd,
|
||||
glsl::vec3(length, projRightEnd, kRightSide), segments[i].m_color));
|
||||
geometry.emplace_back(RV(endPivot, glsl::vec2(0, 0),
|
||||
glsl::vec3(length, 0, kCenter), segments[i].m_color));
|
||||
|
||||
auto & joinsGeometry = geomBufferData.m_joinsGeometry;
|
||||
|
||||
// Generate joins.
|
||||
if (segments[i].m_generateJoin && i < static_cast<int>(segments.size()) - 1)
|
||||
|
@ -287,13 +303,18 @@ void RouteShape::PrepareGeometry(std::vector<m2::PointD> const & path, m2::Point
|
|||
true, joinsGeometry);
|
||||
}
|
||||
|
||||
auto const verticesCount = geomBufferData.m_geometry.size() + geomBufferData.m_joinsGeometry.size();
|
||||
auto const extent = std::max(geomBufferData.m_boundingBox.SizeX(), geomBufferData.m_boundingBox.SizeY());
|
||||
if (verticesCount > kMinVertices && extent > kMinExtent)
|
||||
geometryBufferData.emplace_back(GeometryBufferData<GeometryBuffer>());
|
||||
|
||||
length = startLength;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteShape::PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
||||
m2::RectF const & texRect, float depthStep, float depth,
|
||||
TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry)
|
||||
GeometryBufferData<ArrowGeometryBuffer> & geometryBufferData)
|
||||
{
|
||||
ASSERT(path.size() > 1, ());
|
||||
|
||||
|
@ -310,9 +331,14 @@ void RouteShape::PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::
|
|||
float const depthInc = depthStep / (segments.size() + 1);
|
||||
for (size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
auto & geometry = geometryBufferData.m_geometry;
|
||||
|
||||
UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr,
|
||||
(i < segments.size() - 1) ? &segments[i + 1] : nullptr);
|
||||
|
||||
geometryBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[StartPoint]));
|
||||
geometryBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[EndPoint]));
|
||||
|
||||
// Generate main geometry.
|
||||
m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]),
|
||||
pivot, kShapeCoordScalar);
|
||||
|
@ -332,15 +358,17 @@ void RouteShape::PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::
|
|||
glsl::vec2 const uvLeft = GetUV(tr, 0.5f, 0.0f);
|
||||
glsl::vec2 const uvRight = GetUV(tr, 0.5f, 1.0f);
|
||||
|
||||
geometry.push_back(AV(startPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.push_back(AV(startPivot, leftNormalStart, uvLeft));
|
||||
geometry.push_back(AV(endPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.push_back(AV(endPivot, leftNormalEnd, uvLeft));
|
||||
geometry.emplace_back(AV(startPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.emplace_back(AV(startPivot, leftNormalStart, uvLeft));
|
||||
geometry.emplace_back(AV(endPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.emplace_back(AV(endPivot, leftNormalEnd, uvLeft));
|
||||
|
||||
geometry.push_back(AV(startPivot, rightNormalStart, uvRight));
|
||||
geometry.push_back(AV(startPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.push_back(AV(endPivot, rightNormalEnd, uvRight));
|
||||
geometry.push_back(AV(endPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.emplace_back(AV(startPivot, rightNormalStart, uvRight));
|
||||
geometry.emplace_back(AV(startPivot, glsl::vec2(0, 0), uvCenter));
|
||||
geometry.emplace_back(AV(endPivot, rightNormalEnd, uvRight));
|
||||
geometry.emplace_back(AV(endPivot, glsl::vec2(0, 0), uvCenter));
|
||||
|
||||
auto & joinsGeometry = geometryBufferData.m_joinsGeometry;
|
||||
|
||||
// Generate joins.
|
||||
if (segments[i].m_generateJoin && i < segments.size() - 1)
|
||||
|
@ -411,7 +439,7 @@ void RouteShape::PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::
|
|||
|
||||
void RouteShape::PrepareMarkersGeometry(std::vector<SubrouteMarker> const & markers,
|
||||
m2::PointD const & pivot, float baseDepth,
|
||||
TMarkersGeometryBuffer & geometry)
|
||||
MarkersGeometryBuffer & geometry)
|
||||
{
|
||||
ASSERT(!markers.empty(), ());
|
||||
|
||||
|
@ -488,8 +516,7 @@ void RouteShape::CacheRouteArrows(ref_ptr<dp::GraphicsContext> context,
|
|||
std::vector<ArrowBorders> const & borders, double baseDepthIndex,
|
||||
SubrouteArrowsData & routeArrowsData)
|
||||
{
|
||||
TArrowGeometryBuffer geometry;
|
||||
TArrowGeometryBuffer joinsGeometry;
|
||||
GeometryBufferData<ArrowGeometryBuffer> geometryData;
|
||||
dp::TextureManager::SymbolRegion region;
|
||||
GetArrowTextureRegion(mng, region);
|
||||
auto state = CreateRenderState(gpu::Program::RouteArrow, DepthLayer::GeometryLayer);
|
||||
|
@ -504,18 +531,23 @@ void RouteShape::CacheRouteArrows(ref_ptr<dp::GraphicsContext> context,
|
|||
std::vector<m2::PointD> points = CalculatePoints(polyline, b.m_startDistance, b.m_endDistance);
|
||||
ASSERT_LESS_OR_EQUAL(points.size(), polyline.GetSize(), ());
|
||||
PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depthStep,
|
||||
depth, geometry, joinsGeometry);
|
||||
depth, geometryData);
|
||||
}
|
||||
|
||||
BatchGeometry(context, state, make_ref(geometry.data()), static_cast<uint32_t>(geometry.size()),
|
||||
make_ref(joinsGeometry.data()), static_cast<uint32_t>(joinsGeometry.size()),
|
||||
AV::GetBindingInfo(), routeArrowsData.m_renderProperty);
|
||||
double constexpr kBoundingBoxScale = 1.2;
|
||||
geometryData.m_boundingBox.Scale(kBoundingBoxScale);
|
||||
|
||||
BatchGeometry(context, state, make_ref(geometryData.m_geometry.data()),
|
||||
static_cast<uint32_t>(geometryData.m_geometry.size()),
|
||||
make_ref(geometryData.m_joinsGeometry.data()),
|
||||
static_cast<uint32_t>(geometryData.m_joinsGeometry.size()),
|
||||
geometryData.m_boundingBox, AV::GetBindingInfo(),
|
||||
routeArrowsData.m_renderProperty);
|
||||
}
|
||||
|
||||
drape_ptr<df::SubrouteData> RouteShape::CacheRoute(ref_ptr<dp::GraphicsContext> context,
|
||||
dp::DrapeID subrouteId,
|
||||
SubrouteConstPtr subroute, size_t styleIndex,
|
||||
int recacheId,
|
||||
dp::DrapeID subrouteId, SubrouteConstPtr subroute,
|
||||
size_t styleIndex, int recacheId,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
size_t startIndex;
|
||||
|
@ -565,28 +597,34 @@ drape_ptr<df::SubrouteData> RouteShape::CacheRoute(ref_ptr<dp::GraphicsContext>
|
|||
subrouteData->m_recacheId = recacheId;
|
||||
subrouteData->m_distanceOffset = subroute->m_polyline.GetLength(startIndex);
|
||||
|
||||
TGeometryBuffer geometry;
|
||||
TGeometryBuffer joinsGeometry;
|
||||
std::vector<GeometryBufferData<GeometryBuffer>> geometryBufferData;
|
||||
PrepareGeometry(points, subrouteData->m_pivot, segmentsColors,
|
||||
static_cast<float>(subroute->m_baseDepthIndex * kDepthPerSubroute),
|
||||
geometry, joinsGeometry);
|
||||
geometryBufferData);
|
||||
|
||||
auto state = CreateRenderState(subroute->m_style[styleIndex].m_pattern.m_isDashed ?
|
||||
gpu::Program::RouteDash : gpu::Program::Route, DepthLayer::GeometryLayer);
|
||||
state.SetColorTexture(textures->GetSymbolsTexture());
|
||||
|
||||
BatchGeometry(context, state, make_ref(geometry.data()), static_cast<uint32_t>(geometry.size()),
|
||||
make_ref(joinsGeometry.data()), static_cast<uint32_t>(joinsGeometry.size()),
|
||||
RV::GetBindingInfo(), subrouteData->m_renderProperty);
|
||||
double constexpr kBoundingBoxScale = 1.2;
|
||||
for (auto & data : geometryBufferData)
|
||||
{
|
||||
data.m_boundingBox.Scale(kBoundingBoxScale);
|
||||
BatchGeometry(context, state, make_ref(data.m_geometry.data()),
|
||||
static_cast<uint32_t>(data.m_geometry.size()),
|
||||
make_ref(data.m_joinsGeometry.data()),
|
||||
static_cast<uint32_t>(data.m_joinsGeometry.size()),
|
||||
data.m_boundingBox, RV::GetBindingInfo(),
|
||||
subrouteData->m_renderProperty);
|
||||
}
|
||||
|
||||
|
||||
return subrouteData;
|
||||
}
|
||||
|
||||
drape_ptr<df::SubrouteMarkersData> RouteShape::CacheMarkers(ref_ptr<dp::GraphicsContext> context,
|
||||
dp::DrapeID subrouteId,
|
||||
SubrouteConstPtr subroute,
|
||||
int recacheId,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
dp::DrapeID subrouteId, SubrouteConstPtr subroute,
|
||||
int recacheId, ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
if (subroute->m_markers.empty())
|
||||
return nullptr;
|
||||
|
@ -596,7 +634,7 @@ drape_ptr<df::SubrouteMarkersData> RouteShape::CacheMarkers(ref_ptr<dp::Graphics
|
|||
markersData->m_pivot = subroute->m_polyline.GetLimitRect().Center();
|
||||
markersData->m_recacheId = recacheId;
|
||||
|
||||
TMarkersGeometryBuffer geometry;
|
||||
MarkersGeometryBuffer geometry;
|
||||
auto const depth = static_cast<float>(subroute->m_baseDepthIndex * kDepthPerSubroute + kMarkersDepth);
|
||||
PrepareMarkersGeometry(subroute->m_markers, markersData->m_pivot, depth, geometry);
|
||||
if (geometry.empty())
|
||||
|
@ -628,19 +666,27 @@ drape_ptr<df::SubrouteMarkersData> RouteShape::CacheMarkers(ref_ptr<dp::Graphics
|
|||
void RouteShape::BatchGeometry(ref_ptr<dp::GraphicsContext> context, dp::RenderState const & state,
|
||||
ref_ptr<void> geometry, uint32_t geomSize,
|
||||
ref_ptr<void> joinsGeometry, uint32_t joinsGeomSize,
|
||||
dp::BindingInfo const & bindingInfo, RouteRenderProperty & property)
|
||||
m2::RectD const & boundingBox, dp::BindingInfo const & bindingInfo,
|
||||
RouteRenderProperty & property)
|
||||
{
|
||||
size_t const verticesCount = geomSize + joinsGeomSize;
|
||||
auto verticesCount = geomSize + joinsGeomSize;
|
||||
if (verticesCount == 0)
|
||||
return;
|
||||
|
||||
uint32_t const kBatchSize = 5000;
|
||||
dp::Batcher batcher(kBatchSize, kBatchSize);
|
||||
uint32_t constexpr kMinBatchSize = 100;
|
||||
uint32_t constexpr kMaxBatchSize = 65000;
|
||||
uint32_t constexpr kIndicesScalar = 2;
|
||||
|
||||
verticesCount = base::clamp(verticesCount, kMinBatchSize, kMaxBatchSize);
|
||||
auto const indicesCount = base::clamp(verticesCount * kIndicesScalar, kMinBatchSize, kMaxBatchSize);
|
||||
|
||||
dp::Batcher batcher(indicesCount, verticesCount);
|
||||
batcher.SetBatcherHash(static_cast<uint64_t>(BatcherBucket::Routing));
|
||||
dp::SessionGuard guard(context, batcher, [&property](dp::RenderState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
dp::SessionGuard guard(context, batcher, [&property, &boundingBox](dp::RenderState const & state,
|
||||
drape_ptr<dp::RenderBucket> && b)
|
||||
{
|
||||
property.m_buckets.push_back(std::move(b));
|
||||
property.m_boundingBoxes.push_back(boundingBox);
|
||||
property.m_state = state;
|
||||
});
|
||||
|
||||
|
|
|
@ -50,10 +50,6 @@ enum class RouteType : uint8_t
|
|||
|
||||
struct RoutePattern
|
||||
{
|
||||
bool m_isDashed = false;
|
||||
double m_dashLength = 0.0;
|
||||
double m_gapLength = 0.0;
|
||||
|
||||
RoutePattern() = default;
|
||||
|
||||
RoutePattern(double dashLength, double gapLength)
|
||||
|
@ -69,6 +65,10 @@ struct RoutePattern
|
|||
std::fabs(m_dashLength - pattern.m_dashLength) < kEps &&
|
||||
std::fabs(m_gapLength - pattern.m_gapLength) < kEps;
|
||||
}
|
||||
|
||||
bool m_isDashed = false;
|
||||
double m_dashLength = 0.0;
|
||||
double m_gapLength = 0.0;
|
||||
};
|
||||
|
||||
enum class SubrouteStyleType
|
||||
|
@ -79,14 +79,8 @@ enum class SubrouteStyleType
|
|||
|
||||
struct SubrouteStyle
|
||||
{
|
||||
df::ColorConstant m_color;
|
||||
df::ColorConstant m_outlineColor;
|
||||
df::RoutePattern m_pattern;
|
||||
size_t m_startIndex = 0;
|
||||
size_t m_endIndex = 0;
|
||||
|
||||
SubrouteStyle() = default;
|
||||
SubrouteStyle(df::ColorConstant const & color)
|
||||
explicit SubrouteStyle(df::ColorConstant const & color)
|
||||
: m_color(color)
|
||||
, m_outlineColor(color)
|
||||
{}
|
||||
|
@ -106,16 +100,19 @@ struct SubrouteStyle
|
|||
, m_pattern(pattern)
|
||||
{}
|
||||
|
||||
bool operator == (SubrouteStyle const & style) const
|
||||
bool operator==(SubrouteStyle const & style) const
|
||||
{
|
||||
return m_color == style.m_color && m_outlineColor == style.m_outlineColor &&
|
||||
m_pattern == style.m_pattern;
|
||||
}
|
||||
|
||||
bool operator != (SubrouteStyle const & style) const
|
||||
{
|
||||
return !operator == (style);
|
||||
}
|
||||
bool operator!=(SubrouteStyle const & style) const { return !operator==(style); }
|
||||
|
||||
df::ColorConstant m_color;
|
||||
df::ColorConstant m_outlineColor;
|
||||
df::RoutePattern m_pattern;
|
||||
size_t m_startIndex = 0;
|
||||
size_t m_endIndex = 0;
|
||||
};
|
||||
|
||||
// Colored circle on the subroute.
|
||||
|
@ -157,11 +154,13 @@ using SubrouteConstPtr = std::shared_ptr<Subroute const>;
|
|||
|
||||
struct RouteRenderProperty
|
||||
{
|
||||
dp::RenderState m_state;
|
||||
std::vector<drape_ptr<dp::RenderBucket>> m_buckets;
|
||||
RouteRenderProperty()
|
||||
: m_state(CreateRenderState(gpu::Program::Route, DepthLayer::GeometryLayer))
|
||||
{}
|
||||
|
||||
dp::RenderState m_state;
|
||||
std::vector<drape_ptr<dp::RenderBucket>> m_buckets;
|
||||
std::vector<m2::RectD> m_boundingBoxes;
|
||||
};
|
||||
|
||||
struct BaseSubrouteData
|
||||
|
@ -196,11 +195,11 @@ class RouteShape
|
|||
{
|
||||
public:
|
||||
using RV = gpu::RouteVertex;
|
||||
using TGeometryBuffer = buffer_vector<RV, 128>;
|
||||
using GeometryBuffer = buffer_vector<RV, 128>;
|
||||
using AV = gpu::SolidTexturingVertex;
|
||||
using TArrowGeometryBuffer = buffer_vector<AV, 128>;
|
||||
using ArrowGeometryBuffer = buffer_vector<AV, 128>;
|
||||
using MV = gpu::RouteMarkerVertex;
|
||||
using TMarkersGeometryBuffer = buffer_vector<MV, 32>;
|
||||
using MarkersGeometryBuffer = buffer_vector<MV, 32>;
|
||||
|
||||
static drape_ptr<df::SubrouteData> CacheRoute(ref_ptr<dp::GraphicsContext> context,
|
||||
dp::DrapeID subrouteId, SubrouteConstPtr subroute,
|
||||
|
@ -218,20 +217,30 @@ public:
|
|||
SubrouteArrowsData & routeArrowsData);
|
||||
|
||||
private:
|
||||
template<typename GeometryBufferType>
|
||||
struct GeometryBufferData
|
||||
{
|
||||
GeometryBufferData()
|
||||
: m_boundingBox(m2::RectD::GetEmptyRect())
|
||||
{}
|
||||
|
||||
GeometryBufferType m_geometry;
|
||||
GeometryBufferType m_joinsGeometry;
|
||||
m2::RectD m_boundingBox;
|
||||
};
|
||||
static void PrepareGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
||||
std::vector<glsl::vec4> const & segmentsColors, float baseDepth,
|
||||
TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry);
|
||||
std::vector<GeometryBufferData<GeometryBuffer>> & geometryBufferData);
|
||||
static void PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
||||
m2::RectF const & texRect, float depthStep, float depth,
|
||||
TArrowGeometryBuffer & geometry,
|
||||
TArrowGeometryBuffer & joinsGeometry);
|
||||
GeometryBufferData<ArrowGeometryBuffer> & geometryBufferData);
|
||||
static void PrepareMarkersGeometry(std::vector<SubrouteMarker> const & markers,
|
||||
m2::PointD const & pivot, float baseDepth,
|
||||
TMarkersGeometryBuffer & geometry);
|
||||
MarkersGeometryBuffer & geometry);
|
||||
|
||||
static void BatchGeometry(ref_ptr<dp::GraphicsContext> context, dp::RenderState const & state,
|
||||
ref_ptr<void> geometry, uint32_t geomSize, ref_ptr<void> joinsGeometry,
|
||||
uint32_t joinsGeomSize, dp::BindingInfo const & bindingInfo,
|
||||
RouteRenderProperty & property);
|
||||
uint32_t joinsGeomSize, m2::RectD const & boundingBox,
|
||||
dp::BindingInfo const & bindingInfo, RouteRenderProperty & property);
|
||||
};
|
||||
} // namespace df
|
||||
|
|
Loading…
Add table
Reference in a new issue