#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; }