<commit_before>#include "arrow3d.hpp"

#include "drape/glconstants.hpp"
#include "drape/glfunctions.hpp"
#include "drape/glsl_func.hpp"
#include "drape/glsl_types.hpp"
#include "drape/glstate.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/shader_def.hpp"
#include "drape/uniform_values_storage.hpp"

#include "geometry/screenbase.hpp"

namespace df
{

double const kArrowSizeX = 2.0;
double const kArrowSizeY = 3.0;
double const kArrow3dScale = 1.2;

Arrow3d::Arrow3d()
  : m_state(gpu::ARROW_3D_PROGRAM, dp::GLState::OverlayLayer)
{
  m_vertices = {  0.0f,  0.0f,  -1.0f,
                 -1.0f, -1.0f,  0.0f,
                  0.0f,  2.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  0.0f,  2.0f,  0.0f,
                  1.0f, -1.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  0.0f, -0.5f,  0.0f,
                 -1.0f, -1.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  1.0f, -1.0f,  0.0f,
                  0.0f, -0.5f,  0.0f
               };

  m_normals.resize(m_vertices.size());
  for (size_t triangle = 0; triangle < m_vertices.size() / 9; ++triangle)
  {
    glsl::vec3 v[3];
    for (size_t vertex = 0; vertex < 3; ++vertex)
    {
      size_t const offset = triangle * 9 + vertex * 3;
      v[vertex] = glsl::vec3(m_vertices[offset], m_vertices[offset + 1], m_vertices[offset + 2]);
    }

    glsl::vec3 normal = glsl::cross(glsl::vec3(v[1].x - v[0].x, v[1].y - v[0].y, v[1].z - v[0].z),
                                    glsl::vec3(v[2].x - v[0].x, v[2].y - v[0].y, v[2].z - v[0].z));
    normal = glsl::normalize(normal);

    for (size_t vertex = 0; vertex < 3; ++vertex)
    {
      size_t const offset = triangle * 9 + vertex * 3;
      m_normals[offset] = normal.x;
      m_normals[offset + 1] = normal.y;
      m_normals[offset + 2] = normal.z;
    }
  }
}

Arrow3d::~Arrow3d()
{
  if (m_bufferId != 0)
    GLFunctions::glDeleteBuffer(m_bufferId);

  if (m_bufferNormalsId != 0)
    GLFunctions::glDeleteBuffer(m_bufferNormalsId);
}

void Arrow3d::SetPosition(const m2::PointD & position)
{
  m_position = position;
}

void Arrow3d::SetAzimuth(double azimuth)
{
  m_azimuth = azimuth;
}

void Arrow3d::SetSize(uint32_t width, uint32_t height)
{
  m_pixelWidth = width;
  m_pixelHeight = height;
}

void Arrow3d::Build(ref_ptr<dp::GpuProgram> prg)
{
  m_bufferId = GLFunctions::glGenBuffer();
  GLFunctions::glBindBuffer(m_bufferId, gl_const::GLArrayBuffer);

  m_attributePosition = prg->GetAttributeLocation("a_pos");
  ASSERT_NOT_EQUAL(m_attributePosition, -1, ());

  GLFunctions::glBufferData(gl_const::GLArrayBuffer, m_vertices.size() * sizeof(m_vertices[0]),
                            m_vertices.data(), gl_const::GLStaticDraw);

  m_bufferNormalsId = GLFunctions::glGenBuffer();
  GLFunctions::glBindBuffer(m_bufferNormalsId, gl_const::GLArrayBuffer);

  m_attributeNormal = prg->GetAttributeLocation("a_normal");
  ASSERT_NOT_EQUAL(m_attributeNormal, -1, ());

  GLFunctions::glBufferData(gl_const::GLArrayBuffer, m_normals.size() * sizeof(m_normals[0]),
                            m_normals.data(), gl_const::GLStaticDraw);

  GLFunctions::glBindVertexArray(0);
  GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
}

void Arrow3d::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng)
{
  ref_ptr<dp::GpuProgram> prg = mng->GetProgram(gpu::ARROW_3D_PROGRAM);
  prg->Bind();

  if (!m_isInitialized)
  {
    Build(prg);
    m_isInitialized = true;<commit_msg>Fixed route end point rendering<commit_after>#include "arrow3d.hpp"

#include "drape/glconstants.hpp"
#include "drape/glfunctions.hpp"
#include "drape/glsl_func.hpp"
#include "drape/glsl_types.hpp"
#include "drape/glstate.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/shader_def.hpp"
#include "drape/uniform_values_storage.hpp"

#include "geometry/screenbase.hpp"

namespace df
{

double const kArrowSizeX = 2.0;
double const kArrowSizeY = 3.0;
double const kArrow3dScale = 1.2;

Arrow3d::Arrow3d()
  : m_state(gpu::ARROW_3D_PROGRAM, dp::GLState::OverlayLayer)
{
  m_vertices = {  0.0f,  0.0f,  -1.0f,
                 -1.0f, -1.0f,  0.0f,
                  0.0f,  2.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  0.0f,  2.0f,  0.0f,
                  1.0f, -1.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  0.0f, -0.5f,  0.0f,
                 -1.0f, -1.0f,  0.0f,

                  0.0f,  0.0f,  -1.0f,
                  1.0f, -1.0f,  0.0f,
                  0.0f, -0.5f,  0.0f
               };

  m_normals.resize(m_vertices.size());
  for (size_t triangle = 0; triangle < m_vertices.size() / 9; ++triangle)
  {
    glsl::vec3 v[3];
    for (size_t vertex = 0; vertex < 3; ++vertex)
    {
      size_t const offset = triangle * 9 + vertex * 3;
      v[vertex] = glsl::vec3(m_vertices[offset], m_vertices[offset + 1], m_vertices[offset + 2]);
    }

    glsl::vec3 normal = glsl::cross(glsl::vec3(v[1].x - v[0].x, v[1].y - v[0].y, v[1].z - v[0].z),
                                    glsl::vec3(v[2].x - v[0].x, v[2].y - v[0].y, v[2].z - v[0].z));
    normal = glsl::normalize(normal);

    for (size_t vertex = 0; vertex < 3; ++vertex)
    {
      size_t const offset = triangle * 9 + vertex * 3;
      m_normals[offset] = normal.x;
      m_normals[offset + 1] = normal.y;
      m_normals[offset + 2] = normal.z;
    }
  }
}

Arrow3d::~Arrow3d()
{
  if (m_bufferId != 0)
    GLFunctions::glDeleteBuffer(m_bufferId);

  if (m_bufferNormalsId != 0)
    GLFunctions::glDeleteBuffer(m_bufferNormalsId);
}

void Arrow3d::SetPosition(const m2::PointD & position)
{
  m_position = position;
}

void Arrow3d::SetAzimuth(double azimuth)
{
  m_azimuth = azimuth;
}

void Arrow3d::SetSize(uint32_t width, uint32_t height)
{
  m_pixelWidth = width;
  m_pixelHeight = height;
}

void Arrow3d::Build(ref_ptr<dp::GpuProgram> prg)
{
  m_bufferId = GLFunctions::glGenBuffer();
  GLFunctions::glBindBuffer(m_bufferId, gl_const::GLArrayBuffer);

  m_attributePosition = prg->GetAttributeLocation("a_pos");
  ASSERT_NOT_EQUAL(m_attributePosition, -1, ());

  GLFunctions::glBufferData(gl_const::GLArrayBuffer, m_vertices.size() * sizeof(m_vertices[0]),
                            m_vertices.data(), gl_const::GLStaticDraw);

  m_bufferNormalsId = GLFunctions::glGenBuffer();
  GLFunctions::glBindBuffer(m_bufferNormalsId, gl_const::GLArrayBuffer);

  m_attributeNormal = prg->GetAttributeLocation("a_normal");
  ASSERT_NOT_EQUAL(m_attributeNormal, -1, ());

  GLFunctions::glBufferData(gl_const::GLArrayBuffer, m_normals.size() * sizeof(m_normals[0]),
                            m_normals.data(), gl_const::GLStaticDraw);

  GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
}

void Arrow3d::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng)
{
  // Unbind current VAO, because glVertexAttributePointer and glEnableVertexAttribute can affect it.
  GLFunctions::glBindVertexArray(0);

  ref_ptr<dp::GpuProgram> prg = mng->GetProgram(gpu::ARROW_3D_PROGRAM);
  prg->Bind();

  if (!m_isInitialized)
  {
    Build(prg);
    m_isInitialized = true;
{'fraction_non_alphanumeric': 0.15414908579465542, 'fraction_numerical': 0.03825597749648382, 'mean_word_length': 2.9417960088691797, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '742896', 'n_tokens_mistral': 2917, 'n_tokens_neox': 2806, 'n_words': 451}