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

circle_shape.cpp « drape_frontend - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c9c9099dccb68e33de375e9f901fd9ab1b4da521 (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
#include "circle_shape.hpp"

#include "../drape/glsl_types.hpp"
#include "../drape/batcher.hpp"
#include "../drape/attribute_provider.hpp"
#include "../drape/glstate.hpp"
#include "../drape/shader_def.hpp"
#include "../drape/texture_set_holder.hpp"

#define BLOCK_X_OFFSET  0
#define BLOCK_Y_OFFSET  1
#define BLOCK_Z_OFFSET  2
#define BLOCK_NX_OFFSET 3
#define BLOCK_NY_OFFSET 4
#define BLOCK_CX_OFFSET 5
#define BLOCK_CY_OFFSET 6
#define BLOCK_IND_OFFSET 7
#define VERTEX_STRIDE 8

namespace df
{

namespace
{

void AddPoint(vector<float> & stream, size_t pointIndex, float x, float y, float z, float nX, float nY, glsl::vec3 const & color)
{
  size_t startIndex = pointIndex * VERTEX_STRIDE;
  stream[startIndex + BLOCK_X_OFFSET] = x;
  stream[startIndex + BLOCK_Y_OFFSET] = y;
  stream[startIndex + BLOCK_Z_OFFSET] = z;
  stream[startIndex + BLOCK_NX_OFFSET] = nX;
  stream[startIndex + BLOCK_NY_OFFSET] = nY;
  stream[startIndex + BLOCK_CX_OFFSET] = color.x;
  stream[startIndex + BLOCK_CY_OFFSET] = color.y;
  stream[startIndex + BLOCK_IND_OFFSET] = color.z;
}

} // namespace

CircleShape::CircleShape(m2::PointF const & mercatorPt, CircleViewParams const & params)
  : m_pt(mercatorPt)
  , m_params(params)
{
}

void CircleShape::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureSetHolder> textures) const
{
  double const TriangleCount = 20.0;
  double const etalonSector = (2.0 * math::pi) / TriangleCount;

  dp::ColorKey key(m_params.m_color.GetColorInInt());
  dp::TextureSetHolder::ColorRegion region;
  textures->GetColorRegion(key, region);
  glsl::vec3 color(glsl::ToVec2(region.GetTexRect().Center()), region.GetTextureNode().GetOffset());

  /// x, y, z floats on geompoint
  /// normal x, y on triangle forming normals
  /// 20 triangles on full circle
  /// 22 points as triangle fan need n + 2 points on n triangles

  vector<float> stream((3 + 2 + 3) * (TriangleCount + 2));
  AddPoint(stream, 0, m_pt.x, m_pt.y, m_params.m_depth, 0.0f, 0.0f, color);

  m2::PointD startNormal(0.0f, m_params.m_radius);

  for (size_t i = 0; i < TriangleCount + 1; ++i)
  {
    m2::PointD rotatedNormal = m2::Rotate(startNormal, (i) * etalonSector);
    AddPoint(stream, i + 1, m_pt.x, m_pt.y, m_params.m_depth, rotatedNormal.x, rotatedNormal.y, color);
  }

  dp::GLState state(gpu::SOLID_SHAPE_PROGRAM, dp::GLState::OverlayLayer);
  state.SetTextureSet(region.GetTextureNode().m_textureSet);

  dp::AttributeProvider provider(1, TriangleCount + 2);
  dp::BindingInfo info(3);
  dp::BindingDecl & posDecl = info.GetBindingDecl(0);
  posDecl.m_attributeName = "a_position";
  posDecl.m_componentCount = 3;
  posDecl.m_componentType = gl_const::GLFloatType;
  posDecl.m_offset = 0;
  posDecl.m_stride = VERTEX_STRIDE * sizeof(float);

  dp::BindingDecl & normalDecl = info.GetBindingDecl(1);
  normalDecl.m_attributeName = "a_normal";
  normalDecl.m_componentCount = 2;
  normalDecl.m_componentType = gl_const::GLFloatType;
  normalDecl.m_offset = BLOCK_NX_OFFSET * sizeof(float);
  normalDecl.m_stride = VERTEX_STRIDE * sizeof(float);

  dp::BindingDecl & colorDecl = info.GetBindingDecl(2);
  colorDecl.m_attributeName = "a_color_index";
  colorDecl.m_componentCount = 3;
  colorDecl.m_componentType = gl_const::GLFloatType;
  colorDecl.m_offset = BLOCK_CX_OFFSET * sizeof(float);
  colorDecl.m_stride = VERTEX_STRIDE * sizeof(float);

  dp::OverlayHandle * overlay = new dp::SquareHandle(m_params.m_id,
                                                     dp::Center, m_pt,
                                                     m2::PointD(m_params.m_radius, m_params.m_radius),
                                                     m_params.m_depth);

  provider.InitStream(0, info, dp::MakeStackRefPointer<void>(&stream[0]));
  batcher->InsertTriangleFan(state, dp::MakeStackRefPointer(&provider), dp::MovePointer(overlay));
}

} // namespace df