mixer working pretty well now

This commit is contained in:
2018-08-05 00:34:07 +02:00
parent 12c1aa33c4
commit 9969594f54
6 changed files with 111 additions and 31 deletions

View File

@@ -37,12 +37,15 @@ void App::initShaders()
static const char* shader_alpha_f =
SHADER_VERSION
"uniform sampler2D tex;\n"
"uniform sampler2D tex_alpha;\n"
"uniform mediump float alpha;\n"
"uniform bool highlight;\n"
"in mediump vec3 uv;\n"
"out mediump vec4 frag;\n"
"void main(){\n"
" mediump vec4 c = texture(tex, uv.xy);\n"
" mediump vec3 rgb = texture(tex, uv.xy).rgb;\n"
" mediump float a = texture(tex_alpha, uv.xy).a;\n"
" mediump vec4 c = vec4(rgb, a);\n"
" frag = highlight ? \n"
" vec4(clamp(vec3(.3)+c.rgb, vec3(0), vec3(1)), c.a) : \n"
" texture(tex, uv.xy) * vec4(1,1,1,alpha);\n"
@@ -350,15 +353,15 @@ 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"
" rgb.rgb = mix(rgb.rgb, mbg.rgb, mix_alpha * mbg.a);\n"
" fg.rgb = mix(fg.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"

View File

@@ -219,16 +219,19 @@ void ui::Canvas::stroke_cancel()
m_current_stroke = nullptr;
m_show_tmp = false;
}
void ui::Canvas::stroke_draw_mix()
void ui::Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
{
m_mixer.bindFramebuffer();
m_mixer.clear({ 1, 1, 1, 0 });
glViewport(0, 0, m_mixer.getWidth(), m_mixer.getHeight());
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_SCISSOR_TEST);
glScissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_mixer.clear({ 1, 1, 1, 0 });
m_sampler.bind(0);
m_sampler_linear.bind(1);
auto layer_index = m_current_layer_idx;
for (int plane_index = 0; plane_index < 6; plane_index++)
{
@@ -244,28 +247,77 @@ void ui::Canvas::stroke_draw_mix()
ui::ShaderManager::use(kShader::TextureAlpha);
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
ui::ShaderManager::u_int(kShaderUniform::TexA, 1);
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
ui::ShaderManager::u_int(kShaderUniform::Highlight, false);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE1);
m_layers[layer_index].m_rtt[plane_index].bindTexture();
m_node->m_face_plane.draw_fill();
glActiveTexture(GL_TEXTURE1);
m_layers[layer_index].m_rtt[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].unbindTexture();
glEnable(GL_BLEND);
// glActiveTexture(GL_TEXTURE0);
// m_tmp[plane_index].bindTexture();
// glActiveTexture(GL_TEXTURE1);
// m_tmp[plane_index].bindTexture();
// m_node->m_face_plane.draw_fill();
// glActiveTexture(GL_TEXTURE1);
// m_tmp[plane_index].unbindTexture();
// glActiveTexture(GL_TEXTURE0);
// m_tmp[plane_index].unbindTexture();
m_sampler.bind(0);
m_sampler.bind(1);
m_sampler.bind(2);
auto& paper = TextureManager::get(const_hash("data/paper.jpg"));
ui::ShaderManager::use(kShader::CompDraw);
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
//ui::ShaderManager::u_int(kShaderUniform::TexA, 0);
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ui::ShaderManager::u_int(kShaderUniform::TexMask, 2);
//ui::ShaderManager::u_int(kShaderUniform::TexStencil, 3);
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
ui::ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index].m_alpha_locked);
ui::ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
ui::ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE1);
m_tmp[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE3);
paper.bind();
m_node->m_face_plane.draw_fill();
paper.unbind();
glActiveTexture(GL_TEXTURE2);
m_smask.m_rtt[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE1);
m_tmp[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[plane_index].unbindTexture();
}
m_sampler.unbind();
m_mixer.unbindFramebuffer();
glDisable(GL_SCISSOR_TEST);
}
void ui::Canvas::stroke_draw()
{
if (!(m_current_stroke && m_current_stroke->has_sample()))
{
//stroke_draw_mix({ 0,0 }, { m_mixer.getWidth(), m_mixer.getHeight() });
return;
}
m_dirty = true;
@@ -288,8 +340,31 @@ void ui::Canvas::stroke_draw()
m_mixer_idle = false;
}
if (m_brush.m_tip_mix > 0.f)
stroke_draw_mix();
static glm::vec2 UV2[4];
{
glm::vec2 dx(m_mixer_sample.size * 0.5f, 0), dy(0, m_mixer_sample.size * 0.5f);
glm::vec2 off[4] = {
-dx - dy, // A - bottom-left
-dx + dy, // B - top-left
+dx + dy, // C - top-right
+dx - dy, // D - bottom-right
};
auto sz = glm::vec2(m_mixer.getWidth(), m_mixer.getHeight()) * m_mixer_scale;
glm::vec2 bb_min(sz);
glm::vec2 bb_max(0, 0);
for (int j = 0; j < 4; j++)
{
auto p = (m_mixer_sample.pos + off[j] + glm::vec2(0, 1));
UV2[j] = p / sz;
//UV2[j].y = 1.f - UV2[j].y;
bb_min = glm::max({ 0, 0 }, glm::min(bb_min, p));
bb_max = glm::min(sz, glm::max(bb_max, p));
}
auto bb_sz = bb_max - bb_min;
if (m_brush.m_tip_mix > 0.f)
stroke_draw_mix(bb_min, bb_sz);
}
glViewport(0, 0, m_width, m_height);
@@ -298,7 +373,8 @@ void ui::Canvas::stroke_draw()
m_sampler_brush.bind(0);
m_sampler_bg.bind(1);
m_sampler_stencil.bind(2);
m_sampler_mix.bind(3);
m_sampler.bind(3);
//m_sampler_linear.bind(5);
glActiveTexture(GL_TEXTURE2);
stencil.bind();
@@ -313,6 +389,7 @@ void ui::Canvas::stroke_draw()
#endif
ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
ShaderManager::u_vec2(kShaderUniform::StencilOffset, stencil_offset);
ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil);
@@ -320,20 +397,6 @@ void ui::Canvas::stroke_draw()
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++)
{
glm::vec2 dx(m_mixer_sample.size * 0.5f, 0), dy(0, m_mixer_sample.size * 0.5f);
glm::vec2 off[4] = {
-dx - dy, // A - bottom-left
-dx + dy, // B - top-left
+dx + dy, // C - top-right
+dx - dy, // D - bottom-right
};
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++)
{
// check if plane is even visible
@@ -863,6 +926,7 @@ bool ui::Canvas::create(int width, int height)
m_tex2[i].create(width, height, GL_RGBA8); // TODO: destroy before recreating
}
m_sampler.create(GL_NEAREST);
m_sampler.create(GL_LINEAR);
m_sampler_brush.create();
m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
m_sampler_bg.create(GL_NEAREST);
@@ -878,7 +942,7 @@ bool ui::Canvas::create(int width, int height)
l.create(width, height, "");
}
m_smask.create(width*2, height*2, "mask");
m_smask.clear({1, 1, 1, 1});
//m_smask.clear({1, 1, 1, 1});
m_unsaved = true;
return true;
}

