improving mixer
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<NodeImageTexture>("tex-debug"))
|
||||
img->tex.assign(m_canvas->m_mixer.getTextureID());
|
||||
// m_canvas->resize((int)new_size.x, (int)new_size.y);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<std::string> 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);
|
||||
|
||||
Reference in New Issue
Block a user