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--> <!--layers panel template-->
<layout id="tpl-panel-layers"> <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"> <border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
<text text="Layers" color="1 1 1 1"/> <text text="Layers" color="1 1 1 1"/>
</border> </border>
@@ -121,7 +121,7 @@
<!--color panel--> <!--color panel-->
<layout id="tpl-panel-color"> <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"> <border height="30" color=".5" align="center" justify="center">
<text text="Colors" color="1 1 1 1"/> <text text="Colors" color="1 1 1 1"/>
</border> </border>
@@ -134,7 +134,7 @@
<!--stroke panel--> <!--stroke panel-->
<layout id="tpl-panel-stroke"> <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"> <border height="30" color=".5" align="center" justify="center">
<text text="Stroke" color="1 1 1 1"/> <text text="Stroke" color="1 1 1 1"/>
</border> </border>
@@ -149,7 +149,7 @@
<!-- PRESET AND SHAPE --> <!-- PRESET AND SHAPE -->
<node dir="row"> <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="20" justify="center" margin="5 0 5 0"><text text="Shade"/></node>-->
<node height="40" justify="center" margin="5 0 0 0"> <node height="40" justify="center" margin="5 0 0 0">
<text text="Preset"/> <text text="Preset"/>
@@ -199,7 +199,7 @@
<text text="Color"/> <text text="Color"/>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="30" justify="center" margin="0 0 5 0"> <node height="30" justify="center" margin="0 0 5 0">
<text text="Blend"/> <text text="Blend"/>
@@ -235,7 +235,7 @@
<text text="Metrics"/> <text text="Metrics"/>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="20" justify="center" margin="0 0 20 0"> <node height="20" justify="center" margin="0 0 20 0">
<text text="Size"/> <text text="Size"/>
@@ -275,28 +275,82 @@
</node> </node>
</node> </node>
<!-- TEXTURE --> <!-- PATTERN -->
<border color=".2" height="20" dir="row" justify="center" align="center" margin="5 0 5 0"> <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"> <node align="center" width="1" grow="1">
<text text="Texture"/> <text text="Pattern"/>
</node> </node>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="40" justify="center"> <node height="40" justify="center" margin="0 0 5 0">
<text text="Pattern"/> <text text="Pattern"/>
</node> </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>
<node dir="col" align="center" grow="1" width="1"> <node dir="col" grow="1" width="1">
<!--controls--> <!--controls-->
<node height="40" width="100%" dir="row"> <node dir="row" margin="0 0 5 0">
<slider-h id="tip-stencil" width="1" grow="1" height="30" margin="5 5 5 0"/> <button-custom id="pattern-change" width="40" height="40" dir="row" pad="4">
<button-custom id="texture-change" width="40" height="40" dir="row" pad="4"> <image id="pattern-change-thumb" width="32" height="100%"/>
<image id="texture-change-thumb" width="32" height="100%"/>
</button-custom> </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> </node>
</node> </node>
@@ -310,9 +364,9 @@
</node> </node>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="40" justify="center" margin="5 0 0 0"> <node height="40" justify="center" margin="0 0 5 0">
<text text="Shape"/> <text text="Shape"/>
</node> </node>
<node height="30" justify="center" margin="0 0 5 0"> <node height="30" justify="center" margin="0 0 5 0">
@@ -397,7 +451,7 @@
<text text="Medium"/> <text text="Medium"/>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="20" justify="center"> <node height="20" justify="center">
<text text="Mixer"/> <text text="Mixer"/>
@@ -429,7 +483,7 @@
<text text="Color Variations"/> <text text="Color Variations"/>
</border> </border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<!--labels--> <!--labels-->
<node height="20" justify="center"> <node height="20" justify="center">
<text text="Hue"/> <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> <border color=".2" height="20" justify="center" align="center" margin="5 0 5 0"><text text="Jitter Settings"/></border>
<node dir="row"> <node dir="row">
<node width="30%" dir="col"> <node width="36%" dir="col">
<node height="20" justify="center"> <node height="20" justify="center">
<text text="Flip"/> <text text="Flip"/>
</node> </node>
@@ -522,14 +576,14 @@
<!--grids panel--> <!--grids panel-->
<layout id="tpl-panel-grid"> <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"> <border height="30" color=".5" align="center" justify="center">
<text text="Grids" color="1 1 1 1"/> <text text="Grids" color="1 1 1 1"/>
</border> </border>
<border color=".3" pad="5" dir="col" width="100%"> <border color=".3" pad="5" dir="col" width="100%">
<node dir="row"> <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="Opacity"/></node>
<node height="20" justify="center"><text text="Value"/></node> <node height="20" justify="center"><text text="Value"/></node>
<node height="20" justify="center"><text text="Offset"/></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"/> <image-texture id="grid-heightmap-preview" width="100%" grow="1" height="100" aspect-ratio="1"/>
</border> </border>
<node dir="row"> <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"><text text="File"/></node>
<node height="30" justify="center" margin="5 0 0 0"><text text="Shading"/></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> <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_jitter_val = i.m_jitter_val;
//b->m_blend_mode = i.m_blend_mode; //b->m_blend_mode = i.m_blend_mode;
//b->m_name.resize(i.m_name_len); //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")); auto tip_uid = wstr2str(samp->value<String>("sampledData"));
LOG("tip uid %d %s", tip_uid.size(), tip_uid.c_str()); LOG("tip uid %d %s", tip_uid.size(), tip_uid.c_str());
b->m_brush_path = path + "/brushes/" + tip_uid + ".png"; 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")) if (auto patt = p->get<Descriptor>("Txtr"))
{ {
auto patt_uid = wstr2str(patt->value<String>("Idnt")); 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_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); ret.push_back(b);
} }

