rename texture to pattern and implement initial pattern settings

This commit is contained in:
2019-02-17 23:41:17 +01:00
parent 49d9b17719
commit e4ee87e4c6
16 changed files with 379 additions and 232 deletions

View File

@@ -24,7 +24,7 @@
<!--layers panel template-->
<layout id="tpl-panel-layers">
<node width="220" margin="0 0 10 0" rtl="ltr">
<node width="250" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
<text text="Layers" color="1 1 1 1"/>
</border>
@@ -121,7 +121,7 @@
<!--color panel-->
<layout id="tpl-panel-color">
<node width="220" margin="0 0 10 0" rtl="ltr">
<node width="250" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center">
<text text="Colors" color="1 1 1 1"/>
</border>
@@ -134,7 +134,7 @@
<!--stroke panel-->
<layout id="tpl-panel-stroke">
<node width="220" margin="0 0 10 0" rtl="ltr">
<node width="250" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center">
<text text="Stroke" color="1 1 1 1"/>
</border>
@@ -149,7 +149,7 @@
<!-- PRESET AND SHAPE -->
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--<node height="20" justify="center" margin="5 0 5 0"><text text="Shade"/></node>-->
<node height="40" justify="center" margin="5 0 0 0">
<text text="Preset"/>
@@ -199,7 +199,7 @@
<text text="Color"/>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="30" justify="center" margin="0 0 5 0">
<text text="Blend"/>
@@ -235,7 +235,7 @@
<text text="Metrics"/>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="20" justify="center" margin="0 0 20 0">
<text text="Size"/>
@@ -275,28 +275,82 @@
</node>
</node>
<!-- TEXTURE -->
<!-- PATTERN -->
<border color=".2" height="20" dir="row" justify="center" align="center" margin="5 0 5 0">
<checkbox id="tex-enabled" width="20" height="20"/>
<checkbox id="pattern-enabled" width="20" height="20"/>
<node align="center" width="1" grow="1">
<text text="Texture"/>
<text text="Pattern"/>
</node>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="40" justify="center">
<node height="40" justify="center" margin="0 0 5 0">
<text text="Pattern"/>
</node>
<node height="30" justify="center" margin="0 0 5 0">
<text text="Blend"/>
</node>
<node height="30" justify="center" margin="0 0 5 0">
<text text="Projection"/>
</node>
<node height="20" justify="center">
<text text="Apply"/>
</node>
<node height="20" justify="center">
<text text="Opacity"/>
</node>
<node height="20" justify="center">
<text text="Scale"/>
</node>
<node height="20" justify="center">
<text text="Brightness"/>
</node>
<node height="20" justify="center">
<text text="Contrast"/>
</node>
</node>
<node dir="col" align="center" grow="1" width="1">
<node dir="col" grow="1" width="1">
<!--controls-->
<node height="40" width="100%" dir="row">
<slider-h id="tip-stencil" width="1" grow="1" height="30" margin="5 5 5 0"/>
<button-custom id="texture-change" width="40" height="40" dir="row" pad="4">
<image id="texture-change-thumb" width="32" height="100%"/>
<node dir="row" margin="0 0 5 0">
<button-custom id="pattern-change" width="40" height="40" dir="row" pad="4">
<image id="pattern-change-thumb" width="32" height="100%"/>
</button-custom>
<node width="1" grow="1" height="40">
<node align="center" dir="row">
<checkbox id="pattern-invert" width="20" height="19"/>
<text text="invert value"/>
</node>
<node align="center" dir="row">
<checkbox id="pattern-flipx" width="20" height="19"/>
<text text="flipX"/>
<checkbox id="pattern-flipy" width="20" height="19" margin="0 0 0 5"/>
<text text="flipY"/>
</node>
</node>
</node>
<node height="30" width="100%" pad="1" dir="row" margin="0 0 5 0">
<combobox id="pattern-blend-mode" width="100%" height="28" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
</node>
<node height="30" width="100%" pad="1" dir="row" margin="0 0 5 0">
<combobox id="pattern-proj-mode" width="100%" height="28" combo-list="Cube,Screen" default="0"/>
</node>
<node align="center" dir="row">
<checkbox id="pattern-eachsample" height="20" width="20"/>
<text text="each sample"/>
</node>
<node height="20" pad="1" width="100%">
<slider-h id="pattern-opacity" value="1"/>
</node>
<node height="20" pad="1" width="100%">
<slider-h id="pattern-scale" value=".25"/>
</node>
<node height="20" pad="1" width="100%">
<slider-h id="pattern-brightness" value=".5"/>
</node>
<node height="20" pad="1" width="100%">
<slider-h id="pattern-contrast" value=".5"/>
</node>
</node>
</node>
@@ -310,9 +364,9 @@
</node>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="40" justify="center" margin="5 0 0 0">
<node height="40" justify="center" margin="0 0 5 0">
<text text="Shape"/>
</node>
<node height="30" justify="center" margin="0 0 5 0">
@@ -397,7 +451,7 @@
<text text="Medium"/>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="20" justify="center">
<text text="Mixer"/>
@@ -429,7 +483,7 @@
<text text="Color Variations"/>
</border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<!--labels-->
<node height="20" justify="center">
<text text="Hue"/>
@@ -459,7 +513,7 @@
<border color=".2" height="20" justify="center" align="center" margin="5 0 5 0"><text text="Jitter Settings"/></border>
<node dir="row">
<node width="30%" dir="col">
<node width="36%" dir="col">
<node height="20" justify="center">
<text text="Flip"/>
</node>
@@ -522,14 +576,14 @@
<!--grids panel-->
<layout id="tpl-panel-grid">
<node width="220" margin="0 0 10 0" rtl="ltr">
<node width="250" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center">
<text text="Grids" color="1 1 1 1"/>
</border>
<border color=".3" pad="5" dir="col" width="100%">
<node dir="row">
<node width="40%" dir="col">
<node width="36%" dir="col">
<node height="20" justify="center"><text text="Opacity"/></node>
<node height="20" justify="center"><text text="Value"/></node>
<node height="20" justify="center"><text text="Offset"/></node>
@@ -550,7 +604,7 @@
<image-texture id="grid-heightmap-preview" width="100%" grow="1" height="100" aspect-ratio="1"/>
</border>
<node dir="row">
<node width="40%" dir="col">
<node width="36%" dir="col">
<node height="30" justify="center"><text text="File"/></node>
<node height="30" justify="center" margin="5 0 0 0"><text text="Shading"/></node>
<node height="20" justify="center" margin="5 0 0 0"><text text="Wireframe"/></node>

View File

