mixer working with scaling factor

This commit is contained in:
2018-08-01 17:11:49 +02:00
parent 76033a1ca8
commit be3b3c089a
4 changed files with 124 additions and 134 deletions

View File

@@ -801,7 +801,7 @@
<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>
<!--<color-picker/>-->
<!-- <image-texture id="tex-debug" positioning="absolute" position="0 0" width="300" height="300"></image-texture> -->
<!-- <color-picker/> -->
</layout>
</root>

View File

@@ -235,6 +235,7 @@ void ui::Canvas::stroke_draw_mix()
if (m_layers[layer_index].m_opacity == .0f)
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 *
m_plane_transform[plane_index] *
//glm::scale(glm::vec3(1, -1, 1)) *
@@ -294,151 +295,139 @@ void ui::Canvas::stroke_draw()
glActiveTexture(GL_TEXTURE3);
m_mixer.bindTexture();
for (int i = 0; i < 6; i++)
{
// check if plane is even visible
glm::vec4 forward = m_mv * glm::vec4(0, 0, 1, 1);
float dot = glm::dot(xyz(forward), m_plane_normal[i]);
// TODO: use better threshold than 0.3
// some trigonometric shit, tangent and stuff
// if (dot < -0.3f)
// continue;
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);
m_tmp[i].bindFramebuffer();
glActiveTexture(GL_TEXTURE1);
m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing)
if (m_use_instanced)
for (const auto& s : samples)
{
if (m_mixer_idle)
{
glEnable(GL_BLEND);
ShaderManager::use(kShader::BrushStroke);
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
ShaderManager::u_int(kShaderUniform::Tex, 0);
m_mesh.draw(samples, ortho_proj);
m_mixer_sample = s;
m_mixer_idle = false;
}
else
static glm::vec2 UV2[4];
for (int j = 0; j < 4; j++)
{
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);
for (const auto& s : samples)
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(m_mixer.getWidth(), m_mixer.getHeight()) * m_mixer_scale;
UV2[j].y = 1 - UV2[j].y;
}
for (int i = 0; i < 6; i++)
{
// check if plane is even visible
glm::vec4 forward = m_mv * glm::vec4(0, 0, 1, 1);
float dot = glm::dot(xyz(forward), m_plane_normal[i]);
// TODO: use better threshold than 0.3
// some trigonometric shit, tangent and stuff
// if (dot < -0.3f)
// continue;
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.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
};
static glm::vec4 P[4];
int intersected = 0;
int inside = 0;
for (int j = 0; j < 4; j++)
{
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.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
};
static glm::vec4 P[4];
static glm::vec2 UV2[4];
int intersected = 0;
int inside = 0;
if (m_mixer_idle)
glm::vec3 ray_origin, ray_dir;
point_unproject(s.pos + off[j] * glm::orientate2(-s.angle), { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
glm::vec3 hit;
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i], hit))
{
m_mixer_sample = s;
m_mixer_idle = false;
glm::mat4 plane_camera = glm::lookAt(m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i]);
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
if (glm::abs(plane_local.x) < 1.5f && glm::abs(plane_local.y) < 1.5f)
{
inside++;
}
P[j].x = -(plane_local.x * 0.5f - 0.5f) * m_width;
P[j].y = (plane_local.y * 0.5f + 0.5f) * m_height;
intersected++;
}
for (int j = 0; j < 4; j++)
else
{
glm::vec3 ray_origin, ray_dir;
point_unproject(s.pos + off[j] * glm::orientate2(-s.angle), { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
{
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(m_mixer.getWidth(), m_mixer.getHeight());
UV2[j].y = 1 - UV2[j].y;
}
glm::vec3 hit;
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i], hit))
{
glm::mat4 plane_camera = glm::lookAt(m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i]);
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
if (glm::abs(plane_local.x) < 1.5f && glm::abs(plane_local.y) < 1.5f)
{
inside++;
}
P[j].x = -(plane_local.x * 0.5f - 0.5f) * m_width;
P[j].y = (plane_local.y * 0.5f + 0.5f) * m_height;
intersected++;
}
else
{
// if (i==0)
// LOG("no intersection with plane %d", i);
break;
}
break;
}
m_mixer_sample = s;
if (intersected < 4 || inside == 0)
continue;
m_dirty_face[i] = true;
glm::vec2 bb_min(m_width, m_height);
glm::vec2 bb_max(0, 0);
for (int j = 0; j < 4; j++)
{
bb_min = glm::max({ 0, 0 }, glm::min(bb_min, xy(P[j])));
bb_max = glm::min({ m_width, m_height }, glm::max(bb_max, xy(P[j])));
}
auto bb_sz = bb_max - bb_min;
glm::vec2 pad(1);
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad , { 0, 0 }, { m_width, m_height });
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz ) + pad*2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos));
#ifndef __IOS__
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
tex_pos.x, tex_pos.y,
tex_pos.x, tex_pos.y,
tex_sz.x, tex_sz.y);
#endif
m_dirty_box[i] = glm::vec4(
glm::min(xy(m_dirty_box[i]), (glm::vec2)tex_pos),
glm::max(zw(m_dirty_box[i]), (glm::vec2)(tex_pos + tex_sz))
);
ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj);
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush.m_tip_color.a));
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
m_plane_brush.update_vertices(P, nullptr, UV2);
m_plane_brush.draw_fill();
}
if (intersected < 4 || inside == 0)
continue;
m_dirty_face[i] = true;
m_tmp[i].bindFramebuffer();
glActiveTexture(GL_TEXTURE1);
m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing)
glm::vec2 bb_min(m_width, m_height);
glm::vec2 bb_max(0, 0);
for (int j = 0; j < 4; j++)
{
bb_min = glm::max({ 0, 0 }, glm::min(bb_min, xy(P[j])));
bb_max = glm::min({ m_width, m_height }, glm::max(bb_max, xy(P[j])));
}
auto bb_sz = bb_max - bb_min;
glm::vec2 pad(1);
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad , { 0, 0 }, { m_width, m_height });
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz ) + pad*2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos));
#ifndef __IOS__
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
tex_pos.x, tex_pos.y,
tex_pos.x, tex_pos.y,
tex_sz.x, tex_sz.y);
#endif
m_dirty_box[i] = glm::vec4(
glm::min(xy(m_dirty_box[i]), (glm::vec2)tex_pos),
glm::max(zw(m_dirty_box[i]), (glm::vec2)(tex_pos + tex_sz))
);
ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj);
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush.m_tip_color.a));
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
m_plane_brush.update_vertices(P, nullptr, UV2);
m_plane_brush.draw_fill();
glActiveTexture(GL_TEXTURE1);
m_tex[i].unbind();
m_tmp[i].unbindFramebuffer();
}
// if (m_alpha_lock)
// {
// glActiveTexture(GL_TEXTURE2);
// m_layers[m_current_layer_idx].m_rtt[i].unbindTexture();
// }
glActiveTexture(GL_TEXTURE1);
m_tex[i].unbind();
m_tmp[i].unbindFramebuffer();
}
m_mixer_sample = s;
}
glDisable(GL_BLEND);

View File

@@ -76,6 +76,7 @@ public:
bool m_smask_active = false;
RTT m_tmp[6];
RTT m_mixer;
float m_mixer_scale = 0.25f;
ui::StrokeSample m_mixer_sample;
bool m_mixer_idle = true;
Texture2D m_brush_mix;

View File

@@ -270,7 +270,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, (int)new_size.y);
m_canvas->m_mixer.create((int)new_size.x * m_canvas->m_mixer_scale, (int)new_size.y * m_canvas->m_mixer_scale);
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);