View File

@@ -129,11 +129,11 @@ void App::init_sidebar()
Canvas::I->m_current_brush->m_tip_color = color; Canvas::I->m_current_brush->m_tip_color = color;
}; };
stroke->on_brush_changed = [this](Node* target, const std::string& path, const std::string& thumb) { 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->m_preview->draw_stroke();
}; };
stroke->on_texture_changed = [this](Node*target, const std::string& path, const std::string& thumb) { stroke->on_pattern_changed = [this](Node*target, const std::string& path, const std::string& thumb) {
Canvas::I->m_current_brush->load_stencil(path, thumb); Canvas::I->m_current_brush->load_pattern(path, thumb);
stroke->m_preview->draw_stroke(); stroke->m_preview->draw_stroke();
}; };
stroke->on_dual_changed = [this](Node*target, const std::string& path, const std::string& thumb) { 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_stroke;\n"
"uniform sampler2D tex_mask;\n" "uniform sampler2D tex_mask;\n"
"uniform sampler2D tex_dual;\n" "uniform sampler2D tex_dual;\n"
//"uniform sampler2D tex_stencil;\n" "uniform sampler2D tex_pattern;\n"
"uniform mediump float alpha;\n" "uniform mediump float alpha;\n"
"uniform mediump float stroke_alpha;\n" "uniform mediump float stroke_alpha;\n"
"uniform mediump float pattern_alpha;\n"
"uniform mediump int blend_mode;\n" "uniform mediump int blend_mode;\n"
"uniform mediump int dual_blend_mode;\n" "uniform mediump int dual_blend_mode;\n"
"uniform mediump vec2 resolution;\n" "uniform mediump vec2 resolution;\n"
@@ -229,6 +230,7 @@ void App::initShaders()
"uniform bool mask;\n" "uniform bool mask;\n"
"uniform bool fragUV2;\n" "uniform bool fragUV2;\n"
"uniform bool use_dual;\n" "uniform bool use_dual;\n"
"uniform bool use_pattern;\n"
"in mediump vec2 uv;\n" "in mediump vec2 uv;\n"
"out mediump vec4 frag;\n" "out mediump vec4 frag;\n"
SHADER_FUNCTION_BLUR SHADER_FUNCTION_BLUR
@@ -238,6 +240,9 @@ void App::initShaders()
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n" " mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
" mediump vec4 base = texture(tex, uv2);\n" " mediump vec4 base = texture(tex, uv2);\n"
" mediump vec4 stroke = texture(tex_stroke, uv);\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" " if (use_dual){\n"
" mediump vec4 dual = texture(tex_dual, uv);\n" " mediump vec4 dual = texture(tex_dual, uv);\n"
//" stroke.a = stroke.a * dual.a;\n" //" stroke.a = stroke.a * dual.a;\n"
@@ -385,16 +390,17 @@ void App::initShaders()
SHADER_EXT_FB_FETCH SHADER_EXT_FB_FETCH
"uniform mediump sampler2D tex;\n" "uniform mediump sampler2D tex;\n"
"uniform mediump sampler2D tex_bg;\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 sampler2D tex_mix;\n"
"uniform mediump vec4 col;\n" "uniform mediump vec4 col;\n"
"uniform mediump vec2 resolution;\n" "uniform mediump vec2 resolution;\n"
"uniform mediump float alpha;\n" "uniform mediump float alpha;\n"
"uniform mediump float noise;\n" "uniform mediump float noise;\n"
"uniform mediump vec2 stencil_offset;\n" "uniform mediump vec2 pattern_offset;\n"
"uniform mediump float stencil_alpha;\n" "uniform mediump float pattern_alpha;\n"
"uniform mediump float mix_alpha;\n" "uniform mediump float mix_alpha;\n"
"uniform mediump float wet;\n" "uniform mediump float wet;\n"
"uniform bool use_pattern;\n"
"in mediump vec2 uv;\n" "in mediump vec2 uv;\n"
"in mediump vec2 uv_2;\n" "in mediump vec2 uv_2;\n"
"in mediump float q;\n" "in mediump float q;\n"
@@ -406,9 +412,9 @@ void App::initShaders()
SHADER_FUNCTION_RAND SHADER_FUNCTION_RAND
"void main() {\n" "void main() {\n"
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\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 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" "#if defined(GL_EXT_shader_framebuffer_fetch)\n"
" mediump vec4 bg = frag;\n" " mediump vec4 bg = frag;\n"
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n" "#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
@@ -503,18 +509,18 @@ void App::initShaders()
static const char* shader_stroke_inst_f = static const char* shader_stroke_inst_f =
SHADER_VERSION SHADER_VERSION
"uniform mediump sampler2D tex;\n" "uniform mediump sampler2D tex;\n"
"uniform mediump sampler2D tex_stencil;\n" "uniform mediump sampler2D tex_pattern;\n"
"uniform mediump vec4 col;\n" "uniform mediump vec4 col;\n"
"uniform mediump vec2 resolution;\n" "uniform mediump vec2 resolution;\n"
"uniform mediump vec2 stencil_offset;\n" "uniform mediump vec2 pattern_offset;\n"
"uniform mediump float stencil_alpha;\n" "uniform mediump float pattern_alpha;\n"
"in mediump float alpha;\n" "in mediump float alpha;\n"
"in mediump vec3 uv;\n" "in mediump vec3 uv;\n"
"out mediump vec4 frag;\n" "out mediump vec4 frag;\n"
"void main() {\n" "void main() {\n"
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\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 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 * stencil;\n" " mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * pattern;\n"
" frag = vec4(col.rgb, a);\n" " frag = vec4(col.rgb, a);\n"
"}\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) 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); sampler.bind(0);
ShaderManager::use(kShader::CompDraw); ShaderManager::use(kShader::CompDraw);
ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::TexMask, 2);
ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size); ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size);
//ShaderManager::u_int(kShaderUniform::TexStencil, 3); ShaderManager::u_int(kShaderUniform::TexPattern, 3);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->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, canvas->m_canvas->m_layers[layer_index].m_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::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::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); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
canvas->m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); 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); glActiveTexture(GL_TEXTURE2);
canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture(); canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE3); glActiveTexture(GL_TEXTURE3);
if (canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture) if (b->m_pattern_texture)
canvas->m_canvas->m_current_stroke->m_brush->m_stencil_texture->bind(); b->m_pattern_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
m_face_plane.draw_fill(); 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); glActiveTexture(GL_TEXTURE2);
canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);

