From 12c1aa33c4785cbaa9842bb48e42f6a759e0a034 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 2 Aug 2018 09:44:14 +0200 Subject: [PATCH] improving mixer --- data/brushes/Round-Hard.png | Bin 1105 -> 26403 bytes data/layout.xml | 4 +- engine/app_layout.cpp | 5 ++- engine/app_shaders.cpp | 10 ++--- engine/brush.cpp | 2 +- engine/canvas.cpp | 82 ++++++++++++++++++------------------ engine/canvas.h | 2 +- engine/node_canvas.cpp | 2 +- engine/node_panel_brush.cpp | 13 ++++++ engine/node_panel_brush.h | 2 + 10 files changed, 71 insertions(+), 51 deletions(-) diff --git a/data/brushes/Round-Hard.png b/data/brushes/Round-Hard.png index 0ec829d8b58a066c543111dfef21218c807bed4a..da3bfc4b59e250c4a396df6fbc90afd9e3518fad 100644 GIT binary patch literal 26403 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 R_M95Vc){}d7v|Y-|9_z`x#<7^ literal 1105 zcmV-X1g`suP)(1-7@hVSRlarlzLC4TvGgG)-(Y8YoE;#^Z4W0AG&B<0wfIHX02y zO*4$B7$^Wu)39EzV=9&MUE0m5R0`|$I%=90WaMA~7>0q>Y85$-3%t199LHg`T1CS! zf{6Zg0L^9-bGcmT#qAbF5u42>I{?Gs5G$1m_2PE#@9*PqIHU`p*Xv=SP+(sE-GxE{ zd%YeV0PS`g^Z7jU(st+bd2F}a;Q~-q71QZ7^RjMEr_-paYB&Hooeq9o-dp{0VtQt%u9{xa=9D~07X%lm+@;wQN9LXFc@GalVM)OuQQnp z_WOPR0AyKaUgE2kW!WD9P1C4c+lOtAC>uEW*U6){c#xVX5W5{QM)&(Dc50zkXnrV@sQoVpPJ z?(grZgkd44ZUlhG$44q*Sjedx0pRuZl}Z>EdU<&v#v+LSpB|4yBGdx0kge{|njDQr zqr?~iU}k29N*EU6IF1-203;F#Dq&d2>Bl7iQ zEiF+A!$MBo2mqU#n^eNE(AL%#IXJl;wkZ~iL9tjI74F!pSS&&;79++TFNAh>c0vzC zTdtkl9*Tys&WDvpekdA^MqzJn&pX~R*Y57F<7F@aI3EFs-)myz>FLR>ru)Q5DwTqR zg9ERS$5xd}1q4BGe}gL;MC|wbKYMZ%5%Ki&lz9=qJ~=u0te&?85~Wg!d6`jNDwVuc z^9H~$3|w1VV_wRuS65d(uOuC5k<|SBJo9p&Ih)M}zews`cyEam;WfkFi@6dY8xhGSw>yggNPpdmYG_uhRI|y z@Z!m25^J^Ecy5`o%d#v~6a^(oLZ0V+m*#mMB}qa>QC#omzbayGFlc?;Hg|J#0}l@m z(Cv2N`S}?P!+`1OY2Y{x5{U%N&CS8W!oq*s<~BAqLf --> - + + + diff --git a/engine/app_layout.cpp b/engine/app_layout.cpp index d2faafa..7f2a29a 100644 --- a/engine/app_layout.cpp +++ b/engine/app_layout.cpp @@ -627,8 +627,9 @@ void App::initLayout() } Brush b; - b.m_tex_id = brushes->get_texture_id(0); - b.id = brushes->get_brush_id(0); + int br_idx = brushes->find_brush("Round-Hard"); + b.m_tex_id = brushes->get_texture_id(br_idx); + b.id = brushes->get_brush_id(br_idx); b.m_tip_size = .1f; b.m_tip_flow = .5f; b.m_tip_spacing = .1f; diff --git a/engine/app_shaders.cpp b/engine/app_shaders.cpp index b4c0c3a..d01dd7d 100644 --- a/engine/app_shaders.cpp +++ b/engine/app_shaders.cpp @@ -350,21 +350,21 @@ void App::initShaders() #endif " fg.a *= 1.0-rand(uv2+uv)*noise;\n" " if (fg.a == 0.0) discard;\n" + " mediump float contribution = (1.0 - bg.a) * fg.a;\n" + " mediump float alpha_tot = bg.a + contribution;" + " mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n" " if (mix_alpha > 0.0){\n" " mediump vec2 uv_mix = uv_2 / q;\n" " if (uv_mix.x < 0.0 || uv_mix.x > 1.0 || uv_mix.y < 0.0 || uv_mix.y > 1.0) discard;\n" " mediump vec4 mbg = texture(tex_mix, uv_mix);\n" - " fg.rgb = mix(fg.rgb, mbg.rgb, mix_alpha * mbg.a);\n" + " rgb.rgb = mix(rgb.rgb, mbg.rgb, mix_alpha * mbg.a);\n" " }\n" - " mediump float contribution = (1.0 - bg.a) * fg.a;\n" - " mediump float alpha_tot = bg.a + contribution;" - " mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n" " mediump vec4 frag_wet = vec4(rgb, max(bg.a, fg.a * 1.2));\n" " mediump vec4 frag_dry = vec4(rgb, alpha_tot);\n" " frag = mix(frag_dry, frag_wet, wet);\n" // " mediump vec4 mbg = texture(tex_mix, uv_2 / q);\n" -// " frag.rgb = mix(frag.rgb, mbg.rgb, mix_alpha);\n" +// " frag.rgb = mix(frag.rgb, mbg.rgb, mix_alpha * mbg.a);\n" "}\n"; static const char* shader_checkerboard_v = diff --git a/engine/brush.cpp b/engine/brush.cpp index 30dc9a0..5119d71 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -211,7 +211,7 @@ void ui::Stroke::add_point(glm::vec2 pos, float pressure) if (m_brush.m_tip_size_pressure) m_step = glm::max(m_brush.m_tip_spacing * m_brush.m_tip_size * pressure * 800.f, 1.f); - float dist = m_keypoints.empty() ? 0.f : + float dist = m_keypoints.empty() ? m_step : m_keypoints.back().dist + glm::distance(m_keypoints.back().pos, pos); if (m_keypoints.empty()) m_prev_sample.origin = pos; diff --git a/engine/canvas.cpp b/engine/canvas.cpp index 40fa749..4d0a9e2 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -228,7 +228,7 @@ void ui::Canvas::stroke_draw_mix() glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - m_sampler_bg.bind(0); + m_sampler.bind(0); auto layer_index = m_current_layer_idx; for (int plane_index = 0; plane_index < 6; plane_index++) { @@ -236,9 +236,10 @@ void ui::Canvas::stroke_draw_mix() continue; glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f); - auto plane_mvp_z = m_proj * m_mv * + auto plane_mvp_z = + glm::scale(glm::vec3(1, -1, 1)) * + m_proj * m_mv * m_plane_transform[plane_index] * - //glm::scale(glm::vec3(1, -1, 1)) * glm::translate(glm::vec3(0, 0, -1)); ui::ShaderManager::use(kShader::TextureAlpha); @@ -258,7 +259,7 @@ void ui::Canvas::stroke_draw_mix() m_node->m_face_plane.draw_fill(); m_tmp[plane_index].unbindTexture(); } - m_sampler_bg.unbind(); + m_sampler.unbind(); m_mixer.unbindFramebuffer(); } void ui::Canvas::stroke_draw() @@ -273,42 +274,11 @@ void ui::Canvas::stroke_draw() glGetIntegerv(GL_VIEWPORT, vp); glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); - stroke_draw_mix(); - - glViewport(0, 0, m_width, m_height); - - auto ortho_proj = glm::ortho(0.f, (float)m_width, 0.f, (float)m_height, -1.f, 1.f); - auto m_brush = m_current_stroke->m_brush; auto samples = m_current_stroke->compute_samples(); auto& tex = TextureManager::get(m_brush.m_tex_id); auto& stencil = TextureManager::get(const_hash("data/paper.jpg")); - glActiveTexture(GL_TEXTURE0); - tex.bind(); - m_sampler_brush.bind(0); - m_sampler_bg.bind(1); - m_sampler_stencil.bind(2); - m_sampler_mix.bind(3); - - glActiveTexture(GL_TEXTURE2); - stencil.bind(); - glActiveTexture(GL_TEXTURE3); - m_mixer.bindTexture(); - - glDisable(GL_BLEND); - ShaderManager::use(ui::kShader::Stroke); - ShaderManager::u_int(kShaderUniform::Tex, 0); // brush -#ifndef __IOS__ - ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg -#endif - ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil - ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer - ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); - ShaderManager::u_vec2(kShaderUniform::StencilOffset, stencil_offset); - ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil); - ShaderManager::u_float(kShaderUniform::MixAlpha, m_brush.m_tip_mix); - ShaderManager::u_float(kShaderUniform::Wet, m_brush.m_tip_wet); - ShaderManager::u_float(kShaderUniform::Noise, m_brush.m_tip_noise); + auto ortho_proj = glm::ortho(0.f, (float)m_width, 0.f, (float)m_height, -1.f, 1.f); for (const auto& s : samples) { @@ -317,7 +287,39 @@ void ui::Canvas::stroke_draw() m_mixer_sample = s; m_mixer_idle = false; } - + + if (m_brush.m_tip_mix > 0.f) + stroke_draw_mix(); + + glViewport(0, 0, m_width, m_height); + + glActiveTexture(GL_TEXTURE0); + tex.bind(); + m_sampler_brush.bind(0); + m_sampler_bg.bind(1); + m_sampler_stencil.bind(2); + m_sampler_mix.bind(3); + + glActiveTexture(GL_TEXTURE2); + stencil.bind(); + glActiveTexture(GL_TEXTURE3); + m_mixer.bindTexture(); + + glDisable(GL_BLEND); + ShaderManager::use(ui::kShader::Stroke); + ShaderManager::u_int(kShaderUniform::Tex, 0); // brush +#ifndef __IOS__ + ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg +#endif + ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil + ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer + ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); + ShaderManager::u_vec2(kShaderUniform::StencilOffset, stencil_offset); + ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil); + ShaderManager::u_float(kShaderUniform::MixAlpha, m_brush.m_tip_mix); + ShaderManager::u_float(kShaderUniform::Wet, m_brush.m_tip_wet); + ShaderManager::u_float(kShaderUniform::Noise, m_brush.m_tip_noise); + static glm::vec2 UV2[4]; for (int j = 0; j < 4; j++) { @@ -328,8 +330,8 @@ void ui::Canvas::stroke_draw() +dx + dy, // C - top-right +dx - dy, // D - bottom-right }; - UV2[j] = (m_mixer_sample.pos + off[j]) / glm::vec2(m_mixer.getWidth(), m_mixer.getHeight()) * m_mixer_scale; - UV2[j].y = 1 - UV2[j].y; + UV2[j] = (m_mixer_sample.pos + off[j] + glm::vec2(0,1)) / glm::vec2(m_mixer.getWidth(), m_mixer.getHeight()) * m_mixer_scale; + //UV2[j].y = 1.f - UV2[j].y; } for (int i = 0; i < 6; i++) @@ -866,7 +868,7 @@ bool ui::Canvas::create(int width, int height) m_sampler_bg.create(GL_NEAREST); m_sampler_mask.create(GL_LINEAR); m_sampler_stencil.create(GL_LINEAR, GL_REPEAT); - m_sampler_mix.create(GL_LINEAR, GL_REPEAT); + m_sampler_mix.create(GL_NEAREST, GL_REPEAT); m_plane.create<1>(1, 1); m_plane_brush.create<1>(1, 1); m_mesh.create(); diff --git a/engine/canvas.h b/engine/canvas.h index d06e87f..8da6ea6 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -76,7 +76,7 @@ public: bool m_smask_active = false; RTT m_tmp[6]; RTT m_mixer; - float m_mixer_scale = 0.25f; + float m_mixer_scale = 1; ui::StrokeSample m_mixer_sample; bool m_mixer_idle = true; Texture2D m_brush_mix; diff --git a/engine/node_canvas.cpp b/engine/node_canvas.cpp index 9bbaf19..0ab34cd 100644 --- a/engine/node_canvas.cpp +++ b/engine/node_canvas.cpp @@ -271,7 +271,7 @@ void NodeCanvas::handle_resize(glm::vec2 old_size, glm::vec2 new_size) if (new_size.x > m_canvas->m_width) { m_canvas->m_mixer.create((int)new_size.x * m_canvas->m_mixer_scale, - (int)new_size.y * m_canvas->m_mixer_scale); + (int)new_size.y * m_canvas->m_mixer_scale, -1, GL_RGBA32F); if (auto img = root()->find("tex-debug")) img->tex.assign(m_canvas->m_mixer.getTextureID()); // m_canvas->resize((int)new_size.x, (int)new_size.y); diff --git a/engine/node_panel_brush.cpp b/engine/node_panel_brush.cpp index ba5567c..f700f39 100644 --- a/engine/node_panel_brush.cpp +++ b/engine/node_panel_brush.cpp @@ -63,6 +63,7 @@ void NodePanelBrush::init() brush->set_icon(path.c_str()); brush->m_brushID = count++; brush->high_path = path_hi; + brush->brush_name = i; brush->high_id = const_hash(path_hi.c_str()); m_brushes.push_back(brush); brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1); @@ -82,6 +83,18 @@ void NodePanelBrush::handle_click(Node* target) on_brush_changed(this, m_current->m_brushID); } +int NodePanelBrush::find_brush(const std::string & name) const +{ + for (int i = 0; i < m_brushes.size(); i++) + { + if (m_brushes[i]->brush_name.find(name) != std::string::npos) + { + return i; + } + } + return -1; +} + uint16_t NodePanelBrush::get_texture_id(int index) const { TextureManager::load(m_brushes[index]->high_path.c_str(), true); diff --git a/engine/node_panel_brush.h b/engine/node_panel_brush.h index ff77001..8e54950 100644 --- a/engine/node_panel_brush.h +++ b/engine/node_panel_brush.h @@ -10,6 +10,7 @@ class NodeButtonBrush : public NodeButtonCustom public: int m_brushID; bool m_selected = false; + std::string brush_name; std::string high_path; uint16_t high_id; NodeImage* img; @@ -30,6 +31,7 @@ public: virtual void init() override; void handle_click(Node* target); std::vector FindAllBrushes(const std::string& folder); + int find_brush(const std::string& name) const; uint16_t get_texture_id(int index) const; int get_brush_id(int index) const; void select_brush(int brush_id);