View File

@@ -90,6 +90,7 @@ public:
static glm::mat4 m_plane_transform[6];
glm::vec2 stencil_offset;
Sampler m_sampler;
Sampler m_sampler_linear;
Sampler m_sampler_brush;
Sampler m_sampler_bg;
Sampler m_sampler_mask;
@@ -131,7 +132,7 @@ public:
void layer_merge(int source_idx, int dest_idx);
void stroke_start(glm::vec2 point, float pressure, const ui::Brush& brush);
void stroke_update(glm::vec2 point, float pressure);
void stroke_draw_mix();
void stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz);
void stroke_draw();
void stroke_end();
void stroke_cancel();

View File

@@ -160,7 +160,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
#ifndef __IOS__
if (1)
if (!m_dragging)
{
auto pos = m_resizing ? m_size_pos_start : m_cur_pos;
if (App::I.keys[(int)kKey::KeyAlt])

View File

@@ -179,15 +179,25 @@ void NodeCanvas::draw()
}
else
{
m_sampler_linear.bind(0);
m_sampler.bind(0);
m_sampler_linear.bind(1);
ui::ShaderManager::use(kShader::TextureAlpha);
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
ui::ShaderManager::u_int(kShaderUniform::TexA, 1);
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
ui::ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index].m_hightlight);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
glActiveTexture(GL_TEXTURE1);
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
m_face_plane.draw_fill();
glActiveTexture(GL_TEXTURE1);
m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture();
glActiveTexture(GL_TEXTURE0);
m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture();
}

View File

@@ -7,9 +7,11 @@ enum class kShaderUniform : uint16_t
{
MVP = const_hash("mvp"),
Tex = const_hash("tex"),
TexA = const_hash("tex_alpha"),
TexFG = const_hash("tex_fg"),
TexBG = const_hash("tex_bg"),
TexMix = const_hash("tex_mix"),
TexMixA = const_hash("tex_mix_alpha"),
TexMask = const_hash("tex_mask"),
TexStroke = const_hash("tex_stroke"),
TexStencil = const_hash("tex_stencil"),