View File

@@ -291,7 +291,7 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
prng.seed(0); 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>(); m_tip_texture = std::make_shared<Texture2D>();
if (!m_tip_texture->load(path)) if (!m_tip_texture->load(path))
@@ -315,15 +315,15 @@ bool Brush::load_dual(const std::string& path, const std::string& thumb)
return true; 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>(); m_pattern_texture = std::make_shared<Texture2D>();
if (!m_stencil_texture->load(path)) if (!m_pattern_texture->load(path))
return false; return false;
m_stencil_texture->create_mipmaps(); m_pattern_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true; m_pattern_texture->auto_destroy = true;
m_stencil_path = path; m_pattern_path = path;
m_stencil_thumb_path = thumb; m_texture_thumb_path = thumb;
return true; return true;
} }
@@ -354,19 +354,19 @@ bool Brush::load()
m_dual_texture->create_mipmaps(); m_dual_texture->create_mipmaps();
m_dual_texture->auto_destroy = true; m_dual_texture->auto_destroy = true;
} }
if (!m_stencil_path.empty()) if (!m_pattern_path.empty())
{ {
m_stencil_texture = std::make_shared<Texture2D>(); m_pattern_texture = std::make_shared<Texture2D>();
if (!m_stencil_texture->load(m_stencil_path)) 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_tip_texture = nullptr;
m_dual_texture = nullptr; m_dual_texture = nullptr;
m_stencil_texture = nullptr; m_pattern_texture = nullptr;
return false; return false;
} }
m_stencil_texture->create_mipmaps(); m_pattern_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true; m_pattern_texture->auto_destroy = true;
} }
return true; return true;
} }

View File

