From e26fcf11636b566ea3e23c82489b1912e7a28acd Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 22 Jan 2019 22:49:43 +0100 Subject: [PATCH] refactor Brush to be used in shared_ptr --- data/layout.xml | 4 +- src/app_layout.cpp | 45 ++++---------- src/app_vr.cpp | 30 ++++----- src/asset.cpp | 5 ++ src/asset.h | 2 +- src/brush.cpp | 54 +++++++++++----- src/brush.h | 15 +++-- src/canvas.cpp | 36 +++++------ src/canvas.h | 4 +- src/canvas_modes.cpp | 31 +++++----- src/canvas_modes.h | 3 +- src/image.cpp | 25 +++++--- src/node_canvas.cpp | 8 +-- src/node_panel_brush.cpp | 31 +++++++--- src/node_panel_brush.h | 6 +- src/node_panel_color.cpp | 2 +- src/node_panel_stroke.cpp | 120 ++++++++++++++++++++---------------- src/node_panel_stroke.h | 4 +- src/node_stroke_preview.cpp | 10 +-- src/node_stroke_preview.h | 2 +- src/texture.cpp | 12 ++++ src/texture.h | 2 + 22 files changed, 254 insertions(+), 197 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 3bad08e..4cc1e7b 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -163,7 +163,7 @@ - + @@ -179,7 +179,7 @@ - + diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 2502551..61c346e 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -128,39 +128,27 @@ void App::init_sidebar() // if (canvas) // { -// Canvas::I->m_current_brush.m_tip_color = color->m_color; +// Canvas::I->m_current_brush->m_tip_color = color->m_color; // stroke->m_canvas->draw_stroke(); // } - //brushes->on_brush_changed = [this](Node* target, int index) { - // Canvas::I->m_current_brush.m_tex_id = brushes->get_texture_id(index); - // Canvas::I->m_current_brush.id = brushes->get_brush_id(index); - // stroke->m_preview->draw_stroke(); - //}; presets->on_brush_changed = [this](Node* target, int index) { auto b = presets->get_brush(index); // don't change some params - b.m_tip_size = Canvas::I->m_current_brush.m_tip_size; - b.m_tip_color = Canvas::I->m_current_brush.m_tip_color; + b->m_tip_size = Canvas::I->m_current_brush->m_tip_size; + b->m_tip_color = Canvas::I->m_current_brush->m_tip_color; Canvas::I->m_current_brush = b; stroke->m_preview->draw_stroke(); }; - color->on_color_changed = [this](Node* target, glm::vec4 color) { - Canvas::I->m_current_brush.m_tip_color = color; + Canvas::I->m_current_brush->m_tip_color = color; }; -// -// stroke->on_stroke_change = [this](Node*target) { -// if (canvas) -// canvas->m_brush = stroke->m_canvas->m_brush; -// }; - stroke->on_brush_changed = [this](Node* target, int brush_id, uint16_t brush_tex) { - Canvas::I->m_current_brush.m_tex_id = brush_tex; - Canvas::I->m_current_brush.id = brush_id; + stroke->on_brush_changed = [this](Node* target, const std::string& path) { + Canvas::I->m_current_brush->load_texture(path); stroke->m_preview->draw_stroke(); }; - stroke->on_stencil_changed = [this](Node*target, uint16_t id) { - Canvas::I->m_current_brush.m_tex_stencil_id = id; + stroke->on_stencil_changed = [this](Node*target, const std::string& path) { + Canvas::I->m_current_brush->load_stencil(path); stroke->m_preview->draw_stroke(); }; @@ -263,7 +251,7 @@ void App::init_sidebar() panels->fix_scroll(); button->set_color(panels->get_child_index(color.get()) == -1 ? color_button_normal : color_button_hlight); // auto pick = layout[main_id]->add_child(); -// pick->m_color_cur->m_color = Canvas::I->m_current_brush.m_tip_color; +// pick->m_color_cur->m_color = Canvas::I->m_current_brush->m_tip_color; }; } if (auto* button = layout[main_id]->find("btn-layer")) @@ -395,7 +383,7 @@ void App::init_toolbar_draw() if (auto* button = layout[main_id]->find("btn-bucket")) { button->on_click = [this](Node*) { - canvas->m_canvas->clear(Canvas::I->m_current_brush.m_tip_color); + canvas->m_canvas->clear(Canvas::I->m_current_brush->m_tip_color); }; } } @@ -689,7 +677,7 @@ void App::init_menu_about() void App::brush_update() { -// brushes->select_brush(canvas->m_brush.id); +// brushes->select_brush(canvas->m_brush->id); // stroke->set_params(canvas->m_brush); } @@ -826,17 +814,6 @@ void App::initLayout() version_label->set_text(g_version); } - Brush b; - int br_idx = stroke->m_brush_popup->find_brush("Round-Hard"); - b.m_tex_id = stroke->m_brush_popup->get_texture_id(br_idx); - b.id = stroke->m_brush_popup->get_brush_id(br_idx); - b.m_tip_size = .1f; - b.m_tip_flow = .5f; - b.m_tip_spacing = .1f; - b.m_tip_opacity = 1.f; - Canvas::I->m_current_brush = b; - stroke->m_brush_thumb->set_image(stroke->m_brush_popup->get_thumb_path(br_idx)); - brush_update(); TextureManager::load("data/paper.jpg"); diff --git a/src/app_vr.cpp b/src/app_vr.cpp index b81836d..7816180 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -65,7 +65,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index].m_opacity); //ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked); ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active); @@ -86,18 +86,18 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat else if (canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) { sampler.bind(0); - auto& paper = TextureManager::get(canvas->m_canvas->m_current_stroke->m_brush.m_tex_stencil_id); + auto& paper = *canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture; ShaderManager::use(kShader::CompDraw); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size); //ShaderManager::u_int(kShaderUniform::TexStencil, 3); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index].m_opacity); ShaderManager::u_int(kShaderUniform::Lock, canvas->m_canvas->m_layers[layer_index].m_alpha_locked); ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active); - ShaderManager::u_int(kShaderUniform::BlendMode, canvas->m_canvas->m_current_stroke->m_brush.m_blend_mode); + ShaderManager::u_int(kShaderUniform::BlendMode, canvas->m_canvas->m_current_stroke->m_brush->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); canvas->m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); @@ -163,25 +163,25 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat { auto pos = mode->m_resizing ? mode->m_size_pos_start : mode->m_cur_pos; if (App::I.keys[(int)kKey::KeyAlt] && !mode->m_resizing) - pos.x = pos.x - canvas->m_canvas->m_current_brush.m_tip_size * 500; + pos.x = pos.x - canvas->m_canvas->m_current_brush->m_tip_size * 500; auto cur = (glm::vec2(pos.x / width, 1.f - pos.y / height) - 0.5f) * 2.f; ShaderManager::use(kShader::StrokePreview); ShaderManager::u_int(kShaderUniform::Tex, 0); - ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush.m_tip_flow); - auto tip_color = glm::vec4(glm::vec3(canvas->m_canvas->m_current_brush.m_tip_color), 1); + ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush->m_tip_flow); + auto tip_color = glm::vec4(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_color), 1); ShaderManager::u_vec4(kShaderUniform::Col, tip_color); ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera * glm::scale(glm::vec3(100)) * glm::transpose(canvas->m_canvas->m_cam_rot) * glm::translate(glm::vec3(cur * glm::vec2(aspect * tan_fov), -1)) * - glm::scale(glm::vec3(canvas->m_canvas->m_current_brush.m_tip_size * 800.f / App::I.height)) * - glm::eulerAngleZ(canvas->m_canvas->m_current_brush.m_tip_angle * (float)(M_PI * 2.0)) + glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size * 800.f / App::I.height)) * + glm::eulerAngleZ(canvas->m_canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0)) ); glEnable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - auto& tex = TextureManager::get(canvas->m_canvas->m_current_brush.m_tex_id); + auto& tex = *canvas->m_canvas->m_current_brush->m_tip_texture; tex.bind(); sampler_linear.bind(0); m_face_plane.draw_fill(); @@ -238,19 +238,19 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat auto pos = glm::translate(glm::normalize(vr_controller_pos)); ShaderManager::use(kShader::StrokePreview); ShaderManager::u_int(kShaderUniform::Tex, 0); - ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush.m_tip_flow); - auto tip_color = glm::vec4(glm::vec3(canvas->m_canvas->m_current_brush.m_tip_color), 1); + ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush->m_tip_flow); + auto tip_color = glm::vec4(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_color), 1); ShaderManager::u_vec4(kShaderUniform::Col, tip_color); ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera * pos * glm::inverse(glm::lookAt({ 0, 0, 0 }, vr_controller_pos, { 0, 1, 0 })) * //glm::scale(glm::vec3(0.1)) * - glm::scale(glm::vec3(canvas->m_canvas->m_current_brush.m_tip_size * 800.f / App::I.height)) * - glm::eulerAngleZ(canvas->m_canvas->m_current_brush.m_tip_angle * (float)(M_PI * 2.0)) + glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size * 800.f / App::I.height)) * + glm::eulerAngleZ(canvas->m_canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0)) ); glEnable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - auto& tex = TextureManager::get(canvas->m_canvas->m_current_brush.m_tex_id); + auto& tex = *canvas->m_canvas->m_current_brush->m_tip_texture; tex.bind(); sampler_linear.bind(0); m_face_plane.draw_fill(); diff --git a/src/asset.cpp b/src/asset.cpp index 9ec6b56..8d8665d 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -128,6 +128,11 @@ std::string Asset::absolute(const std::string& path) #endif } +bool Asset::is_asset(const std::string & path) +{ + return path.find("data/") != std::string::npos; +} + bool Asset::open(const char* path) { //LOG("Asset::open %s", path); diff --git a/src/asset.h b/src/asset.h index 1fcc440..214f7a6 100644 --- a/src/asset.h +++ b/src/asset.h @@ -11,7 +11,7 @@ public: static bool exist(std::string path, bool is_asset); static bool delete_file(const std::string& path); static std::string absolute(const std::string& path); - + static bool is_asset(const std::string& path); std::string m_current_path; FILE* m_fp = nullptr; int m_len = 0; diff --git a/src/brush.cpp b/src/brush.cpp index 336a613..1108959 100644 --- a/src/brush.cpp +++ b/src/brush.cpp @@ -133,19 +133,19 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa auto rnd_rad = [&] { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi] auto rnd_vec = [&] { float rad = rnd_rad(); return glm::vec3(cosf(rad), sinf(rad), 0); }; // normalized direction vector - float size_dyn = m_brush.m_tip_size_pressure ? pressure : 1.f; - float flow_dyn = m_brush.m_tip_flow_pressure ? pressure : 1.f; + float size_dyn = m_brush->m_tip_size_pressure ? pressure : 1.f; + float flow_dyn = m_brush->m_tip_flow_pressure ? pressure : 1.f; StrokeSample s; s.origin = pos; - s.angle = -curve_angle + (m_brush.m_tip_angle + rnd_nor() * m_brush.m_jitter_angle) * (float)(M_PI * 2.0); - s.pos = pos + (rnd_vec() * m_brush.m_jitter_spread * 100.f); - s.size = 800.f * m_brush.m_tip_size * (1.f - rnd_nor() * m_brush.m_jitter_scale) * size_dyn; - s.flow = m_brush.m_tip_flow * (1.f - rnd_nor() * m_brush.m_jitter_flow) * flow_dyn; - auto hsv = convert_rgb2hsv(m_brush.m_tip_color); - hsv.x = glm::clamp(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush.m_tip_hue * (float)m_brush.m_tip_hue_pressure) + (rnd_nor() - 0.5f) * m_brush.m_jitter_hue, 0.f, 1.f); - hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush.m_tip_sat * (float)m_brush.m_tip_sat_pressure) + (rnd_nor() - 0.5f) * m_brush.m_jitter_sat, 0.f, 1.f); - hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush.m_tip_val * (float)m_brush.m_tip_val_pressure) + (rnd_nor() - 0.5f) * m_brush.m_jitter_val, 0.f, 1.f); + s.angle = -curve_angle + (m_brush->m_tip_angle + rnd_nor() * m_brush->m_jitter_angle) * (float)(M_PI * 2.0); + s.pos = pos + (rnd_vec() * m_brush->m_jitter_spread * 100.f); + s.size = 800.f * m_brush->m_tip_size * (1.f - rnd_nor() * m_brush->m_jitter_scale) * size_dyn; + s.flow = m_brush->m_tip_flow * (1.f - rnd_nor() * m_brush->m_jitter_flow) * flow_dyn; + auto hsv = convert_rgb2hsv(m_brush->m_tip_color); + hsv.x = glm::clamp(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush->m_tip_hue * (float)m_brush->m_tip_hue_pressure) + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue, 0.f, 1.f); + hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush->m_tip_sat * (float)m_brush->m_tip_sat_pressure) + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat, 0.f, 1.f); + hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush->m_tip_val * (float)m_brush->m_tip_val_pressure) + (rnd_nor() - 0.5f) * m_brush->m_jitter_val, 0.f, 1.f); m_hsv_jitter.add(hsv); s.col = convert_hsv2rgb(m_hsv_jitter.average()); return s; @@ -169,7 +169,7 @@ std::vector Stroke::compute_samples() float pressure = glm::lerp(A.pressure, B.pressure, t); auto s = randomize_sample(pos, pressure, 0); - if (m_brush.m_tip_angle_follow) + if (m_brush->m_tip_angle_follow) { auto& pre = m_prev_sample; glm::vec2 v = glm::normalize(s.origin - pre.origin); @@ -214,8 +214,8 @@ void Stroke::add_point(glm::vec3 pos, float pressure) //m_pressure_buff.add(pressure); //pressure = m_pressure_buff.average(); - if (m_brush.m_tip_size_pressure) - m_step = glm::max(m_brush.m_tip_spacing * m_brush.m_tip_size * pressure * 800.f, 1.f); + if (m_brush->m_tip_size_pressure) + m_step = glm::max(m_brush->m_tip_spacing * m_brush->m_tip_size * pressure * 800.f, 1.f); float dist = m_keypoints.empty() ? m_step : m_keypoints.back().dist + glm::distance(m_keypoints.back().pos, pos); @@ -229,7 +229,7 @@ void Stroke::add_point(glm::vec3 pos, float pressure) kp.dist = dist; m_keypoints.push_back(kp); } -void Stroke::start(const Brush& brush) +void Stroke::start(const std::shared_ptr& brush) { m_hold_points.clear(); m_curve = 0.f; @@ -238,8 +238,28 @@ void Stroke::start(const Brush& brush) m_hsv_jitter.clear(); m_last_kp = 0; m_dist = 0.f; - m_brush = brush; - m_brush.m_tip_size *= 1.f / glm::tan(glm::radians(m_camera.fov * 0.5f)); - m_step = glm::max(m_brush.m_tip_spacing * m_brush.m_tip_size * 800.f, 1.f); + m_brush = std::make_shared(*brush); + m_brush->m_tip_size *= 1.f / glm::tan(glm::radians(m_camera.fov * 0.5f)); + m_step = glm::max(m_brush->m_tip_spacing * m_brush->m_tip_size * 800.f, 1.f); prng.seed(0); } + +bool Brush::load_texture(const std::string & path) +{ + m_tip_texture = std::make_shared(); + if (!m_tip_texture->load(path)) + return false; + m_tip_texture->create_mipmaps(); + m_tip_texture->auto_destroy = true; + return true; +} + +bool Brush::load_stencil(const std::string & path) +{ + m_stencil_texture = std::make_shared(); + if (!m_stencil_texture->load(path)) + return false; + m_stencil_texture->create_mipmaps(); + m_stencil_texture->auto_destroy = true; + return true; +} diff --git a/src/brush.h b/src/brush.h index d63a8d9..a4cc8c9 100644 --- a/src/brush.h +++ b/src/brush.h @@ -1,14 +1,19 @@ #pragma once #include "rtt.h" #include "shader.h" +#include "texture.h" class Brush { public: + Brush() = default; + Brush(const Brush& brush) = default; int id = 0; std::string m_name; - uint16_t m_tex_id = 0; - uint16_t m_tex_stencil_id = const_hash("data/paper.jpg"); + std::shared_ptr m_tip_texture; + std::shared_ptr m_stencil_texture; + //uint16_t m_tex_id = 0; + //uint16_t m_tex_stencil_id = const_hash("data/paper.jpg"); glm::vec4 m_tip_color{0, 0, 0, 1}; float m_tip_size = 0; float m_tip_spacing = 0; @@ -36,6 +41,8 @@ public: float m_jitter_sat = 0; float m_jitter_val = 0; int m_blend_mode = 0; + bool load_texture(const std::string& path); + bool load_stencil(const std::string& path); }; struct StrokeSample @@ -88,7 +95,7 @@ public: float m_dist = 0; float m_step = 0; Camera m_camera; - Brush m_brush; + std::shared_ptr m_brush; cbuffer m_curve_angles; cbuffer m_pressure_buff; cbuffer m_hsv_jitter; @@ -98,7 +105,7 @@ public: std::vector m_samples; int m_last_kp; std::minstd_rand prng; - void start(const Brush& brush); + void start(const std::shared_ptr& brush); void add_point(glm::vec3 pos, float pressure); void reset(bool clear_keypoints = false); bool has_sample(); diff --git a/src/canvas.cpp b/src/canvas.cpp index 843be37..6b29076 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -304,7 +304,7 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) m_sampler.bind(0); m_sampler.bind(1); m_sampler.bind(2); - auto& paper = TextureManager::get(m_current_stroke->m_brush.m_tex_stencil_id); + auto& paper = *m_current_stroke->m_brush->m_stencil_texture; ShaderManager::use(kShader::CompDraw); ShaderManager::u_int(kShaderUniform::Tex, 0); //ShaderManager::u_int(kShaderUniform::TexA, 0); @@ -312,12 +312,12 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) ShaderManager::u_int(kShaderUniform::TexMask, 2); //ShaderManager::u_vec2(kShaderUniform::Resolution, m_size); //ShaderManager::u_int(kShaderUniform::TexStencil, 3); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, 1); ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index].m_alpha_locked); ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); - ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode); + ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); m_layers[layer_index].m_rtt[plane_index].bindTexture(); @@ -357,10 +357,10 @@ void Canvas::stroke_draw() float zoom = m_node->root()->m_zoom; - auto m_brush = m_current_stroke->m_brush; + const auto& m_brush = m_current_stroke->m_brush; auto samples = m_current_stroke->compute_samples(); - auto& tex = TextureManager::get(m_brush.m_tex_id); - auto& stencil = TextureManager::get(m_brush.m_tex_stencil_id); + auto& tex = *m_brush->m_tip_texture; + auto& stencil = *m_brush->m_stencil_texture; auto ortho_proj = glm::ortho(0.f, (float)m_width, 0.f, (float)m_height, -1.f, 1.f); std::vector B{ @@ -396,10 +396,10 @@ void Canvas::stroke_draw() //ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); ShaderManager::u_vec2(kShaderUniform::StencilOffset, stencil_offset); - ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil); - ShaderManager::u_float(kShaderUniform::MixAlpha, m_brush.m_tip_mix); - ShaderManager::u_float(kShaderUniform::Wet, m_brush.m_tip_wet); - ShaderManager::u_float(kShaderUniform::Noise, m_brush.m_tip_noise); + ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush->m_tip_stencil); + ShaderManager::u_float(kShaderUniform::MixAlpha, m_brush->m_tip_mix); + ShaderManager::u_float(kShaderUniform::Wet, m_brush->m_tip_wet); + ShaderManager::u_float(kShaderUniform::Noise, m_brush->m_tip_noise); auto unp_vp = zw(m_box); auto unp_inv = glm::inverse(m_proj * m_mv); @@ -443,7 +443,7 @@ void Canvas::stroke_draw() } auto bb_sz = bb_max - bb_min; - if (m_brush.m_tip_mix > 0.f) + if (m_brush->m_tip_mix > 0.f) { stroke_draw_mix(bb_min, bb_sz); @@ -569,7 +569,7 @@ void Canvas::stroke_draw() ShaderManager::use(kShader::Stroke); ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj); - ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush.m_tip_color.a)); + ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush->m_tip_color.a)); ShaderManager::u_float(kShaderUniform::Alpha, s.flow); if (P.size() == 4) @@ -827,7 +827,7 @@ void Canvas::stroke_commit() ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, 1); ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); @@ -846,18 +846,18 @@ void Canvas::stroke_commit() } else { - auto& paper = TextureManager::get(m_current_stroke->m_brush.m_tex_stencil_id); + auto& paper = *m_current_stroke->m_brush->m_stencil_texture; ShaderManager::use(kShader::CompDraw); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); //ShaderManager::u_vec2(kShaderUniform::Resolution, m_size); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, 1); ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); - ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode); + ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); glActiveTexture(GL_TEXTURE0); @@ -882,7 +882,7 @@ void Canvas::stroke_commit() // ShaderManager::use(kShader::StrokeLayer); // ShaderManager::u_int(kShaderUniform::TexBG, 1); // ShaderManager::u_int(kShaderUniform::Lock, m_layers[m_current_layer_idx].m_alpha_locked); -// ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity); +// ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush->m_tip_opacity); // // ShaderManager::u_int(kShaderUniform::Tex, 0); // ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); @@ -912,7 +912,7 @@ void Canvas::stroke_update(glm::vec3 point, float pressure) { m_current_stroke->add_point(point, pressure); } -void Canvas::stroke_start(glm::vec3 point, float pressure, const Brush& brush) +void Canvas::stroke_start(glm::vec3 point, float pressure, const std::shared_ptr& brush) { // need to commit this now before starting a new stroke if (m_current_stroke && m_commit_delayed) diff --git a/src/canvas.h b/src/canvas.h index f9bdd1f..e06de2d 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -191,7 +191,7 @@ public: float m_cam_fov = 85; glm::vec2 m_cur_pos; - Brush m_current_brush; + std::shared_ptr m_current_brush; enum class kCanvasMode { Draw, Erase, Line, Camera, Grid, Transform, Fill, MaskFree, MaskLine, COUNT }; kCanvasMode m_state{ kCanvasMode::Draw }; @@ -220,7 +220,7 @@ public: void layer_add(std::string name); void layer_order(int idx, int pos); void layer_merge(int source_idx, int dest_idx); - void stroke_start(glm::vec3 point, float pressure, const Brush& brush); + void stroke_start(glm::vec3 point, float pressure, const std::shared_ptr& brush); void stroke_update(glm::vec3 point, float pressure); void stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz); void stroke_draw(); diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index bc4561f..b962533 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -120,7 +120,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_picking = true; canvas->pick_start(); glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush.m_tip_color = pix; + canvas->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); } else @@ -140,7 +140,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { node->mouse_release(); glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush.m_tip_color = pix; + canvas->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); canvas->pick_end(); } @@ -153,7 +153,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_resizing = true; m_dragging = true; m_size_pos_start = m_cur_pos; - m_size_value_start = canvas->m_current_brush.m_tip_size; + m_size_value_start = canvas->m_current_brush->m_tip_size; node->mouse_capture(); } break; @@ -171,13 +171,13 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) if (m_dragging && m_picking) { glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush.m_tip_color = pix; + canvas->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); } if (m_dragging && m_resizing) { auto diff = m_cur_pos - m_size_pos_start; - canvas->m_current_brush.m_tip_size = m_size_value_start + diff.x * 0.001f; + canvas->m_current_brush->m_tip_size = m_size_value_start + diff.x * 0.001f; } m_cur_pos = loc; break; @@ -204,14 +204,14 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const { auto pos = m_resizing ? m_size_pos_start : m_cur_pos; if (App::I.keys[(int)kKey::KeyAlt] && !m_resizing) - pos.x = pos.x - canvas->m_current_brush.m_tip_size * 500.f; + pos.x = pos.x - canvas->m_current_brush->m_tip_size * 500.f; ShaderManager::use(kShader::StrokePreview); ShaderManager::u_int(kShaderUniform::Tex, 0); float tip_scale_fix = 1.f / glm::tan(glm::radians(Canvas::I->m_cam_fov * 0.5f)); - float tip_scale = canvas->m_current_brush.m_tip_size * 800.f * tip_scale_fix; - float tip_angle = canvas->m_current_brush.m_tip_angle * (float)(M_PI * 2.0); + float tip_scale = canvas->m_current_brush->m_tip_size * 800.f * tip_scale_fix; + float tip_angle = canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0); glm::vec2 tip_offset = glm::vec2(0); - auto tip_color = glm::vec4(glm::vec3(canvas->m_current_brush.m_tip_color), 1); + auto tip_color = glm::vec4(glm::vec3(canvas->m_current_brush->m_tip_color), 1); if (canvas->m_current_stroke) { const auto& s = canvas->m_current_stroke->m_prev_sample; @@ -234,7 +234,7 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const bool blend = glIsEnabled(GL_BLEND); glEnable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - auto& tex = TextureManager::get(canvas->m_current_brush.m_tex_id); + auto& tex = *canvas->m_current_brush->m_tip_texture; tex.bind(); canvas->m_sampler_brush.bind(0); canvas->m_plane.draw_fill(); @@ -245,21 +245,20 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const void CanvasModePen::leave() { - m_brush = canvas->m_current_brush; + *m_brush = *canvas->m_current_brush; } void CanvasModePen::enter() { m_cur_pos = Canvas::I->m_cur_pos; - if (m_valid_brush) + if (m_brush) { - canvas->m_current_brush = m_brush; + *canvas->m_current_brush = *m_brush; App::I.brush_update(); } else { - m_brush = canvas->m_current_brush; - m_valid_brush = true; + m_brush = std::make_shared(*canvas->m_current_brush); } } @@ -306,7 +305,7 @@ void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons { ShaderManager::use(kShader::Color); ShaderManager::u_mat4(kShaderUniform::MVP, ortho); - ShaderManager::u_vec4(kShaderUniform::Col, canvas->m_current_brush.m_tip_color); + ShaderManager::u_vec4(kShaderUniform::Col, canvas->m_current_brush->m_tip_color); static glm::vec4 AB[2]; AB[0] = { m_drag_start, 0, 1 }; AB[1] = { m_drag_pos, 0, 1 }; diff --git a/src/canvas_modes.h b/src/canvas_modes.h index c48bb89..82ea8aa 100644 --- a/src/canvas_modes.h +++ b/src/canvas_modes.h @@ -62,8 +62,7 @@ class CanvasModePen : public CanvasMode float m_camera_fov; float m_zoom_canvas = 1.f; float m_zoom_start; - bool m_valid_brush = false; - Brush m_brush; + std::shared_ptr m_brush; // resizing the tip bool m_resizing = false; public: diff --git a/src/image.cpp b/src/image.cpp index cbba7fb..6bf22ac 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -7,18 +7,25 @@ bool Image::load(std::string filename) { - stbi_set_flip_vertically_on_load(false); - Asset file; - if (!(file.open(filename.c_str()) && file.read_all())) + if (Asset::is_asset(filename)) { + Asset file; + if (!(file.open(filename.c_str()) && file.read_all())) + { + file.close(); + return false; + } + stbi_set_flip_vertically_on_load(false); + uint8_t* buffer = stbi_load_from_memory(file.m_data, file.m_len, &width, &height, nullptr, 4); file.close(); - return false; + comp = 4; + m_data = std::unique_ptr(buffer); + return true; + } + else + { + return load_file(filename); } - uint8_t* buffer = stbi_load_from_memory(file.m_data, file.m_len, &width, &height, nullptr, 4); - file.close(); - comp = 4; - m_data = std::unique_ptr(buffer); - return true; } bool Image::load_file(std::string filename) diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index e962abc..a24ec73 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -179,7 +179,7 @@ void NodeCanvas::draw() ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); //ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked); @@ -201,19 +201,19 @@ void NodeCanvas::draw() else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { m_sampler.bind(0); - auto& paper = TextureManager::get(m_canvas->m_current_stroke->m_brush.m_tex_stencil_id); + auto& paper = *m_canvas->m_current_stroke->m_brush->m_stencil_texture; ShaderManager::use(kShader::CompDraw); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); //ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom); //ShaderManager::u_int(kShaderUniform::TexStencil, 3); - ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity); + ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush->m_tip_opacity); ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity); ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked); ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); - ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_current_stroke->m_brush.m_blend_mode); + ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_current_stroke->m_brush->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 08ab7ca..d954a84 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -120,6 +120,11 @@ uint16_t NodePanelBrush::get_texture_id(int index) const return m_brushes[index]->high_id; } +std::string NodePanelBrush::get_texture_path(int index) const +{ + return m_brushes[index]->high_path; +} + std::string NodePanelBrush::get_thumb_path(int index) const { return m_brushes[index]->thumb_path; @@ -201,14 +206,15 @@ void NodePanelBrushPreset::init() brush->thumb_path = path; brush->high_path = path_hi; brush->high_id = const_hash(path_hi.c_str()); - brush->m_brush.m_tex_id = const_hash(path.c_str()); - brush->m_brush.m_tip_size = .05; - brush->m_brush.m_tip_flow = .2; - brush->m_brush.m_tip_opacity = 1; - brush->m_brush.m_tip_spacing = 0.03; - //brush->m_brush.m_jitter_spread = (rand() % 1000) * 0.0001; + brush->m_brush = std::make_shared(); + //brush->m_brush->m_tex_id = const_hash(path.c_str()); + brush->m_brush->m_tip_size = .05; + brush->m_brush->m_tip_flow = .2; + brush->m_brush->m_tip_opacity = 1; + brush->m_brush->m_tip_spacing = 0.03; + //brush->m_brush->m_jitter_spread = (rand() % 1000) * 0.0001; brush->m_preview->m_brush = brush->m_brush; - brush->m_preview->draw_stroke(); + //brush->m_preview->draw_stroke(); brush->m_thumb->m_path = path; brush->m_thumb->m_tex_id = const_hash(path.c_str()); brush->m_thumb->create(); @@ -230,11 +236,11 @@ void NodePanelBrushPreset::handle_click(Node* target) on_brush_changed(this, m_current->m_brushID); } -Brush NodePanelBrushPreset::get_brush(int index) const +std::shared_ptr NodePanelBrushPreset::get_brush(int index) const { - auto b = m_brushes[index]->m_brush; + auto& b = m_brushes[index]->m_brush; TextureManager::load(m_brushes[index]->high_path.c_str(), true); - b.m_tex_id = m_brushes[index]->high_id; + //b->m_tex_id = m_brushes[index]->high_id; return b; } @@ -244,6 +250,11 @@ uint16_t NodePanelBrushPreset::get_texture_id(int index) const return m_brushes[index]->high_id; } +std::string NodePanelBrushPreset::get_texture_path(int index) const +{ + return m_brushes[index]->high_path; +} + int NodePanelBrushPreset::get_brush_id(int index) const { return m_brushes[index]->m_brushID; diff --git a/src/node_panel_brush.h b/src/node_panel_brush.h index a1e5d32..68febcd 100644 --- a/src/node_panel_brush.h +++ b/src/node_panel_brush.h @@ -35,6 +35,7 @@ public: std::vector FindAllBrushes(const std::string& folder); int find_brush(const std::string& name) const; uint16_t get_texture_id(int index) const; + std::string get_texture_path(int index) const; std::string get_thumb_path(int index) const; int get_brush_id(int index) const; void select_brush(int brush_id); @@ -46,7 +47,7 @@ class NodeBrushPresetItem : public NodeButtonCustom { public: int m_brushID; - Brush m_brush; + std::shared_ptr m_brush; std::string high_path; std::string thumb_path; uint16_t high_id; @@ -69,7 +70,8 @@ public: virtual void init() override; void handle_click(Node* target); uint16_t get_texture_id(int index) const; - Brush get_brush(int index) const; + std::string get_texture_path(int index) const; + std::shared_ptr get_brush(int index) const; int get_brush_id(int index) const; }; diff --git a/src/node_panel_color.cpp b/src/node_panel_color.cpp index 08ab0ae..91352c7 100644 --- a/src/node_panel_color.cpp +++ b/src/node_panel_color.cpp @@ -55,5 +55,5 @@ void NodePanelColor::set_color(glm::vec3 rgb) void NodePanelColor::added(Node* parent) { - set_color(Canvas::I->m_current_brush.m_tip_color); + set_color(Canvas::I->m_current_brush->m_tip_color); } diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index b2532ca..471672f 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -25,34 +25,75 @@ void NodePanelStroke::init() void NodePanelStroke::update_controls() { const auto& b = Canvas::I->m_current_brush; - m_tip_size->m_value.x = glm::pow(b.m_tip_size, 1.f/3.f); - m_tip_spacing->m_value.x = glm::pow(b.m_tip_spacing, 1.f/2.f) / 4.f; - m_tip_flow->m_value.x = glm::pow(b.m_tip_flow, 1.f/2.f); - m_tip_opacity->m_value.x = b.m_tip_opacity; - m_tip_angle->m_value.x = b.m_tip_angle; - m_tip_stencil->m_value.x = b.m_tip_stencil; - m_tip_wet->m_value.x = b.m_tip_wet; - m_tip_noise->m_value.x = b.m_tip_noise; - m_jitter_scale->m_value.x = b.m_jitter_scale; - m_jitter_angle->m_value.x = b.m_jitter_angle; - m_jitter_spread->m_value.x = b.m_jitter_spread; - m_jitter_flow->m_value.x = b.m_jitter_flow; - m_jitter_hue->m_value.x = b.m_jitter_hue; - m_jitter_sat->m_value.x = b.m_jitter_sat; - m_jitter_val->m_value.x = b.m_jitter_val; - m_tip_angle_follow->checked = b.m_tip_angle_follow; - m_tip_flow_pressure->checked = b.m_tip_flow_pressure; - m_tip_size_pressure->checked = b.m_tip_size_pressure; + m_tip_size->m_value.x = glm::pow(b->m_tip_size, 1.f/3.f); + m_tip_spacing->m_value.x = glm::pow(b->m_tip_spacing, 1.f/2.f) / 4.f; + m_tip_flow->m_value.x = glm::pow(b->m_tip_flow, 1.f/2.f); + m_tip_opacity->m_value.x = b->m_tip_opacity; + m_tip_angle->m_value.x = b->m_tip_angle; + m_tip_stencil->m_value.x = b->m_tip_stencil; + m_tip_wet->m_value.x = b->m_tip_wet; + m_tip_noise->m_value.x = b->m_tip_noise; + m_jitter_scale->m_value.x = b->m_jitter_scale; + m_jitter_angle->m_value.x = b->m_jitter_angle; + m_jitter_spread->m_value.x = b->m_jitter_spread; + m_jitter_flow->m_value.x = b->m_jitter_flow; + m_jitter_hue->m_value.x = b->m_jitter_hue; + m_jitter_sat->m_value.x = b->m_jitter_sat; + m_jitter_val->m_value.x = b->m_jitter_val; + m_tip_angle_follow->checked = b->m_tip_angle_follow; + m_tip_flow_pressure->checked = b->m_tip_flow_pressure; + m_tip_size_pressure->checked = b->m_tip_size_pressure; m_preview->m_brush = b; m_preview->draw_stroke(); } void NodePanelStroke::init_controls() { + m_brush_popup = std::make_shared(); + m_brush_popup->m_manager = m_manager; + m_brush_popup->init(); + m_brush_popup->create(); + m_brush_popup->loaded(); + m_brush_popup->SetPositioning(YGPositionTypeAbsolute); + m_brush_popup->SetSize(400, 400); + m_brush_popup->m_mouse_ignore = false; + m_brush_popup->m_flood_events = true; + m_brush_popup->m_capture_children = false; + + auto b = std::make_shared(); + int br_idx = m_brush_popup->find_brush("Round-Hard"); + b->load_texture(m_brush_popup->get_texture_path(br_idx)); + b->load_stencil("data/paper.jpg"); + b->m_tip_size = .1f; + b->m_tip_flow = .5f; + b->m_tip_spacing = .1f; + b->m_tip_opacity = 1.f; + Canvas::I->m_current_brush = b; + + m_brush_thumb = find("tip-change-thumb"); + m_brush_thumb->set_image(m_brush_popup->get_thumb_path(br_idx)); + + m_brush_button = find("tip-change"); + m_brush_button->on_click = [this](Node*) { + glm::vec2 pos = m_brush_button->m_pos + glm::vec2(m_brush_button->m_size.x, 0); + root()->add_child(m_brush_popup); + m_brush_popup->SetPosition(pos.x, pos.y); + m_brush_popup->mouse_capture(); + root()->update(); + + m_brush_popup->on_brush_changed = [this](Node*, int index) { + if (on_brush_changed) + on_brush_changed(this, m_brush_popup->get_texture_path(index)); + m_brush_thumb->set_image(m_brush_popup->get_thumb_path(index)); + m_brush_popup->mouse_release(); + m_brush_popup->parent->remove_child(m_brush_popup.get()); + }; + }; + m_preview = find("canvas"); m_blend_mode = find("blend-mode"); m_blend_mode->on_select = [](Node*, int index) { - Canvas::I->m_current_brush.m_blend_mode = index; + Canvas::I->m_current_brush->m_blend_mode = index; }; init_slider(m_tip_size, "tip-size", &Brush::m_tip_size); @@ -91,42 +132,17 @@ void NodePanelStroke::init_controls() auto load_stencil = find("tip-stencil-load"); load_stencil->on_click = [this](Node*) { App::I.pick_image([this](std::string path) { + App::I.async_start(); if (TextureManager::load(path.c_str())) { if (on_stencil_changed) - on_stencil_changed(this, const_hash(path.c_str())); + on_stencil_changed(this, path); } + App::I.async_redraw(); + App::I.async_end(); }); }; - m_brush_popup = std::make_shared(); - m_brush_popup->m_manager = m_manager; - m_brush_popup->init(); - m_brush_popup->create(); - m_brush_popup->loaded(); - m_brush_popup->SetPositioning(YGPositionTypeAbsolute); - m_brush_popup->SetSize(400, 400); - m_brush_popup->m_mouse_ignore = false; - m_brush_popup->m_flood_events = true; - m_brush_popup->m_capture_children = false; - - m_brush_thumb = find("tip-change-thumb"); - m_brush_button = find("tip-change"); - m_brush_button->on_click = [this](Node*) { - glm::vec2 pos = m_brush_button->m_pos + glm::vec2(m_brush_button->m_size.x, 0); - root()->add_child(m_brush_popup); - m_brush_popup->SetPosition(pos.x, pos.y); - m_brush_popup->mouse_capture(); - root()->update(); - - m_brush_popup->on_brush_changed = [this](Node*, int index) { - if (on_brush_changed) - on_brush_changed(this, m_brush_popup->get_brush_id(index), m_brush_popup->get_texture_id(index)); - m_brush_thumb->set_image(m_brush_popup->get_thumb_path(index)); - m_brush_popup->mouse_release(); - m_brush_popup->parent->remove_child(m_brush_popup.get()); - }; - }; } void NodePanelStroke::init_slider(NodeSliderH*& target, const char* id, float Brush::* prop) @@ -134,13 +150,13 @@ void NodePanelStroke::init_slider(NodeSliderH*& target, const char* id, float Br target = find(id); target->on_value_changed = std::bind(&NodePanelStroke::handle_slide, this, prop, std::placeholders::_1, std::placeholders::_2); - //m_canvas->m_brush.*prop = target->m_value.x; + //m_canvas->m_brush->*prop = target->m_value.x; } void NodePanelStroke::handle_slide(float Brush::* prop, Node* target, float value) { auto curve = m_curves.find((NodeSliderH*)target); - Canvas::I->m_current_brush.*prop = curve != m_curves.end() ? curve->second(value) : value; + Canvas::I->m_current_brush.get()->*prop = curve != m_curves.end() ? curve->second(value) : value; m_preview->m_brush = Canvas::I->m_current_brush; m_preview->draw_stroke(); if (on_stroke_change) @@ -152,12 +168,12 @@ void NodePanelStroke::init_checkbox(NodeCheckBox*& target, const char* id, bool target = find(id); target->on_value_changed = std::bind(&NodePanelStroke::handle_checkbox, this, prop, std::placeholders::_1, std::placeholders::_2); - Canvas::I->m_current_brush.*prop = target->checked; + Canvas::I->m_current_brush.get()->*prop = target->checked; } void NodePanelStroke::handle_checkbox(bool Brush::* prop, Node *target, bool value) { - Canvas::I->m_current_brush.*prop = value; + Canvas::I->m_current_brush.get()->*prop = value; m_preview->m_brush = Canvas::I->m_current_brush; m_preview->draw_stroke(); if (on_stroke_change) diff --git a/src/node_panel_stroke.h b/src/node_panel_stroke.h index 3a50863..cd2a5cb 100644 --- a/src/node_panel_stroke.h +++ b/src/node_panel_stroke.h @@ -43,8 +43,8 @@ public: NodeImage* m_brush_thumb; std::shared_ptr m_brush_popup; std::function on_stroke_change; - std::function on_stencil_changed; - std::function on_brush_changed; + std::function on_stencil_changed; + std::function on_brush_changed; std::map> m_curves; virtual Node* clone_instantiate() const override; diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 53dc6de..230b43c 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -67,7 +67,7 @@ void NodeStrokePreview::draw_stroke() glEnable(GL_BLEND); glm::mat4 proj = glm::ortho(0, (float)m_rtt.getWidth(), 0, (float)m_rtt.getHeight(), -1, 1); - auto b = m_brush; + const auto& b = m_brush; m_stroke.m_camera.fov = Canvas::I->m_cam_fov; m_stroke.m_camera.rot = Canvas::I->m_cam_rot; m_stroke.reset(); @@ -75,12 +75,12 @@ void NodeStrokePreview::draw_stroke() if (!m_stroke.m_keypoints.empty()) m_stroke.m_prev_sample.origin = m_stroke.m_keypoints[0].pos; auto samples = m_stroke.compute_samples(); - auto& tex = TextureManager::get(b.m_tex_id); + auto& tex = *b->m_tip_texture; glActiveTexture(GL_TEXTURE0); tex.bind(); m_sampler_brush.bind(0); - auto& stencil = TextureManager::get(b.m_tex_stencil_id); + auto& stencil = *b->m_stencil_texture; glActiveTexture(GL_TEXTURE1); stencil.bind(); m_sampler.bind(1); @@ -93,13 +93,13 @@ void NodeStrokePreview::draw_stroke() ShaderManager::u_int(kShaderUniform::TexStencil, 1); // stencil ShaderManager::u_vec2(kShaderUniform::Resolution, { m_rtt.getWidth(), m_rtt.getHeight() }); ShaderManager::u_vec2(kShaderUniform::StencilOffset, glm::vec2(0)); - ShaderManager::u_float(kShaderUniform::StencilAlpha, b.m_tip_stencil); + ShaderManager::u_float(kShaderUniform::StencilAlpha, b->m_tip_stencil); m_mesh.draw(samples, proj); } //else //{ // ShaderManager::use("stroke"); - // ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color); + // ShaderManager::u_vec4(kShaderUniform::Col, m_brush->m_tip_color); // ShaderManager::u_int(kShaderUniform::Tex, 0); // for (const auto& s : samples) // { diff --git a/src/node_stroke_preview.h b/src/node_stroke_preview.h index d4a207c..e2afb5a 100644 --- a/src/node_stroke_preview.h +++ b/src/node_stroke_preview.h @@ -11,7 +11,7 @@ class NodeStrokePreview : public NodeBorder Sampler m_sampler_brush; BrushMesh m_mesh; public: - Brush m_brush; + std::shared_ptr m_brush; Stroke m_stroke; std::vector m_bez_points; virtual Node* clone_instantiate() const override; diff --git a/src/texture.cpp b/src/texture.cpp index 1001aaa..a91c329 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -2,6 +2,7 @@ #include "log.h" #include "texture.h" #include "util.h" +#include "app.h" std::map TextureManager::m_textures; @@ -107,6 +108,17 @@ glm::vec2 Texture2D::size() const return { m_width, m_height }; } +Texture2D::~Texture2D() +{ + if (auto_destroy) + { + LOG("Texture2D auto destroy"); + App::I.async_start(); + destroy(); + App::I.async_end(); + } +} + bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/) { #if USE_SAMPLER diff --git a/src/texture.h b/src/texture.h index 13cf103..8dee49e 100644 --- a/src/texture.h +++ b/src/texture.h @@ -9,6 +9,7 @@ class Texture2D GLint m_format = 0; GLint m_iformat = 0; public: + bool auto_destroy = false; bool has_mips = false; bool create(int width, int height, GLint internal_format = GL_RGBA8, GLint format = GL_RGBA, const uint8_t* data = nullptr); bool create(const Image& img); @@ -22,6 +23,7 @@ public: bool ready() const { return m_tex != 0; } void create_mipmaps(); glm::vec2 size() const; + ~Texture2D(); }; class Sampler