diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 924d98a..857df99 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -48,7 +48,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat { if (!canvas->m_canvas->m_layers[layer_index].m_visible || canvas->m_canvas->m_layers[layer_index].m_opacity == .0f || - !canvas->m_canvas->m_layers[layer_index].m_dirty_face) + !canvas->m_canvas->m_layers[layer_index].m_dirty_face[plane_index]) continue; int z = (int)(canvas->m_canvas->m_order.size() - i); diff --git a/src/canvas.cpp b/src/canvas.cpp index b1dd401..01322f1 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -247,7 +247,7 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) { if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == .0f || - !m_layers[layer_index].m_dirty_face) + !m_layers[layer_index].m_dirty_face[plane_index]) continue; glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f); @@ -1304,7 +1304,7 @@ void Canvas::export_equirectangular_thread(std::string file_path) { if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f || - !m_layers[layer_index].m_dirty_face) + !m_layers[layer_index].m_dirty_face[i]) continue; glActiveTexture(GL_TEXTURE2); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height); @@ -2094,7 +2094,7 @@ Image Canvas::thumbnail_generate(int w, int h) { if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f || - !m_layers[layer_index].m_dirty_face) + !m_layers[layer_index].m_dirty_face[i]) continue; glActiveTexture(GL_TEXTURE2); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index d7c5a73..606b6e6 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -65,11 +65,11 @@ void NodeCanvas::draw() glGetIntegerv(GL_VIEWPORT, vp); glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); - glClearColor(1, 1, 1, 0); - glClear(GL_COLOR_BUFFER_BIT); float zoom = root()->m_zoom; auto box = m_clip * zoom; glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w); + glClearColor(1, 1, 1, 0); + glClear(GL_COLOR_BUFFER_BIT); glViewport(c.x, c.y, c.z, c.w); //m_canvas->m_cam_rot = m_pan * 0.003f; @@ -94,8 +94,6 @@ void NodeCanvas::draw() auto blend = glIsEnabled(GL_BLEND); auto depth = glIsEnabled(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); float pitch = 0; if (auto slider = root()->find("pitch-slider")) @@ -107,20 +105,65 @@ void NodeCanvas::draw() if (auto slider = root()->find("roll-slider")) roll = (slider->get_value() - 0.5) * glm::half_pi(); - m_cache_rtt.bindFramebuffer(); - m_cache_rtt.clear({ 1, 1, 1, 0 }); + // pre computed helpers + for (int plane_index = 0; plane_index < 6; plane_index++) + { + //glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]); + m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]); + m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1)); + // face is the 2d shape of the cube plane i projected onto the window space + m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index); + } + + // check if any layer use blend, otherwise draw directly on main framebuffer + bool use_blend = false; + for (size_t i = 0; i < m_canvas->m_order.size(); i++) + { + auto layer_index = m_canvas->m_order[i]; + use_blend |= m_canvas->m_layers[layer_index].m_blend_mode != 0; + } + + if (use_blend) + { + m_cache_rtt.bindFramebuffer(); + m_cache_rtt.clear({ 1, 1, 1, 0 }); + } + else + { + // draw the grid + for (int plane_index = 0; plane_index < 6; plane_index++) + { + auto plane_mvp = proj * camera * + glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) * + m_canvas->m_plane_transform[plane_index] * + glm::translate(glm::vec3(0, 0, -1)); + + ShaderManager::use(kShader::Checkerboard); + ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); + m_face_plane.draw_fill(); + } + } + + // if not using shader blend, use gl rasterizer blend + use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + for (size_t i = 0; i < m_canvas->m_order.size(); i++) { auto layer_index = m_canvas->m_order[i]; for (int plane_index = 0; plane_index < 6; plane_index++) { - if (!m_canvas->m_layers[layer_index].m_visible || + 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].m_dirty_face) + !m_canvas->m_layers[layer_index].m_dirty_face[plane_index])) continue; - m_blender_rtt.bindFramebuffer(); - m_blender_rtt.clear(); + if (use_blend) + { + m_blender_rtt.bindFramebuffer(); + m_blender_rtt.clear(); + } int z = (int)(m_canvas->m_order.size() - i); auto plane_mvp_z = proj * camera * @@ -213,9 +256,13 @@ void NodeCanvas::draw() m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture(); } - m_blender_rtt.unbindFramebuffer(); + if (use_blend) + { + m_blender_rtt.unbindFramebuffer(); + } // draw the blended + if (use_blend) { m_sampler.bind(0); m_sampler_linear.bind(1); @@ -249,22 +296,19 @@ void NodeCanvas::draw() } } } - m_cache_rtt.unbindFramebuffer(); + if (use_blend) + { + m_cache_rtt.unbindFramebuffer(); + } // draw the grid behind the layers using a temporary copy + if (use_blend) { glEnable(GL_BLEND); //draw the grid for (int plane_index = 0; plane_index < 6; plane_index++) { - glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]); - m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]); - m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1)); - - // face is the 2d shape of the cube plane i projected onto the window space - m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index); - auto plane_mvp = proj * camera * glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) * m_canvas->m_plane_transform[plane_index] * @@ -317,6 +361,8 @@ void NodeCanvas::handle_resize(glm::vec2 old_size, glm::vec2 new_size) { if (new_size.x != m_canvas->m_width || new_size.y != m_canvas->m_height) { + // actual screen size + new_size = new_size * root()->m_zoom; #if defined(__IOS__) || defined(__ANDROID__) m_canvas->m_mixer.create((int)new_size.x * m_canvas->m_mixer_scale, (int)new_size.y * m_canvas->m_mixer_scale, -1, GL_RGBA16F);