@@ -18,9 +18,9 @@ public:
std::string m_dual_path; std::string m_dual_path;
std::string m_dual_thumb_path; std::string m_dual_thumb_path;
std::shared_ptr<Texture2D> m_stencil_texture; std::shared_ptr<Texture2D> m_pattern_texture;
std::string m_stencil_path; std::string m_pattern_path;
std::string m_stencil_thumb_path; std::string m_texture_thumb_path;
glm::vec4 m_tip_color{0, 0, 0, 1}; glm::vec4 m_tip_color{0, 0, 0, 1};
float m_tip_size = .25f; float m_tip_size = .25f;
@@ -30,7 +30,7 @@ public:
float m_tip_angle = 0; float m_tip_angle = 0;
float m_tip_angle_delay = 0; float m_tip_angle_delay = 0;
float m_tip_mix = 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_wet = 0;
float m_tip_noise = 0; float m_tip_noise = 0;
float m_tip_hue = 0; float m_tip_hue = 0;
@@ -51,7 +51,7 @@ public:
bool m_tip_invert = false; bool m_tip_invert = false;
bool m_tip_flipx = false; bool m_tip_flipx = false;
bool m_tip_flipy = false; bool m_tip_flipy = false;
bool m_tex_enabled = false; bool m_pattern_enabled = false;
bool m_dual_enabled = false; bool m_dual_enabled = false;
int m_dual_blend_mode = 0; int m_dual_blend_mode = 0;
bool m_dual_randflip = false; bool m_dual_randflip = false;
@@ -69,9 +69,18 @@ public:
float m_dual_opacity = 1.f; float m_dual_opacity = 1.f;
float m_dual_rotate = .25f; 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_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(); 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(0);
m_sampler.bind(1); m_sampler.bind(1);
m_sampler.bind(2); m_sampler.bind(2);
const auto& b = m_current_stroke->m_brush;
ShaderManager::use(kShader::CompDraw); ShaderManager::use(kShader::CompDraw);
ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::Tex, 0);
//ShaderManager::u_int(kShaderUniform::TexA, 0); //ShaderManager::u_int(kShaderUniform::TexA, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::TexMask, 2);
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size); //ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
//ShaderManager::u_int(kShaderUniform::TexStencil, 3); ShaderManager::u_int(kShaderUniform::TexPattern, 3);
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_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::Lock, false/*m_layers[layer_index].m_alpha_locked*/); 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::Mask, false/*m_smask_active*/);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
ShaderManager::u_int(kShaderUniform::UseDual, 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); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].bindTexture(); m_layers[layer_index].m_rtt[plane_index].bindTexture();
@@ -486,12 +489,13 @@ void Canvas::stroke_draw()
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg 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::TexMix, 3); // mixer
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer //ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
ShaderManager::u_vec2(kShaderUniform::StencilOffset, stencil_offset); ShaderManager::u_vec2(kShaderUniform::PatternOffset, stencil_offset);
ShaderManager::u_float(kShaderUniform::StencilAlpha, brush->m_tip_stencil); 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::MixAlpha, brush->m_tip_mix);
ShaderManager::u_float(kShaderUniform::Wet, brush->m_tip_wet); ShaderManager::u_float(kShaderUniform::Wet, brush->m_tip_wet);
ShaderManager::u_float(kShaderUniform::Noise, brush->m_tip_noise); ShaderManager::u_float(kShaderUniform::Noise, brush->m_tip_noise);
@@ -502,10 +506,8 @@ void Canvas::stroke_draw()
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
brush->m_tip_texture->bind(); brush->m_tip_texture->bind();
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
if (brush->m_stencil_texture) if (brush->m_pattern_texture)
brush->m_stencil_texture->bind(); brush->m_pattern_texture->bind();
else
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE3); glActiveTexture(GL_TEXTURE3);
m_mixer.bindTexture(); m_mixer.bindTexture();
auto frames = stroke_draw_compute(*m_current_stroke); auto frames = stroke_draw_compute(*m_current_stroke);
@@ -533,23 +535,19 @@ void Canvas::stroke_draw()
} }
glActiveTexture(GL_TEXTURE3); glActiveTexture(GL_TEXTURE3);
m_mixer.unbindTexture(); m_mixer.unbindTexture();
glActiveTexture(GL_TEXTURE2);
if (brush->m_stencil_texture)
brush->m_stencil_texture->unbind();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
brush->m_tip_texture->unbind(); brush->m_tip_texture->unbind();
// DRAW DUAL BRUSH // 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) if (brush->m_dual_enabled)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
dual_brush->m_tip_texture->bind(); 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); auto frames_dual = stroke_draw_compute(*m_dual_stroke);
for (auto& f : frames_dual) 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)); 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); glActiveTexture(GL_TEXTURE0);
dual_brush->m_tip_texture->unbind(); dual_brush->m_tip_texture->unbind();
} }
@@ -719,6 +714,8 @@ void Canvas::stroke_commit()
glViewport(0, 0, m_width, m_height); glViewport(0, 0, m_width, m_height);
glDisable(GL_BLEND); glDisable(GL_BLEND);
const auto& b = m_current_stroke->m_brush;
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
//m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); // reset bounding box //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.bind(0);
m_sampler_bg.bind(1); m_sampler_bg.bind(1);
m_sampler_mask.bind(2); 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) if (m_current_mode == kCanvasMode::Erase)
{ {
ShaderManager::use(kShader::CompErase); ShaderManager::use(kShader::CompErase);
@@ -764,7 +762,7 @@ void Canvas::stroke_commit()
ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::TexMask, 2);
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); 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_float(kShaderUniform::Alpha, 1);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); 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::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2); 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_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_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); 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_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
ShaderManager::u_int(kShaderUniform::TexDual, 3); ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::UseDual, m_current_stroke->m_brush->m_dual_enabled); ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
ShaderManager::u_int(kShaderUniform::DualBlendMode, m_current_stroke->m_brush->m_dual_blend_mode); ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind(); m_tex2[i].bind();
@@ -805,10 +806,14 @@ void Canvas::stroke_commit()
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[i].bindTexture(); m_smask.m_rtt[i].bindTexture();
glActiveTexture(GL_TEXTURE3); glActiveTexture(GL_TEXTURE3);
m_current_stroke->m_brush->m_dual_enabled ? if (b->m_dual_enabled)
m_tmp_dual[i].bindTexture() : glBindTexture(GL_TEXTURE_2D, 0); m_tmp_dual[i].bindTexture();
glActiveTexture(GL_TEXTURE4);
if (b->m_pattern_texture)
b->m_pattern_texture->bind();
m_plane.draw_fill(); 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(); m_tmp_dual[i].unbindTexture();
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[i].unbindTexture(); m_smask.m_rtt[i].unbindTexture();
@@ -822,7 +827,7 @@ void Canvas::stroke_commit()
// ShaderManager::use(kShader::StrokeLayer); // ShaderManager::use(kShader::StrokeLayer);
// ShaderManager::u_int(kShaderUniform::TexBG, 1); // ShaderManager::u_int(kShaderUniform::TexBG, 1);
// ShaderManager::u_int(kShaderUniform::Lock, m_layers[m_current_layer_idx].m_alpha_locked); // 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_int(kShaderUniform::Tex, 0);
// ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); // 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_vec2(kShaderUniform::Resolution, m_size);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
ShaderManager::u_float(kShaderUniform::StrokeAlpha, 1); 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_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity);
ShaderManager::u_int(kShaderUniform::Lock, false); ShaderManager::u_int(kShaderUniform::Lock, false);
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[source_idx].m_blend_mode); 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_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
ShaderManager::u_int(kShaderUniform::UseDual, false); ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern,false);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind(); m_tex2[i].bind();

View File

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

View File

