<commit_before>/*

    Copyright <NAME> and <NAME>, 2011, 2012, 2013

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    Lasercake is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <vector>
#include <array>

#include <GL/glew.h>
#include <glm/gtc/type_ptr.hpp>

#include "gl_rendering.hpp"
#include "gl_data_format.hpp"

using namespace gl_data_format;

#define BUFFER_OFFSET(i) ((void*)(i))
const GLuint INVALID_BUFFER_ID = 0;

// by_distance_VBO_* are indexed by distance*DISTANCE_IDX_FACTOR + this enum:
enum by_distance_idx_adjustment_enum {
  QUADS_IDX = 0, TRIANGLES_IDX, LINES_IDX, POINTS_IDX,
  DISTANCE_IDX_FACTOR
};

typedef std::array<vertex_with_color, 4> rect_type;

struct gl_renderer::state_t_ {
  GLuint rect_VBO_name;
  std::vector<GLuint> by_distance_VBO_names;
  std::vector<size_t> by_distance_VBO_sizes;
};

gl_renderer::gl_renderer() {}
gl_renderer::~gl_renderer() {}

void gl_renderer::output_gl_data_to_OpenGL(
    abstract_gl_data const& abstract_gl_data,
    viewport_dimension viewport_width,
    viewport_dimension viewport_height,
    LasercakeGLWidget& gl_widget,
    // volatile: Ensure that every load is in fact done,
    // even though they look redundant.
    std::atomic_bool const volatile& interrupt
) {
  // This code is intended to have no operations in it that can possibly
  // throw exceptions, to simplify dealing with OpenGL context state.
  // When allocating, e.g. via std::vector, wrap it in a try/catch
  // and do something sensible if there's an exception.

  gl_all_data const& gl_data = abstract_gl_data.data();

  if(interrupt.load(std::memory_order_relaxed)) {return;};

  if(!state_) {
    try {
      state_.reset(new state_t_);
    }
    catch(std::bad_alloc const&) {
      return;
    }

    const GLenum glew_init_err = glewInit();
    if(glew_init_err != GLEW_OK)
    {
      // give up
      state_.reset();
      return;
    }

    glGenBuffersARB(1, &state_->rect_VBO_name);
    glBindBufferARB(GL_ARRAY_BUFFER, state_->rect_VBO_name);
    glBufferDataARB(GL_ARRAY_BUFFER, sizeof(rect_type), nullptr, GL_STREAM_DRAW);

    if(interrupt.load(std::memory_order_relaxed)) {return;};
  }

  glViewport(0, 0, viewport_width, viewport_height);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  // Depth func LEQUAL not LESS.  We try to draw objects in back-to-front
  // order, so rounding error means the front (later) one should win.
  //glEnable(GL_DEPTH_TEST)
  //glDepthFunc(GL_LEQUAL);
  glClear(GL_COLOR_BUFFER_BIT/* | GL_DEPTH_BUFFER_BIT*/);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  const glm::mat4 projection_matrix =
    make_projection_matrix(float(viewport_width) / float(viewport_height));
  glLoadMatrixf(glm::value_ptr(projection_matrix));

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  const glm::mat4 view_matrix =
    make_view_matrix(gl_data.facing, gl_data.facing_up);
  glLoadMatrixf(glm::value_ptr(view_matrix));

  glEnableClientState(GL_VERTEX_ARRAY);<commit_msg>Enable OpenGL depth test.<commit_after>/*

    Copyright <NAME> and <NAME>, 2011, 2012, 2013

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    Lasercake is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <vector>
#include <array>

#include <GL/glew.h>
#include <glm/gtc/type_ptr.hpp>

#include "gl_rendering.hpp"
#include "gl_data_format.hpp"

using namespace gl_data_format;

#define BUFFER_OFFSET(i) ((void*)(i))
const GLuint INVALID_BUFFER_ID = 0;

// by_distance_VBO_* are indexed by distance*DISTANCE_IDX_FACTOR + this enum:
enum by_distance_idx_adjustment_enum {
  QUADS_IDX = 0, TRIANGLES_IDX, LINES_IDX, POINTS_IDX,
  DISTANCE_IDX_FACTOR
};

typedef std::array<vertex_with_color, 4> rect_type;

struct gl_renderer::state_t_ {
  GLuint rect_VBO_name;
  std::vector<GLuint> by_distance_VBO_names;
  std::vector<size_t> by_distance_VBO_sizes;
};

gl_renderer::gl_renderer() {}
gl_renderer::~gl_renderer() {}

void gl_renderer::output_gl_data_to_OpenGL(
    abstract_gl_data const& abstract_gl_data,
    viewport_dimension viewport_width,
    viewport_dimension viewport_height,
    LasercakeGLWidget& gl_widget,
    // volatile: Ensure that every load is in fact done,
    // even though they look redundant.
    std::atomic_bool const volatile& interrupt
) {
  // This code is intended to have no operations in it that can possibly
  // throw exceptions, to simplify dealing with OpenGL context state.
  // When allocating, e.g. via std::vector, wrap it in a try/catch
  // and do something sensible if there's an exception.

  gl_all_data const& gl_data = abstract_gl_data.data();

  if(interrupt.load(std::memory_order_relaxed)) {return;};

  if(!state_) {
    try {
      state_.reset(new state_t_);
    }
    catch(std::bad_alloc const&) {
      return;
    }

    const GLenum glew_init_err = glewInit();
    if(glew_init_err != GLEW_OK)
    {
      // give up
      state_.reset();
      return;
    }

    glGenBuffersARB(1, &state_->rect_VBO_name);
    glBindBufferARB(GL_ARRAY_BUFFER, state_->rect_VBO_name);
    glBufferDataARB(GL_ARRAY_BUFFER, sizeof(rect_type), nullptr, GL_STREAM_DRAW);

    if(interrupt.load(std::memory_order_relaxed)) {return;};
  }

  glViewport(0, 0, viewport_width, viewport_height);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  // Depth func LEQUAL not LESS.  We try to draw objects in back-to-front
  // order, so rounding error means the front (later) one should win.
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  const glm::mat4 projection_matrix =
    make_projection_matrix(float(viewport_width) / float(viewport_height));
  glLoadMatrixf(glm::value_ptr(projection_matrix));

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  const glm::mat4 view_matrix =
    make_view_matrix(gl_data.facing, gl_data.facing_up);
  glLoadMatrixf(glm::value_ptr(view_matrix));

  glEnableClientState(GL_VERTEX_ARRAY);
{'fraction_non_alphanumeric': 0.09365013199944422, 'fraction_numerical': 0.005835764902042517, 'mean_word_length': 4.3596425912137, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6389247', 'n_tokens_mistral': 2507, 'n_tokens_neox': 2410, 'n_words': 634}