From be3b3c089a015955ef142f9eb6ab0661c6676324 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 1 Aug 2018 17:11:49 +0200 Subject: [PATCH] mixer working with scaling factor --- data/layout.xml | 4 +- engine/canvas.cpp | 251 ++++++++++++++++++++--------------------- engine/canvas.h | 1 + engine/node_canvas.cpp | 2 +- 4 files changed, 124 insertions(+), 134 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 2147222..78b791b 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -801,7 +801,7 @@ --> - - + + diff --git a/engine/canvas.cpp b/engine/canvas.cpp index 20af869..4b021e8 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -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); diff --git a/engine/canvas.h b/engine/canvas.h index 18edf14..d06e87f 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -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; diff --git a/engine/node_canvas.cpp b/engine/node_canvas.cpp index 931b3d0..5c40203 100644 --- a/engine/node_canvas.cpp +++ b/engine/node_canvas.cpp @@ -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("tex-debug")) img->tex.assign(m_canvas->m_mixer.getTextureID()); // m_canvas->resize((int)new_size.x, (int)new_size.y);