@@ -88,7 +88,8 @@ void NodeCanvas::draw()
m_sampler.bind(0); m_sampler.bind(0);
m_sampler.bind(1); m_sampler.bind(1);
m_sampler.bind(2); m_sampler.bind(2);
m_sampler_stencil.bind(3); m_sampler.bind(3);
m_sampler_stencil.bind(4);
auto blend = glIsEnabled(GL_BLEND); auto blend = glIsEnabled(GL_BLEND);
auto depth = glIsEnabled(GL_DEPTH_TEST); auto depth = glIsEnabled(GL_DEPTH_TEST);
@@ -146,6 +147,8 @@ void NodeCanvas::draw()
use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND); use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST); 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++) for (size_t i = 0; i < m_canvas->m_order.size(); i++)
{ {
auto layer_index = m_canvas->m_order[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::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::TexMask, 2);
ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom); //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_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity); ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked); //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::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_int(kShaderUniform::TexMask, 2);
ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom); ShaderManager::u_int(kShaderUniform::TexDual, 3);
//ShaderManager::u_int(kShaderUniform::TexStencil, 3); //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_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_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::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false); 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_mat4(kShaderUniform::MVP, plane_mvp_z);
ShaderManager::u_int(kShaderUniform::TexDual, 3); ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
ShaderManager::u_int(kShaderUniform::UseDual, m_canvas->m_current_stroke->m_brush->m_dual_enabled); ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
ShaderManager::u_int(kShaderUniform::DualBlendMode, m_canvas->m_current_stroke->m_brush->m_dual_blend_mode); ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
@@ -224,11 +229,14 @@ void NodeCanvas::draw()
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
m_canvas->m_smask.m_rtt[plane_index].bindTexture(); m_canvas->m_smask.m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE3); glActiveTexture(GL_TEXTURE3);
m_canvas->m_current_stroke->m_brush->m_dual_enabled ? if (b->m_dual_enabled)
m_canvas->m_tmp_dual[plane_index].bindTexture() : m_canvas->m_tmp_dual[plane_index].bindTexture();
glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE4);
if (b->m_pattern_texture)
b->m_pattern_texture->bind();
m_face_plane.draw_fill(); 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(); m_canvas->m_tmp_dual[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); 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_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_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_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_path_len = b->m_brush->m_pattern_path.size();
i.m_stencil_thumb_path_len = b->m_brush->m_stencil_thumb_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_color = b->m_brush->m_tip_color;
i.m_tip_size = b->m_brush->m_tip_size; i.m_tip_size = b->m_brush->m_tip_size;
i.m_tip_spacing = b->m_brush->m_tip_spacing; i.m_tip_spacing = b->m_brush->m_tip_spacing;
i.m_tip_flow = b->m_brush->m_tip_flow; i.m_tip_flow = b->m_brush->m_tip_flow;
i.m_tip_opacity = b->m_brush->m_tip_opacity; i.m_tip_opacity = b->m_brush->m_tip_opacity;
i.m_tip_angle = b->m_brush->m_tip_angle; 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_angle_delay = b->m_brush->m_tip_angle_delay;
i.m_tip_mix = b->m_brush->m_tip_mix; i.m_tip_mix = b->m_brush->m_tip_mix;
i.m_tip_stencil = b->m_brush->m_tip_stencil; i.m_pattern_opacity = b->m_brush->m_pattern_opacity;
i.m_tip_wet = b->m_brush->m_tip_wet; i.m_tip_wet = b->m_brush->m_tip_wet;
i.m_tip_noise = b->m_brush->m_tip_noise; i.m_tip_noise = b->m_brush->m_tip_noise;
i.m_tip_hue = b->m_brush->m_tip_hue; i.m_tip_hue = b->m_brush->m_tip_hue;
i.m_tip_sat = b->m_brush->m_tip_sat; i.m_tip_sat = b->m_brush->m_tip_sat;
i.m_tip_val = b->m_brush->m_tip_val; 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_angle_follow = b->m_brush->m_tip_angle_follow;
i.m_tip_flow_pressure = b->m_brush->m_tip_flow_pressure; 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_tip_size_pressure = b->m_brush->m_tip_size_pressure;
i.m_jitter_scale = b->m_brush->m_jitter_scale; i.m_jitter_scale = b->m_brush->m_jitter_scale;
i.m_jitter_angle = b->m_brush->m_jitter_angle; i.m_jitter_angle = b->m_brush->m_jitter_angle;
i.m_jitter_spread = b->m_brush->m_jitter_spread; i.m_jitter_spread = b->m_brush->m_jitter_spread;
i.m_jitter_flow = b->m_brush->m_jitter_flow; i.m_jitter_flow = b->m_brush->m_jitter_flow;
i.m_jitter_hue = b->m_brush->m_jitter_hue; i.m_jitter_hue = b->m_brush->m_jitter_hue;
i.m_jitter_sat = b->m_brush->m_jitter_sat; i.m_jitter_sat = b->m_brush->m_jitter_sat;
i.m_jitter_val = b->m_brush->m_jitter_val; i.m_jitter_val = b->m_brush->m_jitter_val;
i.m_blend_mode = b->m_brush->m_blend_mode; i.m_blend_mode = b->m_brush->m_blend_mode;
i.m_tip_invert = b->m_brush->m_tip_invert; i.m_tip_invert = b->m_brush->m_tip_invert;
i.m_tip_flipx = b->m_brush->m_tip_flipx; i.m_tip_flipx = b->m_brush->m_tip_flipx;
i.m_tip_flipy = b->m_brush->m_tip_flipy; 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_enabled = b->m_brush->m_dual_enabled;
i.m_dual_blend_mode = b->m_brush->m_dual_blend_mode; i.m_dual_blend_mode = b->m_brush->m_dual_blend_mode;
i.m_dual_randflip = b->m_brush->m_dual_randflip; 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_opacity = b->m_brush->m_dual_opacity;
i.m_dual_rotate = b->m_brush->m_dual_rotate; 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(&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_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_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_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_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_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_pattern_path.c_str(), 1, b->m_brush->m_pattern_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_texture_thumb_path.c_str(), 1, b->m_brush->m_texture_thumb_path.size(), fp);
} }
fclose(fp); fclose(fp);
return true; return true;
@@ -634,36 +642,36 @@ bool NodePanelBrushPreset::restore()
item_t i; item_t i;
fread(&i, sizeof(i), 1, fp); fread(&i, sizeof(i), 1, fp);
auto b = std::make_shared<Brush>(); auto b = std::make_shared<Brush>();
b->m_tip_color = i.m_tip_color; b->m_tip_color = i.m_tip_color;
b->m_tip_size = i.m_tip_size; b->m_tip_size = i.m_tip_size;
b->m_tip_spacing = i.m_tip_spacing; b->m_tip_spacing = i.m_tip_spacing;
b->m_tip_flow = i.m_tip_flow; b->m_tip_flow = i.m_tip_flow;
b->m_tip_opacity = i.m_tip_opacity; b->m_tip_opacity = i.m_tip_opacity;
b->m_tip_angle = i.m_tip_angle; b->m_tip_angle = i.m_tip_angle;
b->m_tip_angle_delay = i.m_tip_angle_delay; b->m_tip_angle_delay = i.m_tip_angle_delay;
b->m_tip_mix = i.m_tip_mix; b->m_tip_mix = i.m_tip_mix;
b->m_tip_stencil = i.m_tip_stencil; b->m_pattern_opacity = i.m_pattern_opacity;
b->m_tip_wet = i.m_tip_wet; b->m_tip_wet = i.m_tip_wet;
b->m_tip_noise = i.m_tip_noise; b->m_tip_noise = i.m_tip_noise;
b->m_tip_hue = i.m_tip_hue; b->m_tip_hue = i.m_tip_hue;
b->m_tip_sat = i.m_tip_sat; b->m_tip_sat = i.m_tip_sat;
b->m_tip_val = i.m_tip_val; b->m_tip_val = i.m_tip_val;
b->m_tip_angle_follow = i.m_tip_angle_follow; b->m_tip_angle_follow = i.m_tip_angle_follow;
b->m_tip_flow_pressure = i.m_tip_flow_pressure; b->m_tip_flow_pressure = i.m_tip_flow_pressure;
b->m_tip_size_pressure = i.m_tip_size_pressure; b->m_tip_size_pressure = i.m_tip_size_pressure;
b->m_jitter_scale = i.m_jitter_scale; b->m_jitter_scale = i.m_jitter_scale;
b->m_jitter_angle = i.m_jitter_angle; b->m_jitter_angle = i.m_jitter_angle;
b->m_jitter_spread = i.m_jitter_spread; b->m_jitter_spread = i.m_jitter_spread;
b->m_jitter_flow = i.m_jitter_flow; b->m_jitter_flow = i.m_jitter_flow;
b->m_jitter_hue = i.m_jitter_hue; b->m_jitter_hue = i.m_jitter_hue;
b->m_jitter_sat = i.m_jitter_sat; b->m_jitter_sat = i.m_jitter_sat;
b->m_jitter_val = i.m_jitter_val; b->m_jitter_val = i.m_jitter_val;
b->m_blend_mode = i.m_blend_mode; b->m_blend_mode = i.m_blend_mode;
b->m_tip_invert = i.m_tip_invert; b->m_tip_invert = i.m_tip_invert;
b->m_tip_flipx = i.m_tip_flipx; b->m_tip_flipx = i.m_tip_flipx;
b->m_tip_flipy = i.m_tip_flipy; 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_enabled = i.m_dual_enabled;
b->m_dual_blend_mode = i.m_dual_blend_mode; b->m_dual_blend_mode = i.m_dual_blend_mode;
b->m_dual_randflip = i.m_dual_randflip; 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_opacity = i.m_dual_opacity;
b->m_dual_rotate = i.m_dual_rotate; 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_name.resize(i.m_name_len);
b->m_brush_path.resize(i.m_brush_path_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_brush_thumb_path.resize(i.m_brush_thumb_path_len);
b->m_dual_path.resize(i.m_brush_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_dual_thumb_path.resize(i.m_brush_thumb_path_len);
b->m_stencil_path.resize(i.m_stencil_path_len); b->m_pattern_path.resize(i.m_stencil_path_len);
b->m_stencil_thumb_path.resize(i.m_stencil_thumb_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_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_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_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_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_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_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp);
fread((char*)b->m_stencil_thumb_path.c_str(), 1, b->m_stencil_thumb_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()) if (!b->m_pattern_path.empty())
b->load_stencil(b->m_stencil_path, b->m_stencil_thumb_path); b->load_pattern(b->m_pattern_path, b->m_texture_thumb_path);
NodeBrushPresetItem* brush = new NodeBrushPresetItem; NodeBrushPresetItem* brush = new NodeBrushPresetItem;
m_container->add_child(brush); m_container->add_child(brush);

View File

@@ -111,7 +111,7 @@ class NodePanelBrushPreset : public Node
float m_tip_angle = 0; float m_tip_angle = 0;
float m_tip_angle_delay = 0; float m_tip_angle_delay = 0;
float m_tip_mix = 0; float m_tip_mix = 0;
float m_tip_stencil = 0; float m_pattern_opacity = 0;
float m_tip_wet = 0; float m_tip_wet = 0;
float m_tip_noise = 0; float m_tip_noise = 0;
float m_tip_hue = 0; float m_tip_hue = 0;
@@ -132,7 +132,7 @@ class NodePanelBrushPreset : public Node
bool m_tip_invert = false; bool m_tip_invert = false;
bool m_tip_flipx = false; bool m_tip_flipx = false;
bool m_tip_flipy = false; bool m_tip_flipy = false;
bool m_tex_enabled = false; bool m_pattern_enabled = false;
bool m_dual_enabled = false; bool m_dual_enabled = false;
int m_dual_blend_mode = 0; int m_dual_blend_mode = 0;
bool m_dual_randflip = false; bool m_dual_randflip = false;
@@ -149,6 +149,14 @@ class NodePanelBrushPreset : public Node
float m_dual_flow = .75f; float m_dual_flow = .75f;
float m_dual_opacity = 1.f; float m_dual_opacity = 1.f;
float m_dual_rotate = .25f; 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: public:
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed; 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_opacity->m_value.x = b->m_tip_opacity;
m_tip_angle->m_value.x = b->m_tip_angle; m_tip_angle->m_value.x = b->m_tip_angle;
m_tip_angle_delay->m_value.x = b->m_tip_angle_delay; 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_wet->m_value.x = b->m_tip_wet;
m_tip_noise->m_value.x = b->m_tip_noise; m_tip_noise->m_value.x = b->m_tip_noise;
m_jitter_scale->m_value.x = b->m_jitter_scale; 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_invert->checked = b->m_tip_invert;
m_tip_flipx->checked = b->m_tip_flipx; m_tip_flipx->checked = b->m_tip_flipx;
m_tip_flipy->checked = b->m_tip_flipy; 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_enabled->checked = b->m_dual_enabled;
m_dual_scatter_axis->checked = b->m_dual_scatter_axis; m_dual_scatter_axis->checked = b->m_dual_scatter_axis;
m_dual_invert->checked = b->m_dual_invert; 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_opacity->m_value.x = b->m_dual_opacity;
m_dual_rotate->m_value.x = b->m_dual_rotate; 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_blend_mode->set_index(b->m_blend_mode);
m_dual_blend_mode->set_index(b->m_dual_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->m_brush = b;
m_preview->draw_stroke(); m_preview->draw_stroke();
@@ -87,17 +96,17 @@ void NodePanelStroke::init_controls()
m_brush_popup->m_flood_events = true; m_brush_popup->m_flood_events = true;
m_brush_popup->m_capture_children = false; m_brush_popup->m_capture_children = false;
m_texture_popup = std::make_shared<NodePanelBrush>(); m_pattern_popup = std::make_shared<NodePanelBrush>();
m_texture_popup->m_manager = m_manager; m_pattern_popup->m_manager = m_manager;
m_texture_popup->m_dir_name = "textures"; m_pattern_popup->m_dir_name = "textures";
m_texture_popup->init(); m_pattern_popup->init();
m_texture_popup->create(); m_pattern_popup->create();
m_texture_popup->loaded(); m_pattern_popup->loaded();
m_texture_popup->SetPositioning(YGPositionTypeAbsolute); m_pattern_popup->SetPositioning(YGPositionTypeAbsolute);
m_texture_popup->SetSize(300, 400); m_pattern_popup->SetSize(300, 400);
m_texture_popup->m_mouse_ignore = false; m_pattern_popup->m_mouse_ignore = false;
m_texture_popup->m_flood_events = true; m_pattern_popup->m_flood_events = true;
m_texture_popup->m_capture_children = false; m_pattern_popup->m_capture_children = false;
m_presets_popup = std::make_shared<NodePanelBrushPreset>(); m_presets_popup = std::make_shared<NodePanelBrushPreset>();
m_presets_popup->m_manager = m_manager; m_presets_popup->m_manager = m_manager;
@@ -114,8 +123,9 @@ void NodePanelStroke::init_controls()
// init main brush // init main brush
auto b = std::make_shared<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_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_size = .1f;
b->m_tip_flow = .5f; b->m_tip_flow = .5f;
b->m_tip_spacing = .1f; 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_pattern_thumb = find<NodeImage>("pattern-change-thumb");
m_texture_thumb->set_image(m_texture_popup->get_thumb_path(0)); m_pattern_thumb->set_image(m_pattern_popup->get_thumb_path(0));
m_texture_button = find<NodeButtonCustom>("texture-change"); m_pattern_button = find<NodeButtonCustom>("pattern-change");
m_texture_button->on_click = [this](Node*) { m_pattern_button->on_click = [this](Node*) {
auto screen = root()->m_size; auto screen = root()->m_size;
glm::vec2 pos = m_texture_button->m_pos + glm::vec2(m_texture_button->m_size.x, 0); glm::vec2 pos = m_pattern_button->m_pos + glm::vec2(m_pattern_button->m_size.x, 0);
root()->add_child(m_texture_popup); root()->add_child(m_pattern_popup);
auto tick = root()->add_child<NodeImage>(); auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute); tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32); 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"); tick->set_image("data/ui/popup-tick.png");
root()->update(); root()->update();
if ((pos.y + m_texture_popup->m_size.y) > screen.y) if ((pos.y + m_pattern_popup->m_size.y) > screen.y)
pos.y = screen.y - m_texture_popup->m_size.y; pos.y = screen.y - m_pattern_popup->m_size.y;
if (pos.y < 0) if (pos.y < 0)
pos.y = 0; pos.y = 0;
m_texture_popup->SetPosition(pos.x + 16, pos.y); m_pattern_popup->SetPosition(pos.x + 16, pos.y);
m_texture_popup->mouse_capture(); m_pattern_popup->mouse_capture();
root()->update(); root()->update();
m_texture_popup->on_popup_close = [this, tick](Node*) { m_pattern_popup->on_popup_close = [this, tick](Node*) {
tick->destroy(); tick->destroy();
}; };
m_texture_popup->on_brush_changed = [this](Node*, int index) { m_pattern_popup->on_brush_changed = [this](Node*, int index) {
if (on_texture_changed) if (on_pattern_changed)
on_texture_changed(this, m_texture_popup->get_texture_path(index), m_texture_popup->get_thumb_path(index)); on_pattern_changed(this, m_pattern_popup->get_texture_path(index), m_pattern_popup->get_thumb_path(index));
m_texture_thumb->set_image(m_texture_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, "tip-angle", &Brush::m_tip_angle);
init_slider(m_tip_angle_delay, "tip-angle-delay", &Brush::m_tip_angle_delay); 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_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_wet, "tip-wet", &Brush::m_tip_wet);
init_slider(m_tip_noise, "tip-noise", &Brush::m_tip_noise); init_slider(m_tip_noise, "tip-noise", &Brush::m_tip_noise);
init_slider(m_tip_hue, "tip-hue", &Brush::m_tip_hue); 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_invert, "tip-invert", &Brush::m_tip_invert);
init_checkbox(m_tip_flipx, "tip-flipx", &Brush::m_tip_flipx); 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_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_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_scatter_axis, "dual-scatter-axis", &Brush::m_dual_scatter_axis);
init_checkbox(m_dual_invert, "dual-invert", &Brush::m_dual_invert); 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_dual_randflip, "dual-randflip", &Brush::m_dual_randflip);
init_checkbox(m_tip_randflipx, "tip-randflipx", &Brush::m_tip_randflipx); 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_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_size, "dual-size", &Brush::m_dual_size);
init_slider(m_dual_spacing, "dual-spacing", &Brush::m_dual_spacing); 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_opacity, "dual-opacity", &Brush::m_dual_opacity);
init_slider(m_dual_flow, "dual-flow", &Brush::m_dual_flow); 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_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_cubic = [](float v) { return glm::pow(v, 3.f); };
auto curve_quad = [](float v) { return glm::pow(v, 2.f); }; auto curve_quad = [](float v) { return glm::pow(v, 2.f); };
@@ -353,6 +371,14 @@ void NodePanelStroke::init_controls()
on_stroke_change(this); 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->m_brush = Canvas::I->m_current_brush;
m_preview->draw_stroke(); m_preview->draw_stroke();
@@ -363,8 +389,8 @@ void NodePanelStroke::init_controls()
App::I.async_start(); App::I.async_start();
if (TextureManager::load(path.c_str())) if (TextureManager::load(path.c_str()))
{ {
if (on_texture_changed) if (on_pattern_changed)
on_texture_changed(this, path, ""); on_pattern_changed(this, path, "");
} }
App::I.async_redraw(); App::I.async_redraw();
App::I.async_end(); App::I.async_end();

