improving mixer

This commit is contained in:
2018-08-02 09:44:14 +02:00
parent 8a3760df9e
commit 12c1aa33c4
10 changed files with 71 additions and 51 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -801,7 +801,9 @@
<text text="#opengl #fromscratch #c++" font-face="arial" font-size="11" margin="0 0 0 10" color=".2 .5 1 1"/>
</border>-->
</node>
<!-- <image-texture id="tex-debug" positioning="absolute" position="0 0" width="300" height="300"></image-texture> -->
<border color="1 1 1 1" positioning="absolute" position="0 0" width="300" height="300">
<image-texture id="tex-debug" width="100%" height="100%"></image-texture>
</border>
<!-- <color-picker/> -->
</layout>
</root>

View File

@@ -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;

View File

@@ -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 =

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);