@@ -139,7 +139,7 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
//b->m_jitter_val = i.m_jitter_val;
//b->m_blend_mode = i.m_blend_mode;
//b->m_name.resize(i.m_name_len);
//b->m_stencil_path.resize(i.m_stencil_path_len);
//b->m_texture_path.resize(i.m_stencil_path_len);
auto tip_uid = wstr2str(samp->value<String>("sampledData"));
LOG("tip uid %d %s", tip_uid.size(), tip_uid.c_str());
b->m_brush_path = path + "/brushes/" + tip_uid + ".png";
@@ -147,9 +147,9 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
if (auto patt = p->get<Descriptor>("Txtr"))
{
auto patt_uid = wstr2str(patt->value<String>("Idnt"));
b->m_stencil_path = path + "/patterns/" + patt_uid + ".png";
b->m_pattern_path = path + "/patterns/" + patt_uid + ".png";
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f;
b->m_pattern_opacity = p->value<UnitFloat>("textureDepth") * 0.01f;
}
ret.push_back(b);
}

View File

@@ -129,11 +129,11 @@ void App::init_sidebar()
Canvas::I->m_current_brush->m_tip_color = color;
};
stroke->on_brush_changed = [this](Node* target, const std::string& path, const std::string& thumb) {
Canvas::I->m_current_brush->load_texture(path, thumb);
Canvas::I->m_current_brush->load_tip(path, thumb);
stroke->m_preview->draw_stroke();
};
stroke->on_texture_changed = [this](Node*target, const std::string& path, const std::string& thumb) {
Canvas::I->m_current_brush->load_stencil(path, thumb);
stroke->on_pattern_changed = [this](Node*target, const std::string& path, const std::string& thumb) {
Canvas::I->m_current_brush->load_pattern(path, thumb);
stroke->m_preview->draw_stroke();
};
stroke->on_dual_changed = [this](Node*target, const std::string& path, const std::string& thumb) {

View File

@@ -219,9 +219,10 @@ void App::initShaders()
"uniform sampler2D tex_stroke;\n"
"uniform sampler2D tex_mask;\n"
"uniform sampler2D tex_dual;\n"
//"uniform sampler2D tex_stencil;\n"
"uniform sampler2D tex_pattern;\n"
"uniform mediump float alpha;\n"
"uniform mediump float stroke_alpha;\n"
"uniform mediump float pattern_alpha;\n"
"uniform mediump int blend_mode;\n"
"uniform mediump int dual_blend_mode;\n"
"uniform mediump vec2 resolution;\n"
@@ -229,6 +230,7 @@ void App::initShaders()
"uniform bool mask;\n"
"uniform bool fragUV2;\n"
"uniform bool use_dual;\n"
"uniform bool use_pattern;\n"
"in mediump vec2 uv;\n"
"out mediump vec4 frag;\n"
SHADER_FUNCTION_BLUR
@@ -238,6 +240,9 @@ void App::initShaders()
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
" mediump vec4 base = texture(tex, uv2);\n"
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
" if (use_pattern){\n"
" stroke.a *= 1.0 - texture(tex_pattern, uv2 * 5.0).r * pattern_alpha;\n"
" }\n"
" if (use_dual){\n"
" mediump vec4 dual = texture(tex_dual, uv);\n"
//" stroke.a = stroke.a * dual.a;\n"
@@ -385,16 +390,17 @@ void App::initShaders()
SHADER_EXT_FB_FETCH
"uniform mediump sampler2D tex;\n"
"uniform mediump sampler2D tex_bg;\n"
"uniform mediump sampler2D tex_stencil;\n"
"uniform mediump sampler2D tex_pattern;\n"
"uniform mediump sampler2D tex_mix;\n"
"uniform mediump vec4 col;\n"
"uniform mediump vec2 resolution;\n"
"uniform mediump float alpha;\n"
"uniform mediump float noise;\n"
"uniform mediump vec2 stencil_offset;\n"
"uniform mediump float stencil_alpha;\n"
"uniform mediump vec2 pattern_offset;\n"
"uniform mediump float pattern_alpha;\n"
"uniform mediump float mix_alpha;\n"
"uniform mediump float wet;\n"
"uniform bool use_pattern;\n"
"in mediump vec2 uv;\n"
"in mediump vec2 uv_2;\n"
"in mediump float q;\n"
@@ -406,9 +412,9 @@ void App::initShaders()
SHADER_FUNCTION_RAND
"void main() {\n"
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
" mediump float stencil = 1.0 - (texture(tex_stencil, (uv2+stencil_offset) * 5.0).r) * stencil_alpha;\n"
" mediump float pattern = use_pattern ? 1.0 - (texture(tex_pattern, (uv2+pattern_offset) * 5.0).r) * pattern_alpha : 1.0;\n"
" mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;\n"
" mediump vec4 fg = vec4(col.rgb, brush_alpha * stencil);\n"
" mediump vec4 fg = vec4(col.rgb, brush_alpha * pattern);\n"
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
" mediump vec4 bg = frag;\n"
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
@@ -503,18 +509,18 @@ void App::initShaders()
static const char* shader_stroke_inst_f =
SHADER_VERSION
"uniform mediump sampler2D tex;\n"
"uniform mediump sampler2D tex_stencil;\n"
"uniform mediump sampler2D tex_pattern;\n"
"uniform mediump vec4 col;\n"
"uniform mediump vec2 resolution;\n"
"uniform mediump vec2 stencil_offset;\n"
"uniform mediump float stencil_alpha;\n"
"uniform mediump vec2 pattern_offset;\n"
"uniform mediump float pattern_alpha;\n"
"in mediump float alpha;\n"
"in mediump vec3 uv;\n"
"out mediump vec4 frag;\n"
"void main() {\n"
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
" mediump float stencil = 1.0 - (texture(tex_stencil, (uv2+stencil_offset)).r * 0.9) * stencil_alpha;\n"
" mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * stencil;\n"
" mediump float pattern = 1.0 - (texture(tex_pattern, (uv2+pattern_offset)).r * 0.9) * pattern_alpha;\n"
" mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * pattern;\n"
" frag = vec4(col.rgb, a);\n"
"}\n";

View File

@@ -85,18 +85,22 @@ 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)
{
const auto& b = canvas->m_canvas->m_current_stroke->m_brush;
sampler.bind(0);
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_int(kShaderUniform::TexPattern, 3);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_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, b->m_blend_mode);
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
canvas->m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
@@ -105,13 +109,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
glActiveTexture(GL_TEXTURE2);
canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE3);
if (canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture)
canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
if (b->m_pattern_texture)
b->m_pattern_texture->bind();
m_face_plane.draw_fill();
if (canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture)
canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture->unbind();
glActiveTexture(GL_TEXTURE2);
canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE1);

View File