View File

@@ -21,7 +21,7 @@ public:
NodeSliderH* m_tip_angle; NodeSliderH* m_tip_angle;
NodeSliderH* m_tip_angle_delay; NodeSliderH* m_tip_angle_delay;
NodeSliderH* m_tip_mix; NodeSliderH* m_tip_mix;
NodeSliderH* m_tip_stencil; NodeSliderH* m_pattern_opacity;
NodeSliderH* m_tip_wet; NodeSliderH* m_tip_wet;
NodeSliderH* m_tip_noise; NodeSliderH* m_tip_noise;
NodeSliderH* m_tip_hue; NodeSliderH* m_tip_hue;
@@ -39,10 +39,10 @@ public:
NodeCheckBox* m_tip_size_pressure; NodeCheckBox* m_tip_size_pressure;
NodeButtonCustom* m_brush_button; NodeButtonCustom* m_brush_button;
NodeButtonCustom* m_dual_brush_button; NodeButtonCustom* m_dual_brush_button;
NodeButtonCustom* m_texture_button; NodeButtonCustom* m_pattern_button;
NodeImage* m_brush_thumb; NodeImage* m_brush_thumb;
NodeImage* m_dual_brush_thumb; NodeImage* m_dual_brush_thumb;
NodeImage* m_texture_thumb; NodeImage* m_pattern_thumb;
NodeImage* m_preset_thumb; NodeImage* m_preset_thumb;
NodeButtonCustom* m_preset_button; NodeButtonCustom* m_preset_button;
NodeStrokePreview* m_preset_preview; NodeStrokePreview* m_preset_preview;
@@ -50,7 +50,7 @@ public:
NodeCheckBox* m_tip_invert; NodeCheckBox* m_tip_invert;
NodeCheckBox* m_tip_flipx; NodeCheckBox* m_tip_flipx;
NodeCheckBox* m_tip_flipy; NodeCheckBox* m_tip_flipy;
NodeCheckBox* m_tex_enabled; NodeCheckBox* m_pattern_enabled;
NodeCheckBox* m_dual_enabled; NodeCheckBox* m_dual_enabled;
NodeCheckBox* m_dual_scatter_axis; NodeCheckBox* m_dual_scatter_axis;
NodeCheckBox* m_dual_invert; NodeCheckBox* m_dual_invert;
@@ -67,15 +67,26 @@ public:
NodeSliderH* m_dual_opacity; NodeSliderH* m_dual_opacity;
NodeSliderH* m_dual_rotate; NodeSliderH* m_dual_rotate;
NodeComboBox* m_dual_blend_mode; NodeComboBox* m_dual_blend_mode;
NodeComboBox* m_pattern_blend_mode;
NodeButtonCustom* m_tip_aspect_reset; 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_brush_popup;
std::shared_ptr<NodePanelBrush> m_texture_popup; std::shared_ptr<NodePanelBrush> m_pattern_popup;
std::shared_ptr<NodePanelBrushPreset> m_presets_popup; std::shared_ptr<NodePanelBrushPreset> m_presets_popup;
std::function<void(Node* target)> on_stroke_change; 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_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_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; std::map<NodeSliderH*, std::function<float(float)>> m_curves;
virtual Node* clone_instantiate() const override; virtual Node* clone_instantiate() const override;

View File

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

View File

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