diff --git a/src/canvas_layer.cpp b/src/canvas_layer.cpp index 7dc038d..76061e6 100644 --- a/src/canvas_layer.cpp +++ b/src/canvas_layer.cpp @@ -5,19 +5,25 @@ uint32_t Layer::s_count = 0; -RTT& Layer::rtt(int i) +RTT& Layer::rtt(int i, int frame /*= -1*/) { - return m_frames[m_frame_index].m_rtt[i]; + if (frame == -1) + frame = m_frame_index; + return m_frames[frame].m_rtt[i]; } -glm::vec4& Layer::box(int i) +glm::vec4& Layer::box(int i, int frame /*= -1*/) { - return m_frames[m_frame_index].m_dirty_box[i]; + if (frame == -1) + frame = m_frame_index; + return m_frames[frame].m_dirty_box[i]; } -bool& Layer::face(int i) +bool& Layer::face(int i, int frame /*= -1*/) { - return m_frames[m_frame_index].m_dirty_face[i]; + if (frame == -1) + frame = m_frame_index; + return m_frames[frame].m_dirty_face[i]; } LayerFrame& Layer::frame() diff --git a/src/canvas_layer.h b/src/canvas_layer.h index f49b145..bebaa76 100644 --- a/src/canvas_layer.h +++ b/src/canvas_layer.h @@ -54,9 +54,9 @@ public: void optimize(); int memsize() const; }; - RTT& rtt(int i); - glm::vec4& box(int i); - bool& face(int i); + RTT& rtt(int i, int frame = -1); + glm::vec4& box(int i, int frame = -1); + bool& face(int i, int frame = -1); LayerFrame& frame(); void resize(int width, int height); bool create(int width, int height, std::string name); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 6518a30..553b311 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -214,10 +214,16 @@ void NodeCanvas::draw() auto layer_index = i; for (int plane_index = 0; plane_index < 6; plane_index++) { - if (!(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) && + int onion_size = 1; + int frame_current = m_canvas->m_layers[layer_index]->m_frame_index; + int frame_start = glm::max(frame_current - 1, 0); + int frame_end = glm::min(frame_current + 1, m_canvas->m_layers[layer_index]->m_frames.size() - 1); + bool faces = false; + for (int frame = frame_start; frame <= frame_end; frame++) + faces |= m_canvas->m_layers[layer_index]->face(plane_index, frame); + if (!(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) && (!m_canvas->m_layers[layer_index]->m_visible || - m_canvas->m_layers[layer_index]->m_opacity == .0f || - !m_canvas->m_layers[layer_index]->face(plane_index))) + m_canvas->m_layers[layer_index]->m_opacity == .0f || !faces)) continue; if (use_blend) @@ -232,7 +238,7 @@ void NodeCanvas::draw() glm::eulerAngleYXZ(yaw, pitch, roll) * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); - + if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { m_sampler.bind(0); @@ -244,22 +250,27 @@ void NodeCanvas::draw() ShaderManager::u_int(kShaderUniform::TexStroke, 1); ShaderManager::u_int(kShaderUniform::TexMask, 2); //ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom); - ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity); //ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked); ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); - glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); m_canvas->m_smask.rtt(plane_index).bindTexture(); - m_face_plane.draw_fill(); + for (int frame = frame_start; frame <= frame_end; frame++) + { + float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1); + ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity* onion_alpha); + glActiveTexture(GL_TEXTURE0); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture(); + m_face_plane.draw_fill(); + glActiveTexture(GL_TEXTURE0); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).unbindTexture(); + } + glActiveTexture(GL_TEXTURE2); m_canvas->m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].unbindTexture(); - glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { @@ -280,7 +291,6 @@ void NodeCanvas::draw() ShaderManager::u_int(kShaderUniform::TexDual, 3); ShaderManager::u_int(kShaderUniform::TexPattern, 4); ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size); - ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity); ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked); ShaderManager::u_int(kShaderUniform::UseFragcoord, false); @@ -298,8 +308,6 @@ void NodeCanvas::draw() ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset); - glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); @@ -311,7 +319,16 @@ void NodeCanvas::draw() b->m_pattern_texture ? b->m_pattern_texture->bind() : glBindTexture(GL_TEXTURE_2D, 0); - m_face_plane.draw_fill(); + for (int frame = frame_start; frame <= frame_end; frame++) + { + float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1); + ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity * onion_alpha); + glActiveTexture(GL_TEXTURE0); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture(); + m_face_plane.draw_fill(); + glActiveTexture(GL_TEXTURE0); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).unbindTexture(); + } glActiveTexture(GL_TEXTURE3); if (b->m_dual_enabled) m_canvas->m_tmp_dual[plane_index].unbindTexture(); @@ -319,22 +336,24 @@ void NodeCanvas::draw() m_canvas->m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].unbindTexture(); - glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else { m_canvas->m_cam_fov < 20.f ? m_sampler_nearest.bind(0) : m_sampler.bind(0); ShaderManager::use(kShader::TextureAlpha); ShaderManager::u_int(kShaderUniform::Tex, 0); - ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity); ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); - glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); - m_face_plane.draw_fill(); - m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); + for (int frame = frame_start; frame <= frame_end; frame++) + { + float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1); + ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity * onion_alpha); + glActiveTexture(GL_TEXTURE0); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture(); + m_face_plane.draw_fill(); + m_canvas->m_layers[layer_index]->rtt(plane_index, frame).unbindTexture(); + } } if (use_blend)