@@ -291,7 +291,7 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
prng.seed(0);
}
bool Brush::load_texture(const std::string& path, const std::string& thumb)
bool Brush::load_tip(const std::string& path, const std::string& thumb)
{
m_tip_texture = std::make_shared<Texture2D>();
if (!m_tip_texture->load(path))
@@ -315,15 +315,15 @@ bool Brush::load_dual(const std::string& path, const std::string& thumb)
return true;
}
bool Brush::load_stencil(const std::string& path, const std::string& thumb)
bool Brush::load_pattern(const std::string& path, const std::string& thumb)
{
m_stencil_texture = std::make_shared<Texture2D>();
if (!m_stencil_texture->load(path))
m_pattern_texture = std::make_shared<Texture2D>();
if (!m_pattern_texture->load(path))
return false;
m_stencil_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true;
m_stencil_path = path;
m_stencil_thumb_path = thumb;
m_pattern_texture->create_mipmaps();
m_pattern_texture->auto_destroy = true;
m_pattern_path = path;
m_texture_thumb_path = thumb;
return true;
}
@@ -354,19 +354,19 @@ bool Brush::load()
m_dual_texture->create_mipmaps();
m_dual_texture->auto_destroy = true;
}
if (!m_stencil_path.empty())
if (!m_pattern_path.empty())
{
m_stencil_texture = std::make_shared<Texture2D>();
if (!m_stencil_texture->load(m_stencil_path))
m_pattern_texture = std::make_shared<Texture2D>();
if (!m_pattern_texture->load(m_pattern_path))
{
LOG("failed to load %s", m_stencil_path.c_str());
LOG("failed to load %s", m_pattern_path.c_str());
m_tip_texture = nullptr;
m_dual_texture = nullptr;
m_stencil_texture = nullptr;
m_pattern_texture = nullptr;
return false;
}
m_stencil_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true;
m_pattern_texture->create_mipmaps();
m_pattern_texture->auto_destroy = true;
}
return true;
}

View File

@@ -18,9 +18,9 @@ public:
std::string m_dual_path;
std::string m_dual_thumb_path;
std::shared_ptr<Texture2D> m_stencil_texture;
std::string m_stencil_path;
std::string m_stencil_thumb_path;
std::shared_ptr<Texture2D> m_pattern_texture;
std::string m_pattern_path;
std::string m_texture_thumb_path;
glm::vec4 m_tip_color{0, 0, 0, 1};
float m_tip_size = .25f;
@@ -30,7 +30,7 @@ public:
float m_tip_angle = 0;
float m_tip_angle_delay = 0;
float m_tip_mix = 0;
float m_tip_stencil = 0;
float m_pattern_opacity = 1.f;
float m_tip_wet = 0;
float m_tip_noise = 0;
float m_tip_hue = 0;
@@ -51,7 +51,7 @@ public:
bool m_tip_invert = false;
bool m_tip_flipx = false;
bool m_tip_flipy = false;
bool m_tex_enabled = false;
bool m_pattern_enabled = false;
bool m_dual_enabled = false;
int m_dual_blend_mode = 0;
bool m_dual_randflip = false;
@@ -69,9 +69,18 @@ public:
float m_dual_opacity = 1.f;
float m_dual_rotate = .25f;
bool load_texture(const std::string& path, const std::string& thumb);
int m_pattern_blend_mode = 0;
bool m_pattern_eachsample = false;
bool m_pattern_invert = false;
bool m_pattern_flipx = false;
bool m_pattern_flipy = false;
float m_pattern_scale = .25f;
float m_pattern_brightness = 0.5f;
float m_pattern_contrast = 0.5f;
bool load_tip(const std::string& path, const std::string& thumb);
bool load_dual(const std::string& path, const std::string& thumb);
bool load_stencil(const std::string& path, const std::string& thumb);
bool load_pattern(const std::string& path, const std::string& thumb);
bool load();
};

View File

@@ -240,20 +240,23 @@ 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);
const auto& b = m_current_stroke->m_brush;
ShaderManager::use(kShader::CompDraw);
ShaderManager::u_int(kShaderUniform::Tex, 0);
//ShaderManager::u_int(kShaderUniform::TexA, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
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_int(kShaderUniform::TexPattern, 3);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::Lock, false/*m_layers[layer_index].m_alpha_locked*/);
ShaderManager::u_int(kShaderUniform::Mask, false/*m_smask_active*/);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush->m_blend_mode);
ShaderManager::u_int(kShaderUniform::UsePattern, false);
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].bindTexture();
@@ -486,12 +489,13 @@ void Canvas::stroke_draw()
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
if (!ShaderManager::ext_framebuffer_fetch)
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil
ShaderManager::u_int(kShaderUniform::TexPattern, 2); // pattern
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
//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, brush->m_tip_stencil);
ShaderManager::u_vec2(kShaderUniform::PatternOffset, stencil_offset);
ShaderManager::u_float(kShaderUniform::PatternAlpha, brush->m_pattern_opacity);
ShaderManager::u_int(kShaderUniform::UsePattern, brush->m_pattern_enabled && brush->m_pattern_eachsample);
ShaderManager::u_float(kShaderUniform::MixAlpha, brush->m_tip_mix);
ShaderManager::u_float(kShaderUniform::Wet, brush->m_tip_wet);
ShaderManager::u_float(kShaderUniform::Noise, brush->m_tip_noise);
@@ -502,10 +506,8 @@ void Canvas::stroke_draw()
glActiveTexture(GL_TEXTURE0);
brush->m_tip_texture->bind();
glActiveTexture(GL_TEXTURE2);
if (brush->m_stencil_texture)
brush->m_stencil_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
if (brush->m_pattern_texture)
brush->m_pattern_texture->bind();
glActiveTexture(GL_TEXTURE3);
m_mixer.bindTexture();
auto frames = stroke_draw_compute(*m_current_stroke);
@@ -533,23 +535,19 @@ void Canvas::stroke_draw()
}
glActiveTexture(GL_TEXTURE3);
m_mixer.unbindTexture();
glActiveTexture(GL_TEXTURE2);
if (brush->m_stencil_texture)
brush->m_stencil_texture->unbind();
glActiveTexture(GL_TEXTURE0);
brush->m_tip_texture->unbind();
// DRAW DUAL BRUSH
ShaderManager::u_int(kShaderUniform::UsePattern, false);
ShaderManager::u_float(kShaderUniform::MixAlpha, 0);
ShaderManager::u_float(kShaderUniform::Wet, 0);
ShaderManager::u_float(kShaderUniform::Noise, 0);
if (brush->m_dual_enabled)
{
glActiveTexture(GL_TEXTURE0);
dual_brush->m_tip_texture->bind();
glActiveTexture(GL_TEXTURE2);
if (dual_brush->m_stencil_texture)
dual_brush->m_stencil_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
auto frames_dual = stroke_draw_compute(*m_dual_stroke);
for (auto& f : frames_dual)
{
@@ -570,9 +568,6 @@ void Canvas::stroke_draw()
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], rect), glm::vec4(0), glm::vec4(m_width));
}
}
glActiveTexture(GL_TEXTURE2);
if (dual_brush->m_stencil_texture)
dual_brush->m_stencil_texture->unbind();
glActiveTexture(GL_TEXTURE0);
dual_brush->m_tip_texture->unbind();
}
@@ -719,6 +714,8 @@ void Canvas::stroke_commit()
glViewport(0, 0, m_width, m_height);
glDisable(GL_BLEND);
const auto& b = m_current_stroke->m_brush;
for (int i = 0; i < 6; i++)
{
//m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); // reset bounding box
@@ -755,7 +752,8 @@ void Canvas::stroke_commit()
m_sampler.bind(0);
m_sampler_bg.bind(1);
m_sampler_mask.bind(2);
m_sampler_stencil.bind(3);
m_sampler.bind(3);
m_sampler_stencil.bind(4);
if (m_current_mode == kCanvasMode::Erase)
{
ShaderManager::use(kShader::CompErase);
@@ -764,7 +762,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, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
@@ -787,16 +785,19 @@ void Canvas::stroke_commit()
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2);
ShaderManager::u_int(kShaderUniform::TexDual, 3);
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
//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, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_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, b->m_blend_mode);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
ShaderManager::u_int(kShaderUniform::TexDual, 3);
ShaderManager::u_int(kShaderUniform::UseDual, m_current_stroke->m_brush->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::DualBlendMode, m_current_stroke->m_brush->m_dual_blend_mode);
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind();
@@ -805,10 +806,14 @@ void Canvas::stroke_commit()
glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[i].bindTexture();
glActiveTexture(GL_TEXTURE3);
m_current_stroke->m_brush->m_dual_enabled ?
m_tmp_dual[i].bindTexture() : glBindTexture(GL_TEXTURE_2D, 0);
if (b->m_dual_enabled)
m_tmp_dual[i].bindTexture();
glActiveTexture(GL_TEXTURE4);
if (b->m_pattern_texture)
b->m_pattern_texture->bind();
m_plane.draw_fill();
if (m_current_stroke->m_brush->m_dual_enabled)
glActiveTexture(GL_TEXTURE3);
if (b->m_dual_enabled)
m_tmp_dual[i].unbindTexture();
glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[i].unbindTexture();
@@ -822,7 +827,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->brush->m_tip_opacity);
// ShaderManager::u_float(kShaderUniform::Alpha, b->m_tip_opacity);
//
// ShaderManager::u_int(kShaderUniform::Tex, 0);
// ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
@@ -996,11 +1001,13 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, 1);
ShaderManager::u_float(kShaderUniform::PatternAlpha, 0);
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity);
ShaderManager::u_int(kShaderUniform::Lock, false);
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[source_idx].m_blend_mode);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern,false);
glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind();

