Skip to content
Snippets Groups Projects
drawer.cpp 3.21 KiB
#include <drawer.hpp>
#include <vector>
#include <glad/glad.h>
#include <toolbox.hpp>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

Drawer::Drawer(Toolbox& tb)
	:
	x0_(0.f), y0_(0.f), x1_(0.f), y1_(0.f), num_drawn_(0),
	points_(32, 0.f)
{}
/*Prepares to start drawing*/
void Drawer::start_drawing(const float x, const float y) {
	x0_ = x;
	y0_ = y;
	x1_ = x;
	y1_ = y;
}
/*Draw next stroke*/
bool Drawer::draw(const float x, const float y, Toolbox& tb, bool drawing) {
	++num_drawn_;
	x0_ = x1_;
	y0_ = y1_;
	x1_ = x;
	y1_ = y;
	/*If the drawn stroke is nill, do nothing*/
	if (!calculate_points_(tb, drawing)) {
		return false;
	}
	glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(float), points_.data(), GL_DYNAMIC_DRAW);
  glDrawArrays(GL_TRIANGLE_FAN, 0, 16);
  return true;
}
void Drawer::redraw(Toolbox& tb) {
  glDrawArrays(GL_TRIANGLE_FAN, 0, 16);
}
/*Erase*/
void Drawer::erase(const float x, const float y, Toolbox& tb) {
  ++num_drawn_;
  x0_ = x1_;
  y0_ = y1_;
  x1_ = x;
  y1_ = y;
  /*Change width for points calculation*/
  if (!calculate_points_(tb, false)) {
    return;
  }
  /*Upload vertices*/
  glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(float), &points_[0], GL_DYNAMIC_DRAW);
  glDrawArrays(GL_TRIANGLE_FAN, 0, 16);
}
/*Get number of strokes drawn*/
int Drawer::num_drawn() const {
	return num_drawn_;
}
/*Calculate the vertex coordinates*/
bool Drawer::calculate_points_(Toolbox& tb, bool drawing) {
  float width = tb.drawing_width;
  if (!drawing) {
    width = tb.erasing_width;
  }
  glm::vec2 r_unnorm(x1_ - x0_, y1_ - y0_);
  if (glm::length(r_unnorm) == 0)
    return false;
  float target_length = (float)(width) / (float)(tb.texture_w);
  glm::vec2 r = target_length / (2.f * glm::length(r_unnorm)) * r_unnorm;
  glm::vec2 r_L = glm::vec2(-r.y, r.x);
  glm::vec2 r_R = glm::vec2(r.y, -r.x);
  float cosinus = 0.866025f;
  float sinus = 0.5f;
  glm::vec2 v1(cosinus * r_L.x - sinus * r_L.y, +sinus * r_L.x + cosinus * r_L.y);
  glm::vec2 v2(cosinus * v1.x - sinus * v1.y, +sinus * v1.x + cosinus * v1.y);
  glm::vec2 v3(cosinus * v2.x - sinus * v2.y, +sinus * v2.x + cosinus * v2.y);
  glm::vec2 v4(cosinus * v3.x - sinus * v3.y, +sinus * v3.x + cosinus * v3.y);
  glm::vec2 v5(cosinus * v4.x - sinus * v4.y, +sinus * v4.x + cosinus * v4.y);
  points_[0] = (x0_ + x1_) / 2.f;
  points_[1] = (y0_ + y1_) / 2.f;
  points_[2] = x0_ + r_L.x;
  points_[3] = y0_ + r_L.y;
  points_[4] = x0_ + v1.x;
  points_[5] = y0_ + v1.y;
  points_[6] = x0_ + v2.x;
  points_[7] = y0_ + v2.y;
  points_[8] = x0_ + v3.x;
  points_[9] = y0_ + v3.y;
  points_[10] = x0_ + v4.x;
  points_[11] = y0_ + v4.y;
  points_[12] = x0_ + v5.x;
  points_[13] = y0_ + v5.y;
  points_[14] = x0_ + r_R.x;
  points_[15] = y0_ + r_R.y;
  points_[16] = x1_ + r_R.x;
  points_[17] = y1_ + r_R.y;
  points_[18] = x1_ - v1.x;
  points_[19] = y1_ - v1.y;
  points_[20] = x1_ - v2.x;
  points_[21] = y1_ - v2.y;
  points_[22] = x1_ - v3.x;
  points_[23] = y1_ - v3.y;
  points_[24] = x1_ - v4.x;
  points_[25] = y1_ - v4.y;
  points_[26] = x1_ - v5.x;
  points_[27] = y1_ - v5.y;
  points_[28] = x1_ + r_L.x;
  points_[29] = y1_ + r_L.y;
  points_[30] = x0_ + r_L.x;
  points_[31] = y0_ + r_L.y;
  return true;
}