refactor Brush to be used in shared_ptr

This commit is contained in:
2019-01-22 22:49:43 +01:00
parent 9e76cf3194
commit e26fcf1163
22 changed files with 254 additions and 197 deletions

View File

@@ -163,7 +163,7 @@
<border color=".2" height="20" justify="center" align="center"><text text="Tip Settings" font-face="arial" font-size="11"/></border>
<node dir="row">
<node width="30%" dir="col">
<node height="20" justify="center" margin="5 0 5 0"><text text="Shade" font-face="arial" font-size="11"/></node>
<!--<node height="20" justify="center" margin="5 0 5 0"><text text="Shade" font-face="arial" font-size="11"/></node>-->
<node height="30" justify="center" margin="5 0 5 0"><text text="Blend" font-face="arial" font-size="11"/></node>
<node height="20" justify="center"><text text="Size" font-face="arial" font-size="11"/></node>
<node height="20" justify="center"><text text="Flow" font-face="arial" font-size="11"/></node>
@@ -179,7 +179,7 @@
<node height="20" justify="center"><text text="Val" font-face="arial" font-size="11"/></node>
</node>
<node dir="col" align="center" grow="1" width="1" flood-events="1">
<node height="20" pad="1" width="100%" margin="5 0 5 0"><slider-h id="tip-shade" value="1"/></node>
<!--<node height="20" pad="1" width="100%" margin="5 0 5 0"><slider-h id="tip-shade" value="1"/></node>-->
<node height="30" pad="1" width="100%" dir="row" margin="5 0 5 0">
<combobox id="blend-mode" text="Normal" width="100%" height="30" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
</node>

View File

@@ -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<NodeColorPicker>();
// 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<NodeButtonCustom>("btn-layer"))
@@ -395,7 +383,7 @@ void App::init_toolbar_draw()
if (auto* button = layout[main_id]->find<NodeButtonCustom>("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");

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<StrokeSample> 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>& 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>(*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<Texture2D>();
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<Texture2D>();
if (!m_stencil_texture->load(path))
return false;
m_stencil_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true;
return true;
}

View File

@@ -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<Texture2D> m_tip_texture;
std::shared_ptr<Texture2D> 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<Brush> m_brush;
cbuffer<float, 3> m_curve_angles;
cbuffer<float, 10> m_pressure_buff;
cbuffer<glm::vec3, 3> m_hsv_jitter;
@@ -98,7 +105,7 @@ public:
std::vector<StrokeSample> m_samples;
int m_last_kp;
std::minstd_rand prng;
void start(const Brush& brush);
void start(const std::shared_ptr<Brush>& brush);
void add_point(glm::vec3 pos, float pressure);
void reset(bool clear_keypoints = false);
bool has_sample();

View File

@@ -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<vertex_t> 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>& brush)
{
// need to commit this now before starting a new stroke
if (m_current_stroke && m_commit_delayed)

View File

@@ -191,7 +191,7 @@ public:
float m_cam_fov = 85;
glm::vec2 m_cur_pos;
Brush m_current_brush;
std::shared_ptr<Brush> 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>& 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();

View File

@@ -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<Brush>(*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 };

View File

@@ -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<Brush> m_brush;
// resizing the tip
bool m_resizing = false;
public:

View File

@@ -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<uint8_t[]>(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<uint8_t[]>(buffer);
return true;
}
bool Image::load_file(std::string filename)

View File

@@ -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();

View File

@@ -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>();
//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<Brush> 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;

View File

@@ -35,6 +35,7 @@ public:
std::vector<std::string> 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<Brush> 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<Brush> get_brush(int index) const;
int get_brush_id(int index) const;
};

View File

@@ -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);
}

View File

@@ -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<NodePanelBrush>();
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<Brush>();
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<NodeImage>("tip-change-thumb");
m_brush_thumb->set_image(m_brush_popup->get_thumb_path(br_idx));
m_brush_button = find<NodeButtonCustom>("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<NodeStrokePreview>("canvas");
m_blend_mode = find<NodeComboBox>("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<NodeButton>("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<NodePanelBrush>();
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<NodeImage>("tip-change-thumb");
m_brush_button = find<NodeButtonCustom>("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<NodeSliderH>(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<NodeCheckBox>(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)

View File

@@ -43,8 +43,8 @@ public:
NodeImage* m_brush_thumb;
std::shared_ptr<NodePanelBrush> m_brush_popup;
std::function<void(Node* target)> on_stroke_change;
std::function<void(Node* target, uint16_t id)> on_stencil_changed;
std::function<void(Node* target, int brush_id, uint16_t brush_tex)> on_brush_changed;
std::function<void(Node* target, const std::string& path)> on_stencil_changed;
std::function<void(Node* target, const std::string& path)> on_brush_changed;
std::map<NodeSliderH*, std::function<float(float)>> m_curves;
virtual Node* clone_instantiate() const override;

View File

@@ -67,7 +67,7 @@ void NodeStrokePreview::draw_stroke()
glEnable(GL_BLEND);
glm::mat4 proj = glm::ortho<float>(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)
// {

View File

@@ -11,7 +11,7 @@ class NodeStrokePreview : public NodeBorder
Sampler m_sampler_brush;
BrushMesh m_mesh;
public:
Brush m_brush;
std::shared_ptr<Brush> m_brush;
Stroke m_stroke;
std::vector<glm::vec2> m_bez_points;
virtual Node* clone_instantiate() const override;

View File

@@ -2,6 +2,7 @@
#include "log.h"
#include "texture.h"
#include "util.h"
#include "app.h"
std::map<uint16_t, Texture2D> 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

View File

@@ -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