View File

@@ -1161,6 +1161,7 @@ void CanvasModeTransform::leave()
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
ShaderManager::u_int(kShaderUniform::BlendMode, 0);
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern, false);
Canvas::I->m_sampler_bg.bind(1);
Canvas::I->m_sampler_bg.bind(0);

View File

@@ -88,7 +88,8 @@ void NodeCanvas::draw()
m_sampler.bind(0);
m_sampler.bind(1);
m_sampler.bind(2);
m_sampler_stencil.bind(3);
m_sampler.bind(3);
m_sampler_stencil.bind(4);
auto blend = glIsEnabled(GL_BLEND);
auto depth = glIsEnabled(GL_DEPTH_TEST);
@@ -146,6 +147,8 @@ void NodeCanvas::draw()
use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
const auto& b = m_canvas->m_current_stroke->m_brush;
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
{
auto layer_index = m_canvas->m_order[i];
@@ -177,8 +180,8 @@ void NodeCanvas::draw()
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_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush->m_tip_opacity);
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->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);
@@ -204,18 +207,20 @@ void NodeCanvas::draw()
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_int(kShaderUniform::TexDual, 3);
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_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, b->m_blend_mode);
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
ShaderManager::u_int(kShaderUniform::TexDual, 3);
ShaderManager::u_int(kShaderUniform::UseDual, m_canvas->m_current_stroke->m_brush->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::DualBlendMode, m_canvas->m_current_stroke->m_brush->m_dual_blend_mode);
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
glActiveTexture(GL_TEXTURE0);
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
@@ -224,11 +229,14 @@ void NodeCanvas::draw()
glActiveTexture(GL_TEXTURE2);
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE3);
m_canvas->m_current_stroke->m_brush->m_dual_enabled ?
m_canvas->m_tmp_dual[plane_index].bindTexture() :
glBindTexture(GL_TEXTURE_2D, 0);
if (b->m_dual_enabled)
m_canvas->m_tmp_dual[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE4);
if (b->m_pattern_texture)
b->m_pattern_texture->bind();
m_face_plane.draw_fill();
if (m_canvas->m_current_stroke->m_brush->m_dual_enabled)
glActiveTexture(GL_TEXTURE3);
if (b->m_dual_enabled)
m_canvas->m_tmp_dual[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE2);
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();

View File

