#pragma once #include "rtt.h" #include "shader.h" NS_START class Brush { public: int id = 0; std::string m_name; uint16_t m_tex_id = 0; glm::vec4 m_tip_color{1, 0, 0, 1}; float m_tip_size = 0; float m_tip_spacing = 0; float m_tip_flow = 0; float m_tip_opacity = 0; float m_tip_angle = 0; float m_tip_stencil = 0; float m_tip_wet = 0; float m_tip_noise = 0; bool m_tip_angle_follow = false; bool m_tip_flow_pressure = false; bool m_tip_size_pressure = false; float m_jitter_scale = 0; float m_jitter_angle = 0; float m_jitter_spread = 0; float m_jitter_flow = 0; int m_blend_mode = 0; }; struct StrokeSample { glm::vec2 pos = { 0, 0 }; glm::vec2 origin = { 0,0 }; float size = 0; float flow = 0; float angle = 0; }; class BrushMesh { public: GLuint buffers[3]{ 0 }; GLuint vao{ 0 }; struct vertex_t { glm::vec4 pos; glm::vec2 uvs; }; struct instance_t { glm::mat4 mvp; float flow; }; int loc_flow = 0; int loc_mvp = 0; bool create(); void draw(const std::vector& samples, const glm::mat4& proj); }; class Stroke { public: struct Keypoint { glm::vec2 pos = { 0, 0 }; float pressure = 0; float dist = 0; }; struct Camera { glm::vec2 rot = { 0, 0 }; float fov = 0; }; int m_layer = 0; float m_curve = 0; float m_dist = 0; float m_step = 0; Camera m_camera; ui::Brush m_brush; cbuffer m_curve_angles; StrokeSample m_prev_sample; std::vector m_keypoints; std::vector m_samples; int m_last_kp; std::minstd_rand prng; void start(const ui::Brush& brush); void add_point(glm::vec2 pos, float pressure); void reset(bool clear_keypoints = false); bool has_sample(); std::vector compute_samples(); StrokeSample randomize_sample(const glm::vec2& pos, float pressure, float curve_angle); }; NS_END