Welcome to mirror list, hosted at ThFree Co, Russian Federation.

traffic_renderer.cpp « drape_frontend - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b3f1872bd573d3a14c78de7c5e59f44990bc73eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "drape_frontend/traffic_renderer.hpp"
#include "drape_frontend/color_constants.hpp"
#include "drape_frontend/visual_params.hpp"

#include "drape/glsl_func.hpp"
#include "drape/shader_def.hpp"
#include "drape/vertex_array_buffer.hpp"

#include "indexer/map_style_reader.hpp"
#include "indexer/scales.hpp"

#include "base/logging.hpp"

#include "std/algorithm.hpp"

namespace df
{

namespace
{

int const kMinVisibleZoomLevel = 10;
int const kMinVisibleArrowZoomLevel = 16;

float const kTrafficArrowAspect = 64.0f / 16.0f;

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,
  //11   12     13    14    15    16    17    18    19     20
  0.75f, 0.75f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 5.0f, 8.0f
};

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, 4.0f, 4.0f,
  //11  12    13    14    15    16    17    18    19     20
  4.0f, 4.0f, 4.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 5.0f, 8.0f
};

float CalculateHalfWidth(ScreenBase const & screen, bool left)
{
  double const zoomLevel = GetZoomLevel(screen.GetScale());
  double zoom = trunc(zoomLevel);
  int const index = zoom - 1.0;
  float const lerpCoef = zoomLevel - zoom;

  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]);
  else
    radius = halfWidth[scales::UPPER_STYLE_SCALE];

  return radius * VisualParams::Instance().GetVisualScale();
}

} // namespace

void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng,
                                    vector<TrafficRenderData> && renderData)
{
  if (renderData.empty())
    return;

  size_t const startIndex = m_renderData.size();
  m_renderData.reserve(m_renderData.size() + renderData.size());
  move(renderData.begin(), renderData.end(), std::back_inserter(m_renderData));
  for (size_t i = startIndex; i < m_renderData.size(); i++)
  {
    ref_ptr<dp::GpuProgram> program = mng->GetProgram(m_renderData[i].m_state.GetProgramIndex());
    program->Bind();
    m_renderData[i].m_bucket->GetBuffer()->Build(program);
    for (size_t j = 0; j < m_renderData[i].m_bucket->GetOverlayHandlesCount(); j++)
    {
      TrafficHandle * handle = static_cast<TrafficHandle *>(m_renderData[i].m_bucket->GetOverlayHandle(j).get());
      m_handles.insert(make_pair(handle->GetSegmentId(), handle));
    }
  }
}

void TrafficRenderer::UpdateTraffic(vector<TrafficSegmentData> const & trafficData)
{
  for (TrafficSegmentData const & segment : trafficData)
  {
    auto it = m_texCoords.find(segment.m_speedBucket);
    if (it == m_texCoords.end())
      continue;

    auto handleIt = m_handles.find(segment.m_id);
    if (handleIt != m_handles.end())
      handleIt->second->SetTexCoord(it->second);
  }
}

void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel,
                                    ref_ptr<dp::GpuProgramManager> mng,
                                    dp::UniformValuesStorage const & commonUniforms)
{
  if (m_renderData.empty() || zoomLevel < kMinVisibleZoomLevel)
    return;

  float const pixelHalfWidth = CalculateHalfWidth(screen, true /* left */);
  float const invPixelLength = 1.0f / (2.0f * pixelHalfWidth * kTrafficArrowAspect);

  GLFunctions::glClearDepth();
  for (TrafficRenderData & renderData : m_renderData)
  {
    ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgramIndex());
    program->Bind();
    dp::ApplyState(renderData.m_state, program);

    dp::UniformValuesStorage uniforms = commonUniforms;
    math::Matrix<float, 4, 4> const mv = renderData.m_tileKey.GetTileBasedModelView(screen);
    uniforms.SetMatrix4x4Value("modelView", mv.m_data);
    uniforms.SetFloatValue("u_opacity", 1.0f);
    uniforms.SetFloatValue("u_trafficParams", pixelHalfWidth, CalculateHalfWidth(screen, false /* left */),
                           invPixelLength, zoomLevel >= kMinVisibleArrowZoomLevel ? 1.0f : 0.0f);
    dp::ApplyUniforms(uniforms, program);

    renderData.m_bucket->Render(renderData.m_state.GetDrawAsLine());
  }
}

void TrafficRenderer::SetTexCoords(unordered_map<int, glsl::vec2> && texCoords)
{
  m_texCoords = move(texCoords);
}

void TrafficRenderer::Clear()
{
  m_renderData.clear();
  m_handles.clear();
}

} // namespace df