@@ -545,38 +545,38 @@ bool NodePanelBrushPreset::save()
i.m_brush_thumb_path_len = b->m_brush->m_brush_thumb_path.size();
i.m_dual_path_len = b->m_brush->m_brush_path.size();
i.m_dual_thumb_path_len = b->m_brush->m_brush_thumb_path.size();
i.m_stencil_path_len = b->m_brush->m_stencil_path.size();
i.m_stencil_thumb_path_len = b->m_brush->m_stencil_thumb_path.size();
i.m_tip_color = b->m_brush->m_tip_color;
i.m_tip_size = b->m_brush->m_tip_size;
i.m_tip_spacing = b->m_brush->m_tip_spacing;
i.m_tip_flow = b->m_brush->m_tip_flow;
i.m_tip_opacity = b->m_brush->m_tip_opacity;
i.m_tip_angle = b->m_brush->m_tip_angle;
i.m_tip_angle_delay = b->m_brush->m_tip_angle_delay;
i.m_tip_mix = b->m_brush->m_tip_mix;
i.m_tip_stencil = b->m_brush->m_tip_stencil;
i.m_tip_wet = b->m_brush->m_tip_wet;
i.m_tip_noise = b->m_brush->m_tip_noise;
i.m_tip_hue = b->m_brush->m_tip_hue;
i.m_tip_sat = b->m_brush->m_tip_sat;
i.m_tip_val = b->m_brush->m_tip_val;
i.m_tip_angle_follow = b->m_brush->m_tip_angle_follow;
i.m_tip_flow_pressure = b->m_brush->m_tip_flow_pressure;
i.m_tip_size_pressure = b->m_brush->m_tip_size_pressure;
i.m_jitter_scale = b->m_brush->m_jitter_scale;
i.m_jitter_angle = b->m_brush->m_jitter_angle;
i.m_jitter_spread = b->m_brush->m_jitter_spread;
i.m_jitter_flow = b->m_brush->m_jitter_flow;
i.m_jitter_hue = b->m_brush->m_jitter_hue;
i.m_jitter_sat = b->m_brush->m_jitter_sat;
i.m_jitter_val = b->m_brush->m_jitter_val;
i.m_blend_mode = b->m_brush->m_blend_mode;
i.m_stencil_path_len = b->m_brush->m_pattern_path.size();
i.m_stencil_thumb_path_len = b->m_brush->m_texture_thumb_path.size();
i.m_tip_color = b->m_brush->m_tip_color;
i.m_tip_size = b->m_brush->m_tip_size;
i.m_tip_spacing = b->m_brush->m_tip_spacing;
i.m_tip_flow = b->m_brush->m_tip_flow;
i.m_tip_opacity = b->m_brush->m_tip_opacity;
i.m_tip_angle = b->m_brush->m_tip_angle;
i.m_tip_angle_delay = b->m_brush->m_tip_angle_delay;
i.m_tip_mix = b->m_brush->m_tip_mix;
i.m_pattern_opacity = b->m_brush->m_pattern_opacity;
i.m_tip_wet = b->m_brush->m_tip_wet;
i.m_tip_noise = b->m_brush->m_tip_noise;
i.m_tip_hue = b->m_brush->m_tip_hue;
i.m_tip_sat = b->m_brush->m_tip_sat;
i.m_tip_val = b->m_brush->m_tip_val;
i.m_tip_angle_follow = b->m_brush->m_tip_angle_follow;
i.m_tip_flow_pressure = b->m_brush->m_tip_flow_pressure;
i.m_tip_size_pressure = b->m_brush->m_tip_size_pressure;
i.m_jitter_scale = b->m_brush->m_jitter_scale;
i.m_jitter_angle = b->m_brush->m_jitter_angle;
i.m_jitter_spread = b->m_brush->m_jitter_spread;
i.m_jitter_flow = b->m_brush->m_jitter_flow;
i.m_jitter_hue = b->m_brush->m_jitter_hue;
i.m_jitter_sat = b->m_brush->m_jitter_sat;
i.m_jitter_val = b->m_brush->m_jitter_val;
i.m_blend_mode = b->m_brush->m_blend_mode;
i.m_tip_invert = b->m_brush->m_tip_invert;
i.m_tip_flipx = b->m_brush->m_tip_flipx;
i.m_tip_flipy = b->m_brush->m_tip_flipy;
i.m_tex_enabled = b->m_brush->m_tex_enabled;
i.m_pattern_enabled = b->m_brush->m_pattern_enabled;
i.m_dual_enabled = b->m_brush->m_dual_enabled;
i.m_dual_blend_mode = b->m_brush->m_dual_blend_mode;
i.m_dual_randflip = b->m_brush->m_dual_randflip;
@@ -594,14 +594,22 @@ bool NodePanelBrushPreset::save()
i.m_dual_opacity = b->m_brush->m_dual_opacity;
i.m_dual_rotate = b->m_brush->m_dual_rotate;
i.m_pattern_eachsample = b->m_brush->m_pattern_eachsample;
i.m_pattern_invert = b->m_brush->m_pattern_invert;
i.m_pattern_flipx = b->m_brush->m_pattern_flipx;
i.m_pattern_flipy = b->m_brush->m_pattern_flipy;
i.m_pattern_scale = b->m_brush->m_pattern_scale;
i.m_pattern_brightness = b->m_brush->m_pattern_brightness;
i.m_pattern_contrast = b->m_brush->m_pattern_contrast;
fwrite(&i, sizeof(i), 1, fp);
fwrite(b->m_brush->m_name.c_str(), 1, b->m_brush->m_name.size(), fp);
fwrite(b->m_brush->m_brush_path.c_str(), 1, b->m_brush->m_brush_path.size(), fp);
fwrite(b->m_brush->m_brush_thumb_path.c_str(), 1, b->m_brush->m_brush_thumb_path.size(), fp);
fwrite(b->m_brush->m_dual_path.c_str(), 1, b->m_brush->m_brush_path.size(), fp);
fwrite(b->m_brush->m_dual_thumb_path.c_str(), 1, b->m_brush->m_brush_thumb_path.size(), fp);
fwrite(b->m_brush->m_stencil_path.c_str(), 1, b->m_brush->m_stencil_path.size(), fp);
fwrite(b->m_brush->m_stencil_thumb_path.c_str(), 1, b->m_brush->m_stencil_thumb_path.size(), fp);
fwrite(b->m_brush->m_pattern_path.c_str(), 1, b->m_brush->m_pattern_path.size(), fp);
fwrite(b->m_brush->m_texture_thumb_path.c_str(), 1, b->m_brush->m_texture_thumb_path.size(), fp);
}
fclose(fp);
return true;
@@ -634,36 +642,36 @@ bool NodePanelBrushPreset::restore()
item_t i;
fread(&i, sizeof(i), 1, fp);
auto b = std::make_shared<Brush>();
b->m_tip_color = i.m_tip_color;
b->m_tip_size = i.m_tip_size;
b->m_tip_spacing = i.m_tip_spacing;
b->m_tip_flow = i.m_tip_flow;
b->m_tip_opacity = i.m_tip_opacity;
b->m_tip_angle = i.m_tip_angle;
b->m_tip_angle_delay = i.m_tip_angle_delay;
b->m_tip_mix = i.m_tip_mix;
b->m_tip_stencil = i.m_tip_stencil;
b->m_tip_wet = i.m_tip_wet;
b->m_tip_noise = i.m_tip_noise;
b->m_tip_hue = i.m_tip_hue;
b->m_tip_sat = i.m_tip_sat;
b->m_tip_val = i.m_tip_val;
b->m_tip_angle_follow = i.m_tip_angle_follow;
b->m_tip_flow_pressure = i.m_tip_flow_pressure;
b->m_tip_size_pressure = i.m_tip_size_pressure;
b->m_jitter_scale = i.m_jitter_scale;
b->m_jitter_angle = i.m_jitter_angle;
b->m_jitter_spread = i.m_jitter_spread;
b->m_jitter_flow = i.m_jitter_flow;
b->m_jitter_hue = i.m_jitter_hue;
b->m_jitter_sat = i.m_jitter_sat;
b->m_jitter_val = i.m_jitter_val;
b->m_blend_mode = i.m_blend_mode;
b->m_tip_color = i.m_tip_color;
b->m_tip_size = i.m_tip_size;
b->m_tip_spacing = i.m_tip_spacing;
b->m_tip_flow = i.m_tip_flow;
b->m_tip_opacity = i.m_tip_opacity;
b->m_tip_angle = i.m_tip_angle;
b->m_tip_angle_delay = i.m_tip_angle_delay;
b->m_tip_mix = i.m_tip_mix;
b->m_pattern_opacity = i.m_pattern_opacity;
b->m_tip_wet = i.m_tip_wet;
b->m_tip_noise = i.m_tip_noise;
b->m_tip_hue = i.m_tip_hue;
b->m_tip_sat = i.m_tip_sat;
b->m_tip_val = i.m_tip_val;
b->m_tip_angle_follow = i.m_tip_angle_follow;
b->m_tip_flow_pressure = i.m_tip_flow_pressure;
b->m_tip_size_pressure = i.m_tip_size_pressure;
b->m_jitter_scale = i.m_jitter_scale;
b->m_jitter_angle = i.m_jitter_angle;
b->m_jitter_spread = i.m_jitter_spread;
b->m_jitter_flow = i.m_jitter_flow;
b->m_jitter_hue = i.m_jitter_hue;
b->m_jitter_sat = i.m_jitter_sat;
b->m_jitter_val = i.m_jitter_val;
b->m_blend_mode = i.m_blend_mode;
b->m_tip_invert = i.m_tip_invert;
b->m_tip_flipx = i.m_tip_flipx;
b->m_tip_flipy = i.m_tip_flipy;
b->m_tex_enabled = i.m_tex_enabled;
b->m_pattern_enabled = i.m_pattern_enabled;
b->m_dual_enabled = i.m_dual_enabled;
b->m_dual_blend_mode = i.m_dual_blend_mode;
b->m_dual_randflip = i.m_dual_randflip;
@@ -679,25 +687,33 @@ bool NodePanelBrushPreset::restore()
b->m_dual_opacity = i.m_dual_opacity;
b->m_dual_rotate = i.m_dual_rotate;
b->m_pattern_eachsample = i.m_pattern_eachsample;
b->m_pattern_invert = i.m_pattern_invert;
b->m_pattern_flipx = i.m_pattern_flipx;
b->m_pattern_flipy = i.m_pattern_flipy;
b->m_pattern_scale = i.m_pattern_scale;
b->m_pattern_brightness = i.m_pattern_brightness;
b->m_pattern_contrast = i.m_pattern_contrast;
b->m_name.resize(i.m_name_len);
b->m_brush_path.resize(i.m_brush_path_len);
b->m_brush_thumb_path.resize(i.m_brush_thumb_path_len);
b->m_dual_path.resize(i.m_brush_path_len);
b->m_dual_thumb_path.resize(i.m_brush_thumb_path_len);
b->m_stencil_path.resize(i.m_stencil_path_len);
b->m_stencil_thumb_path.resize(i.m_stencil_thumb_path_len);
b->m_pattern_path.resize(i.m_stencil_path_len);
b->m_texture_thumb_path.resize(i.m_stencil_thumb_path_len);
fread((char*)b->m_name.c_str(), 1, b->m_name.size(), fp);
fread((char*)b->m_brush_path.c_str(), 1, b->m_brush_path.size(), fp);
fread((char*)b->m_brush_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
fread((char*)b->m_dual_path.c_str(), 1, b->m_brush_path.size(), fp);
fread((char*)b->m_dual_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
fread((char*)b->m_stencil_path.c_str(), 1, b->m_stencil_path.size(), fp);
fread((char*)b->m_stencil_thumb_path.c_str(), 1, b->m_stencil_thumb_path.size(), fp);
fread((char*)b->m_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp);
fread((char*)b->m_texture_thumb_path.c_str(), 1, b->m_texture_thumb_path.size(), fp);
if (b->load_texture(b->m_brush_path, b->m_brush_thumb_path))
if (b->load_tip(b->m_brush_path, b->m_brush_thumb_path))
{
if (!b->m_stencil_path.empty())
b->load_stencil(b->m_stencil_path, b->m_stencil_thumb_path);
if (!b->m_pattern_path.empty())
b->load_pattern(b->m_pattern_path, b->m_texture_thumb_path);
NodeBrushPresetItem* brush = new NodeBrushPresetItem;
m_container->add_child(brush);

View File

@@ -111,7 +111,7 @@ class NodePanelBrushPreset : public Node
float m_tip_angle = 0;
float m_tip_angle_delay = 0;
float m_tip_mix = 0;
float m_tip_stencil = 0;
float m_pattern_opacity = 0;
float m_tip_wet = 0;
float m_tip_noise = 0;
float m_tip_hue = 0;
@@ -132,7 +132,7 @@ class NodePanelBrushPreset : public Node
bool m_tip_invert = false;
bool m_tip_flipx = false;
bool m_tip_flipy = false;
bool m_tex_enabled = false;
bool m_pattern_enabled = false;
bool m_dual_enabled = false;
int m_dual_blend_mode = 0;
bool m_dual_randflip = false;
@@ -149,6 +149,14 @@ class NodePanelBrushPreset : public Node
float m_dual_flow = .75f;
float m_dual_opacity = 1.f;
float m_dual_rotate = .25f;
bool m_pattern_eachsample = false;
bool m_pattern_invert = false;
bool m_pattern_flipx = false;
bool m_pattern_flipy = false;
float m_pattern_scale = .25f;
float m_pattern_brightness = 0.5f;
float m_pattern_contrast = 0.5f;
};
public:
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed;

View File

@@ -31,7 +31,7 @@ void NodePanelStroke::update_controls()
m_tip_opacity->m_value.x = b->m_tip_opacity;
m_tip_angle->m_value.x = b->m_tip_angle;
m_tip_angle_delay->m_value.x = b->m_tip_angle_delay;
m_tip_stencil->m_value.x = b->m_tip_stencil;
m_pattern_opacity->m_value.x = b->m_pattern_opacity;
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;
@@ -48,7 +48,7 @@ void NodePanelStroke::update_controls()
m_tip_invert->checked = b->m_tip_invert;
m_tip_flipx->checked = b->m_tip_flipx;
m_tip_flipy->checked = b->m_tip_flipy;
m_tex_enabled->checked = b->m_tex_enabled;
m_pattern_enabled->checked = b->m_pattern_enabled;
m_dual_enabled->checked = b->m_dual_enabled;
m_dual_scatter_axis->checked = b->m_dual_scatter_axis;
m_dual_invert->checked = b->m_dual_invert;
@@ -66,8 +66,17 @@ void NodePanelStroke::update_controls()
m_dual_opacity->m_value.x = b->m_dual_opacity;
m_dual_rotate->m_value.x = b->m_dual_rotate;
m_pattern_eachsample->checked = b->m_pattern_eachsample;
m_pattern_invert->checked = b->m_pattern_invert;
m_pattern_flipx->checked = b->m_pattern_flipx;
m_pattern_flipy->checked = b->m_pattern_flipy;
m_pattern_scale->m_value.x = b->m_pattern_scale;
m_pattern_brightness->m_value.x = b->m_pattern_brightness;
m_pattern_contrast->m_value.x = b->m_pattern_contrast;
m_blend_mode->set_index(b->m_blend_mode);
m_dual_blend_mode->set_index(b->m_dual_blend_mode);
m_pattern_blend_mode->set_index(b->m_pattern_blend_mode);
m_preview->m_brush = b;
m_preview->draw_stroke();
@@ -87,17 +96,17 @@ void NodePanelStroke::init_controls()
m_brush_popup->m_flood_events = true;
m_brush_popup->m_capture_children = false;
m_texture_popup = std::make_shared<NodePanelBrush>();
m_texture_popup->m_manager = m_manager;
m_texture_popup->m_dir_name = "textures";
m_texture_popup->init();
m_texture_popup->create();
m_texture_popup->loaded();
m_texture_popup->SetPositioning(YGPositionTypeAbsolute);
m_texture_popup->SetSize(300, 400);
m_texture_popup->m_mouse_ignore = false;
m_texture_popup->m_flood_events = true;
m_texture_popup->m_capture_children = false;
m_pattern_popup = std::make_shared<NodePanelBrush>();
m_pattern_popup->m_manager = m_manager;
m_pattern_popup->m_dir_name = "textures";
m_pattern_popup->init();
m_pattern_popup->create();
m_pattern_popup->loaded();
m_pattern_popup->SetPositioning(YGPositionTypeAbsolute);
m_pattern_popup->SetSize(300, 400);
m_pattern_popup->m_mouse_ignore = false;
m_pattern_popup->m_flood_events = true;
m_pattern_popup->m_capture_children = false;
m_presets_popup = std::make_shared<NodePanelBrushPreset>();
m_presets_popup->m_manager = m_manager;
@@ -114,8 +123,9 @@ void NodePanelStroke::init_controls()
// init main brush
auto b = std::make_shared<Brush>();
b->load_texture(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
b->load_tip(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
b->load_dual(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
b->load_pattern(m_pattern_popup->get_texture_path(0), m_pattern_popup->get_thumb_path(0));
b->m_tip_size = .1f;
b->m_tip_flow = .5f;
b->m_tip_spacing = .1f;
@@ -237,37 +247,37 @@ void NodePanelStroke::init_controls()
};
// TEXTURE IMAGE
// PATTERN IMAGE
m_texture_thumb = find<NodeImage>("texture-change-thumb");
m_texture_thumb->set_image(m_texture_popup->get_thumb_path(0));
m_texture_button = find<NodeButtonCustom>("texture-change");
m_texture_button->on_click = [this](Node*) {
m_pattern_thumb = find<NodeImage>("pattern-change-thumb");
m_pattern_thumb->set_image(m_pattern_popup->get_thumb_path(0));
m_pattern_button = find<NodeButtonCustom>("pattern-change");
m_pattern_button->on_click = [this](Node*) {
auto screen = root()->m_size;
glm::vec2 pos = m_texture_button->m_pos + glm::vec2(m_texture_button->m_size.x, 0);
root()->add_child(m_texture_popup);
glm::vec2 pos = m_pattern_button->m_pos + glm::vec2(m_pattern_button->m_size.x, 0);
root()->add_child(m_pattern_popup);
auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32);
tick->SetPosition(pos.x, pos.y + (m_texture_button->m_size.y - 32) * 0.5f);
tick->SetPosition(pos.x, pos.y + (m_pattern_button->m_size.y - 32) * 0.5f);
tick->set_image("data/ui/popup-tick.png");
root()->update();
if ((pos.y + m_texture_popup->m_size.y) > screen.y)
pos.y = screen.y - m_texture_popup->m_size.y;
if ((pos.y + m_pattern_popup->m_size.y) > screen.y)
pos.y = screen.y - m_pattern_popup->m_size.y;
if (pos.y < 0)
pos.y = 0;
m_texture_popup->SetPosition(pos.x + 16, pos.y);
m_texture_popup->mouse_capture();
m_pattern_popup->SetPosition(pos.x + 16, pos.y);
m_pattern_popup->mouse_capture();
root()->update();
m_texture_popup->on_popup_close = [this, tick](Node*) {
m_pattern_popup->on_popup_close = [this, tick](Node*) {
tick->destroy();
};
m_texture_popup->on_brush_changed = [this](Node*, int index) {
if (on_texture_changed)
on_texture_changed(this, m_texture_popup->get_texture_path(index), m_texture_popup->get_thumb_path(index));
m_texture_thumb->set_image(m_texture_popup->get_thumb_path(index));
m_pattern_popup->on_brush_changed = [this](Node*, int index) {
if (on_pattern_changed)
on_pattern_changed(this, m_pattern_popup->get_texture_path(index), m_pattern_popup->get_thumb_path(index));
m_pattern_thumb->set_image(m_pattern_popup->get_thumb_path(index));
};
};
@@ -288,7 +298,7 @@ void NodePanelStroke::init_controls()
init_slider(m_tip_angle, "tip-angle", &Brush::m_tip_angle);
init_slider(m_tip_angle_delay, "tip-angle-delay", &Brush::m_tip_angle_delay);
init_slider(m_tip_mix, "tip-mix", &Brush::m_tip_mix);
init_slider(m_tip_stencil, "tip-stencil", &Brush::m_tip_stencil);
init_slider(m_pattern_opacity, "pattern-opacity", &Brush::m_pattern_opacity);
init_slider(m_tip_wet, "tip-wet", &Brush::m_tip_wet);
init_slider(m_tip_noise, "tip-noise", &Brush::m_tip_noise);
init_slider(m_tip_hue, "tip-hue", &Brush::m_tip_hue);
@@ -309,7 +319,7 @@ void NodePanelStroke::init_controls()
init_checkbox(m_tip_invert, "tip-invert", &Brush::m_tip_invert);
init_checkbox(m_tip_flipx, "tip-flipx", &Brush::m_tip_flipx);
init_checkbox(m_tip_flipy, "tip-flipy", &Brush::m_tip_flipy);
init_checkbox(m_tex_enabled, "tex-enabled", &Brush::m_tex_enabled);
init_checkbox(m_pattern_enabled, "pattern-enabled", &Brush::m_pattern_enabled);
init_checkbox(m_dual_enabled, "dual-enabled", &Brush::m_dual_enabled);
init_checkbox(m_dual_scatter_axis, "dual-scatter-axis", &Brush::m_dual_scatter_axis);
init_checkbox(m_dual_invert, "dual-invert", &Brush::m_dual_invert);
@@ -318,6 +328,11 @@ void NodePanelStroke::init_controls()
init_checkbox(m_dual_randflip, "dual-randflip", &Brush::m_dual_randflip);
init_checkbox(m_tip_randflipx, "tip-randflipx", &Brush::m_tip_randflipx);
init_checkbox(m_tip_randflipy, "tip-randflipy", &Brush::m_tip_randflipy);
init_checkbox(m_pattern_eachsample, "pattern-eachsample", &Brush::m_pattern_eachsample);
init_checkbox(m_pattern_invert, "pattern-invert", &Brush::m_pattern_invert);
init_checkbox(m_pattern_flipx, "pattern-flipx", &Brush::m_pattern_flipx);
init_checkbox(m_pattern_flipy, "pattern-flipy", &Brush::m_pattern_flipy);
init_slider(m_dual_size, "dual-size", &Brush::m_dual_size);
init_slider(m_dual_spacing, "dual-spacing", &Brush::m_dual_spacing);
@@ -326,6 +341,9 @@ void NodePanelStroke::init_controls()
init_slider(m_dual_opacity, "dual-opacity", &Brush::m_dual_opacity);
init_slider(m_dual_flow, "dual-flow", &Brush::m_dual_flow);
init_slider(m_dual_rotate, "dual-rotate", &Brush::m_dual_rotate);
init_slider(m_pattern_scale, "pattern-scale", &Brush::m_pattern_scale);
init_slider(m_pattern_brightness, "pattern-brightness", &Brush::m_pattern_brightness);
init_slider(m_pattern_contrast, "pattern-contrast", &Brush::m_pattern_contrast);
auto curve_cubic = [](float v) { return glm::pow(v, 3.f); };
auto curve_quad = [](float v) { return glm::pow(v, 2.f); };
@@ -353,6 +371,14 @@ void NodePanelStroke::init_controls()
on_stroke_change(this);
};
m_pattern_blend_mode = find<NodeComboBox>("pattern-blend-mode");
m_pattern_blend_mode->on_select = [this](Node*, int index) {
Canvas::I->m_current_brush->m_pattern_blend_mode = index;
m_preview->draw_stroke();
if (on_stroke_change)
on_stroke_change(this);
};
m_preview->m_brush = Canvas::I->m_current_brush;
m_preview->draw_stroke();
@@ -363,8 +389,8 @@ void NodePanelStroke::init_controls()
App::I.async_start();
if (TextureManager::load(path.c_str()))
{
if (on_texture_changed)
on_texture_changed(this, path, "");
if (on_pattern_changed)
on_pattern_changed(this, path, "");
}
App::I.async_redraw();
App::I.async_end();

View File

@@ -21,7 +21,7 @@ public:
NodeSliderH* m_tip_angle;
NodeSliderH* m_tip_angle_delay;
NodeSliderH* m_tip_mix;
NodeSliderH* m_tip_stencil;
NodeSliderH* m_pattern_opacity;
NodeSliderH* m_tip_wet;
NodeSliderH* m_tip_noise;
NodeSliderH* m_tip_hue;
@@ -39,10 +39,10 @@ public:
NodeCheckBox* m_tip_size_pressure;
NodeButtonCustom* m_brush_button;
NodeButtonCustom* m_dual_brush_button;
NodeButtonCustom* m_texture_button;
NodeButtonCustom* m_pattern_button;
NodeImage* m_brush_thumb;
NodeImage* m_dual_brush_thumb;
NodeImage* m_texture_thumb;
NodeImage* m_pattern_thumb;
NodeImage* m_preset_thumb;
NodeButtonCustom* m_preset_button;
NodeStrokePreview* m_preset_preview;
@@ -50,7 +50,7 @@ public:
NodeCheckBox* m_tip_invert;
NodeCheckBox* m_tip_flipx;
NodeCheckBox* m_tip_flipy;
NodeCheckBox* m_tex_enabled;
NodeCheckBox* m_pattern_enabled;
NodeCheckBox* m_dual_enabled;
NodeCheckBox* m_dual_scatter_axis;
NodeCheckBox* m_dual_invert;
@@ -67,15 +67,26 @@ public:
NodeSliderH* m_dual_opacity;
NodeSliderH* m_dual_rotate;
NodeComboBox* m_dual_blend_mode;
NodeComboBox* m_pattern_blend_mode;
NodeButtonCustom* m_tip_aspect_reset;
NodeCheckBox* m_pattern_eachsample;
NodeCheckBox* m_pattern_invert;
NodeCheckBox* m_pattern_flipx;
NodeCheckBox* m_pattern_flipy;
NodeSliderH* m_pattern_scale;
NodeSliderH* m_pattern_brightness;
NodeSliderH* m_pattern_contrast;
std::shared_ptr<NodePanelBrush> m_brush_popup;
std::shared_ptr<NodePanelBrush> m_texture_popup;
std::shared_ptr<NodePanelBrush> m_pattern_popup;
std::shared_ptr<NodePanelBrushPreset> m_presets_popup;
std::function<void(Node* target)> on_stroke_change;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_texture_changed;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_pattern_changed;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_brush_changed;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_dual_changed;
//std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_texture_changed;
std::map<NodeSliderH*, std::function<float(float)>> m_curves;
virtual Node* clone_instantiate() const override;

View File

@@ -84,8 +84,8 @@ void NodeStrokePreview::draw_stroke()
m_sampler_brush.bind(0);
glActiveTexture(GL_TEXTURE1);
if (b->m_stencil_texture)
b->m_stencil_texture->bind();
if (b->m_pattern_texture && b->m_pattern_enabled)
b->m_pattern_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
m_sampler.bind(1);
@@ -95,10 +95,10 @@ void NodeStrokePreview::draw_stroke()
ShaderManager::use(kShader::BrushStroke);
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 });
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStencil, 1); // stencil
ShaderManager::u_int(kShaderUniform::TexPattern, 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_vec2(kShaderUniform::PatternOffset, glm::vec2(0));
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
m_mesh.draw(samples, proj);
}
//else

View File

@@ -13,9 +13,9 @@ enum class kShaderUniform : uint16_t
TexMask = const_hash("tex_mask"),
TexDual = const_hash("tex_dual"),
TexStroke = const_hash("tex_stroke"),
TexStencil = const_hash("tex_stencil"),
StencilOffset = const_hash("stencil_offset"),
StencilAlpha = const_hash("stencil_alpha"),
TexPattern = const_hash("tex_pattern"),
PatternOffset = const_hash("pattern_offset"),
PatternAlpha = const_hash("pattern_alpha"),
MixAlpha = const_hash("mix_alpha"),
StrokeAlpha = const_hash("stroke_alpha"),
Wet = const_hash("wet"),
@@ -33,6 +33,7 @@ enum class kShaderUniform : uint16_t
Direction = const_hash("dir"),
UseFragCoordUV2 = const_hash("fragUV2"),
UseDual = const_hash("use_dual"),
UsePattern = const_hash("use_pattern"),
LightDir = const_hash("light_dir"),
Mode = const_hash("mode"),
Ambient = const_hash("ambient"),