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