Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
289
libs/drape_frontend/transit_scheme_renderer.cpp
Normal file
289
libs/drape_frontend/transit_scheme_renderer.cpp
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
#include "drape_frontend/transit_scheme_renderer.hpp"
|
||||
|
||||
#include "drape_frontend/debug_rect_renderer.hpp"
|
||||
#include "drape_frontend/postprocess_renderer.hpp"
|
||||
#include "drape_frontend/shape_view_params.hpp"
|
||||
#include "drape_frontend/visual_params.hpp"
|
||||
|
||||
#include "drape/graphics_context.hpp"
|
||||
#include "drape/overlay_tree.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace df
|
||||
{
|
||||
namespace
|
||||
{
|
||||
float CalculateHalfWidth(ScreenBase const & screen)
|
||||
{
|
||||
double zoom = 0.0;
|
||||
int index = 0;
|
||||
float lerpCoef = 0.0f;
|
||||
ExtractZoomFactors(screen, zoom, index, lerpCoef);
|
||||
|
||||
return InterpolateByZoomLevels(index, lerpCoef, kTransitLinesWidthInPixel) *
|
||||
static_cast<float>(VisualParams::Instance().GetVisualScale());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool TransitSchemeRenderer::IsSchemeVisible(int zoomLevel) const
|
||||
{
|
||||
return zoomLevel >= kTransitSchemeMinZoomLevel;
|
||||
}
|
||||
|
||||
bool TransitSchemeRenderer::HasRenderData() const
|
||||
{
|
||||
return !m_linesRenderData.empty() || !m_linesCapsRenderData.empty() || !m_markersRenderData.empty() ||
|
||||
!m_textRenderData.empty() || !m_colorSymbolRenderData.empty();
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::ClearContextDependentResources(ref_ptr<dp::OverlayTree> tree)
|
||||
{
|
||||
if (tree)
|
||||
{
|
||||
RemoveOverlays(tree, m_textRenderData);
|
||||
RemoveOverlays(tree, m_colorSymbolRenderData);
|
||||
}
|
||||
|
||||
m_linesRenderData.clear();
|
||||
m_linesCapsRenderData.clear();
|
||||
m_markersRenderData.clear();
|
||||
m_textRenderData.clear();
|
||||
m_colorSymbolRenderData.clear();
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::Clear(MwmSet::MwmId const & mwmId, ref_ptr<dp::OverlayTree> tree)
|
||||
{
|
||||
ClearRenderData(mwmId, nullptr /* tree */, m_linesRenderData);
|
||||
ClearRenderData(mwmId, nullptr /* tree */, m_linesCapsRenderData);
|
||||
ClearRenderData(mwmId, nullptr /* tree */, m_markersRenderData);
|
||||
ClearRenderData(mwmId, tree, m_textRenderData);
|
||||
ClearRenderData(mwmId, tree, m_colorSymbolRenderData);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::ClearRenderData(MwmSet::MwmId const & mwmId, ref_ptr<dp::OverlayTree> tree,
|
||||
std::vector<TransitRenderData> & renderData)
|
||||
{
|
||||
auto removePredicate = [&mwmId](TransitRenderData const & data) { return data.m_mwmId == mwmId; };
|
||||
ClearRenderData(removePredicate, tree, renderData);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::ClearRenderData(TRemovePredicate const & predicate, ref_ptr<dp::OverlayTree> tree,
|
||||
std::vector<TransitRenderData> & renderData)
|
||||
{
|
||||
if (tree)
|
||||
{
|
||||
for (auto & data : renderData)
|
||||
if (predicate(data))
|
||||
data.m_bucket->RemoveOverlayHandles(tree);
|
||||
}
|
||||
|
||||
renderData.erase(std::remove_if(renderData.begin(), renderData.end(), predicate), renderData.end());
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::AddRenderData(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ref_ptr<dp::OverlayTree> tree, TransitRenderData && renderData)
|
||||
{
|
||||
switch (renderData.m_type)
|
||||
{
|
||||
case TransitRenderData::Type::LinesCaps:
|
||||
PrepareRenderData(context, mng, tree, m_linesCapsRenderData, std::move(renderData));
|
||||
break;
|
||||
case TransitRenderData::Type::Lines:
|
||||
PrepareRenderData(context, mng, tree, m_linesRenderData, std::move(renderData));
|
||||
break;
|
||||
case TransitRenderData::Type::Markers:
|
||||
PrepareRenderData(context, mng, tree, m_markersRenderData, std::move(renderData));
|
||||
break;
|
||||
case TransitRenderData::Type::Text:
|
||||
PrepareRenderData(context, mng, tree, m_textRenderData, std::move(renderData));
|
||||
break;
|
||||
case TransitRenderData::Type::Stubs:
|
||||
PrepareRenderData(context, mng, tree, m_colorSymbolRenderData, std::move(renderData));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::PrepareRenderData(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ref_ptr<dp::OverlayTree> tree,
|
||||
std::vector<TransitRenderData> & currentRenderData,
|
||||
TransitRenderData && newRenderData)
|
||||
{
|
||||
// Remove obsolete render data.
|
||||
auto const removePredicate = [this, &newRenderData](TransitRenderData const & rd)
|
||||
{ return rd.m_mwmId == newRenderData.m_mwmId && rd.m_recacheId < m_lastRecacheId; };
|
||||
ClearRenderData(removePredicate, tree, currentRenderData);
|
||||
|
||||
m_lastRecacheId = std::max(m_lastRecacheId, newRenderData.m_recacheId);
|
||||
|
||||
// Add new render data.
|
||||
auto program = mng->GetProgram(newRenderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
newRenderData.m_bucket->GetBuffer()->Build(context, program);
|
||||
|
||||
currentRenderData.emplace_back(std::move(newRenderData));
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderTransit(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, ref_ptr<PostprocessRenderer> postprocessRenderer,
|
||||
FrameValues const & frameValues, ref_ptr<DebugRectRenderer> debugRectRenderer)
|
||||
{
|
||||
auto const zoomLevel = GetDrawTileScale(screen);
|
||||
if (!IsSchemeVisible(zoomLevel) || !HasRenderData())
|
||||
return;
|
||||
|
||||
float const pixelHalfWidth = CalculateHalfWidth(screen);
|
||||
|
||||
RenderLinesCaps(context, mng, screen, frameValues, pixelHalfWidth);
|
||||
RenderLines(context, mng, screen, frameValues, pixelHalfWidth);
|
||||
RenderMarkers(context, mng, screen, frameValues, pixelHalfWidth);
|
||||
{
|
||||
StencilWriterGuard guard(postprocessRenderer, context);
|
||||
RenderText(context, mng, screen, frameValues, debugRectRenderer);
|
||||
}
|
||||
// Render only for debug purpose.
|
||||
// RenderStubs(context, mng, screen, frameValues, debugRectRenderer);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::CollectOverlays(ref_ptr<dp::OverlayTree> tree, ScreenBase const & modelView)
|
||||
{
|
||||
CollectOverlays(tree, modelView, m_textRenderData);
|
||||
CollectOverlays(tree, modelView, m_colorSymbolRenderData);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::CollectOverlays(ref_ptr<dp::OverlayTree> tree, ScreenBase const & modelView,
|
||||
std::vector<TransitRenderData> & renderData)
|
||||
{
|
||||
for (auto & data : renderData)
|
||||
if (tree->IsNeedUpdate())
|
||||
data.m_bucket->CollectOverlayHandles(tree);
|
||||
else
|
||||
data.m_bucket->Update(modelView);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RemoveOverlays(ref_ptr<dp::OverlayTree> tree, std::vector<TransitRenderData> & renderData)
|
||||
{
|
||||
for (auto & data : renderData)
|
||||
data.m_bucket->RemoveOverlayHandles(tree);
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderLinesCaps(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, FrameValues const & frameValues,
|
||||
float pixelHalfWidth)
|
||||
{
|
||||
context->Clear(dp::ClearBits::DepthBit, dp::kClearBitsStoreAll);
|
||||
for (auto & renderData : m_linesCapsRenderData)
|
||||
{
|
||||
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
dp::ApplyState(context, program, renderData.m_state);
|
||||
|
||||
gpu::TransitProgramParams params;
|
||||
frameValues.SetTo(params);
|
||||
math::Matrix<float, 4, 4> mv = screen.GetModelView(renderData.m_pivot, kShapeCoordScalar);
|
||||
params.m_modelView = glsl::make_mat4(mv.m_data);
|
||||
params.m_lineHalfWidth = pixelHalfWidth;
|
||||
params.m_maxRadius = kTransitLineHalfWidth;
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderLines(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, FrameValues const & frameValues,
|
||||
float pixelHalfWidth)
|
||||
{
|
||||
for (auto & renderData : m_linesRenderData)
|
||||
{
|
||||
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
dp::ApplyState(context, program, renderData.m_state);
|
||||
|
||||
gpu::TransitProgramParams params;
|
||||
frameValues.SetTo(params);
|
||||
math::Matrix<float, 4, 4> mv = screen.GetModelView(renderData.m_pivot, kShapeCoordScalar);
|
||||
params.m_modelView = glsl::make_mat4(mv.m_data);
|
||||
params.m_lineHalfWidth = pixelHalfWidth;
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderMarkers(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, FrameValues const & frameValues,
|
||||
float pixelHalfWidth)
|
||||
{
|
||||
context->Clear(dp::ClearBits::DepthBit, dp::kClearBitsStoreAll);
|
||||
for (auto & renderData : m_markersRenderData)
|
||||
{
|
||||
auto program = mng->GetProgram(renderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
dp::ApplyState(context, program, renderData.m_state);
|
||||
|
||||
gpu::TransitProgramParams params;
|
||||
frameValues.SetTo(params);
|
||||
math::Matrix<float, 4, 4> mv = screen.GetModelView(renderData.m_pivot, kShapeCoordScalar);
|
||||
params.m_modelView = glsl::make_mat4(mv.m_data);
|
||||
params.m_params = glsl::vec3(static_cast<float>(cos(screen.GetAngle())), static_cast<float>(sin(screen.GetAngle())),
|
||||
pixelHalfWidth);
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderText(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, FrameValues const & frameValues,
|
||||
ref_ptr<DebugRectRenderer> debugRectRenderer)
|
||||
{
|
||||
auto const & glyphParams = df::VisualParams::Instance().GetGlyphVisualParams();
|
||||
for (auto & renderData : m_textRenderData)
|
||||
{
|
||||
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
dp::ApplyState(context, program, renderData.m_state);
|
||||
|
||||
gpu::MapProgramParams params;
|
||||
frameValues.SetTo(params);
|
||||
math::Matrix<float, 4, 4> mv = screen.GetModelView(renderData.m_pivot, kShapeCoordScalar);
|
||||
params.m_modelView = glsl::make_mat4(mv.m_data);
|
||||
params.m_contrastGamma = glsl::vec2(glyphParams.m_outlineContrast, glyphParams.m_outlineGamma);
|
||||
params.m_isOutlinePass = 1.0f;
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
|
||||
params.m_contrastGamma = glsl::vec2(glyphParams.m_contrast, glyphParams.m_gamma);
|
||||
params.m_isOutlinePass = 0.0f;
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
|
||||
renderData.m_bucket->RenderDebug(context, screen, debugRectRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitSchemeRenderer::RenderStubs(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng,
|
||||
ScreenBase const & screen, FrameValues const & frameValues,
|
||||
ref_ptr<DebugRectRenderer> debugRectRenderer)
|
||||
{
|
||||
for (auto & renderData : m_colorSymbolRenderData)
|
||||
{
|
||||
auto program = mng->GetProgram(renderData.m_state.GetProgram<gpu::Program>());
|
||||
program->Bind();
|
||||
dp::ApplyState(context, program, renderData.m_state);
|
||||
|
||||
gpu::MapProgramParams params;
|
||||
frameValues.SetTo(params);
|
||||
math::Matrix<float, 4, 4> mv = screen.GetModelView(renderData.m_pivot, kShapeCoordScalar);
|
||||
params.m_modelView = glsl::make_mat4(mv.m_data);
|
||||
mng->GetParamsSetter()->Apply(context, program, params);
|
||||
|
||||
renderData.m_bucket->Render(context, false /* draw as line */);
|
||||
|
||||
renderData.m_bucket->RenderDebug(context, screen, debugRectRenderer);
|
||||
}
|
||||
}
|
||||
} // namespace df
|
||||
Loading…
Add table
Add a link
Reference in a new issue