diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 59ee7ba..2e0f63d 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -179,11 +179,11 @@ void App::init_sidebar() auto& src = Canvas::I->m_layers[source_index]; for (int i = 0; i < 6; i++) { - if (!src->m_dirty_face[i]) + if (!src->face(i)) continue; - dst->m_rtt[i].copy(src->m_rtt[i]); - dst->m_dirty_face[i] = src->m_dirty_face[i]; - dst->m_dirty_box[i] = src->m_dirty_box[i]; + dst->rtt(i).copy(src->rtt(i)); + dst->face(i) = src->face(i); + dst->box(i) = src->box(i); dst->m_opacity = src->m_opacity; dst->m_blend_mode = src->m_blend_mode; dst->m_alpha_locked = src->m_alpha_locked; diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 196d182..e2240af 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -211,7 +211,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat if (!(canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) && (!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[plane_index])) + !canvas->m_canvas->m_layers[layer_index]->face(plane_index))) continue; int z = (int)(canvas->m_canvas->m_layers.size() - i); @@ -236,17 +236,17 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); canvas->m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); - canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture(); + canvas->m_canvas->m_smask.rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); + canvas->m_canvas->m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); canvas->m_canvas->m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else if (canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) { @@ -287,11 +287,11 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset); glActiveTexture(GL_TEXTURE0); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); canvas->m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); - canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture(); + canvas->m_canvas->m_smask.rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE3); if (b->m_dual_enabled) canvas->m_canvas->m_tmp_dual[plane_index].bindTexture(); @@ -304,11 +304,11 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat if (b->m_dual_enabled) canvas->m_canvas->m_tmp_dual[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE2); - canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); + canvas->m_canvas->m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); canvas->m_canvas->m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else { @@ -320,9 +320,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } } } diff --git a/src/canvas.cpp b/src/canvas.cpp index a9b6861..95a5e64 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -81,11 +81,11 @@ void Canvas::pick_update(int plane) draw_merge(true, faces); int i = plane; - m_layers_merge.m_rtt[i].bindFramebuffer(); + m_layers_merge.rtt(i).bindFramebuffer(); if (!m_pick_data[plane]) m_pick_data[plane] = std::make_unique(m_width * m_height); glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pick_data[plane].get()); - m_layers_merge.m_rtt[i].unbindFramebuffer(); + m_layers_merge.rtt(i).unbindFramebuffer(); }); m_pick_ready[plane] = true; @@ -168,7 +168,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[plane_index]) + !m_layers[layer_index]->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); @@ -198,17 +198,17 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[plane_index].bindTexture(); + m_smask.rtt(plane_index).bindTexture(); m_node->m_face_plane.draw_fill(); - m_smask.m_rtt[plane_index].unbindTexture(); + m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); } m_sampler.unbind(); m_mixer.unbindFramebuffer(); @@ -766,7 +766,7 @@ void Canvas::stroke_commit() if (!m_dirty_face[i]) continue; // no stroke on this face, skip it - m_layers[m_current_layer_idx]->m_rtt[i].bindFramebuffer(); + m_layers[m_current_layer_idx]->rtt(i).bindFramebuffer(); // save image before commit glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]); @@ -774,18 +774,18 @@ void Canvas::stroke_commit() glReadPixels(m_dirty_box[i].x, m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get()); action->m_box[i] = m_dirty_box[i]; - action->m_old_box[i] = m_layers[m_current_layer_idx]->m_dirty_box[i]; - action->m_old_dirty[i] = m_layers[m_current_layer_idx]->m_dirty_face[i]; + action->m_old_box[i] = m_layers[m_current_layer_idx]->box(i); + action->m_old_dirty[i] = m_layers[m_current_layer_idx]->face(i); if (!m_layers[m_current_layer_idx]->m_alpha_locked) { - auto& lbox = m_layers[m_current_layer_idx]->m_dirty_box[i]; + auto& lbox = m_layers[m_current_layer_idx]->box(i); lbox = glm::vec4( glm::min(xy(m_dirty_box[i]), xy(lbox)), glm::max(zw(m_dirty_box[i]), zw(lbox)) ); } - m_layers[m_current_layer_idx]->m_dirty_face[i] = true; + m_layers[m_current_layer_idx]->face(i) = true; // copy to tmp2 for layer blending glActiveTexture(GL_TEXTURE0); @@ -816,9 +816,9 @@ void Canvas::stroke_commit() glActiveTexture(GL_TEXTURE1); m_tmp[i].bindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[i].bindTexture(); + m_smask.rtt(i).bindTexture(); m_plane.draw_fill(); - m_smask.m_rtt[i].unbindTexture(); + m_smask.rtt(i).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[i].unbindTexture(); glActiveTexture(GL_TEXTURE0); @@ -860,7 +860,7 @@ void Canvas::stroke_commit() glActiveTexture(GL_TEXTURE1); m_tmp[i].bindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[i].bindTexture(); + m_smask.rtt(i).bindTexture(); glActiveTexture(GL_TEXTURE3); if (b->m_dual_enabled) m_tmp_dual[i].bindTexture(); @@ -873,7 +873,7 @@ void Canvas::stroke_commit() if (b->m_dual_enabled) m_tmp_dual[i].unbindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[i].unbindTexture(); + m_smask.rtt(i).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[i].unbindTexture(); glActiveTexture(GL_TEXTURE0); @@ -904,7 +904,7 @@ void Canvas::stroke_commit() glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height); m_plane.draw_fill(); - m_layers[m_current_layer_idx]->m_rtt[i].unbindFramebuffer(); + m_layers[m_current_layer_idx]->rtt(i).unbindFramebuffer(); } // restore viewport and clear color states @@ -945,13 +945,13 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI if (!faces[plane_index]) continue; - m_layers_merge.m_rtt[plane_index].bindFramebuffer(); - m_layers_merge.m_rtt[plane_index].clear({ 1, 1, 1, 0 }); + m_layers_merge.rtt(plane_index).bindFramebuffer(); + m_layers_merge.rtt(plane_index).clear({ 1, 1, 1, 0 }); if (use_blend) { glDisable(GL_BLEND); - m_layers_merge.m_rtt[plane_index].clear(); + m_layers_merge.rtt(plane_index).clear(); } else { @@ -970,7 +970,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI if (!(m_show_tmp && m_current_layer_idx == layer_index) && (!m_layers[layer_index]->m_visible || m_layers[layer_index]->m_opacity == .0f || - !m_layers[layer_index]->m_dirty_face[plane_index])) + !m_layers[layer_index]->face(plane_index))) continue; if (use_blend) @@ -995,17 +995,17 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ShaderManager::u_mat4(kShaderUniform::MVP, ortho); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[plane_index].bindTexture(); + m_smask.rtt(plane_index).bindTexture(); m_plane.draw_fill(); - m_smask.m_rtt[plane_index].unbindTexture(); + m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else if (m_current_stroke && m_show_tmp && m_current_layer_idx == layer_index) { @@ -1045,11 +1045,11 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_layers[layer_index]->rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[plane_index].bindTexture(); + m_smask.rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE3); if (b->m_dual_enabled) m_tmp_dual[plane_index].bindTexture(); @@ -1062,11 +1062,11 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI if (b->m_dual_enabled) m_tmp_dual[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE2); - m_smask.m_rtt[plane_index].unbindTexture(); + m_smask.rtt(plane_index).unbindTexture(); glActiveTexture(GL_TEXTURE1); m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else { @@ -1078,9 +1078,9 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI ShaderManager::u_mat4(kShaderUniform::MVP, ortho); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_layers[layer_index]->rtt(plane_index).bindTexture(); m_plane.draw_fill(); - m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); } if (use_blend) @@ -1155,7 +1155,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI m_merge_tex.unbind(); } - m_layers_merge.m_rtt[plane_index].unbindFramebuffer(); + m_layers_merge.rtt(plane_index).unbindFramebuffer(); } } @@ -1275,17 +1275,17 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index for (int i = 0; i < 6; i++) { - if (!m_layers[source_idx]->m_dirty_face[i]) + if (!m_layers[source_idx]->face(i)) continue; // no stroke on this face, skip it - m_layers[dest_idx]->m_rtt[i].bindFramebuffer(); + m_layers[dest_idx]->rtt(i).bindFramebuffer(); - auto& lbox = m_layers[dest_idx]->m_dirty_box[i]; + auto& lbox = m_layers[dest_idx]->box(i); lbox = glm::vec4( - glm::min(xy(m_layers[source_idx]->m_dirty_box[i]), xy(lbox)), - glm::max(zw(m_layers[source_idx]->m_dirty_box[i]), zw(lbox)) + glm::min(xy(m_layers[source_idx]->box(i)), xy(lbox)), + glm::max(zw(m_layers[source_idx]->box(i)), zw(lbox)) ); - m_layers[dest_idx]->m_dirty_face[i] = true; + m_layers[dest_idx]->face(i) = true; // copy to tmp2 for layer blending glActiveTexture(GL_TEXTURE0); @@ -1312,14 +1312,14 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index glActiveTexture(GL_TEXTURE0); m_tex2[i].bind(); glActiveTexture(GL_TEXTURE1); - m_layers[source_idx]->m_rtt[i].bindTexture(); + m_layers[source_idx]->rtt(i).bindTexture(); m_plane.draw_fill(); - m_layers[source_idx]->m_rtt[i].unbindTexture(); + m_layers[source_idx]->rtt(i).unbindTexture(); glActiveTexture(GL_TEXTURE0); m_tex2[i].unbind(); } - m_layers[dest_idx]->m_rtt[i].unbindFramebuffer(); + m_layers[dest_idx]->rtt(i).unbindFramebuffer(); } }); } @@ -1346,14 +1346,14 @@ void Canvas::flood_fill(int layer, int plane, std::vector pos, Flood LOG("flood_fill plane %d", plane); - auto& rtt = m_layers[layer]->m_rtt[plane]; + auto& rtt = m_layers[layer]->rtt(plane); auto sz = rtt.getSize(); if (!plane_data.mask[plane]) { plane_data.mask[plane] = std::make_unique((size_t)sz.x * sz.y); plane_data.rgb[plane] = std::unique_ptr( - reinterpret_cast(m_layers[layer]->m_rtt[plane].readTextureData())); + reinterpret_cast(m_layers[layer]->rtt(plane).readTextureData())); plane_data.bb[plane] = { sz.x, sz.y, 0, 0 }; plane_data.dirty[plane] = false; plane_data.layer = m_layers[layer]; @@ -1488,7 +1488,7 @@ void Canvas::FloodData::apply() { if (!dirty[plane]) continue; - auto& rtt = layer->m_rtt[plane]; + auto& rtt = layer->rtt(plane); App::I->render_task([&] { rtt.bindTexture(); @@ -1496,8 +1496,8 @@ void Canvas::FloodData::apply() GL_RGBA, GL_UNSIGNED_BYTE, rgb[plane].get()); rtt.unbindTexture(); }); - layer->m_dirty_face[plane] = true; - layer->m_dirty_box[plane] = box_union(layer->m_dirty_box[plane], bb[plane]); + layer->face(plane) = true; + layer->box(plane) = box_union(layer->box(plane), bb[plane]); } Canvas::I->m_unsaved = true; } @@ -1713,8 +1713,8 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt } for (int i = 0; i < 6; i++) { - layer->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); - layer->m_dirty_face[i] = true; + layer->box(i) = glm::vec4(0, 0, m_width, m_height); + layer->face(i) = true; } } @@ -1852,9 +1852,9 @@ void Canvas::export_depth_thread(std::string file_name) ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - m_layers_merge.m_rtt[plane_index].bindTexture(); + m_layers_merge.rtt(plane_index).bindTexture(); m_plane.draw_fill(); - m_layers_merge.m_rtt[plane_index].unbindTexture(); + m_layers_merge.rtt(plane_index).unbindTexture(); } rtt.unbindFramebuffer(); }); @@ -1878,7 +1878,7 @@ void Canvas::export_depth_thread(std::string file_name) { if ((!m_layers[layer_index]->m_visible || m_layers[layer_index]->m_opacity == .0f || - !m_layers[layer_index]->m_dirty_face[plane_index])) + !m_layers[layer_index]->face(plane_index))) continue; auto plane_mvp_z = proj * camera * @@ -1893,9 +1893,9 @@ void Canvas::export_depth_thread(std::string file_name) ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_layers[layer_index]->rtt(plane_index).bindTexture(); m_plane.draw_fill(); - m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); } } rtt.unbindFramebuffer(); @@ -1967,7 +1967,7 @@ void Canvas::export_cube_faces_thread(std::string file_name) for (int i = 0; i < 6; i++) { - Image face = m_layers_merge.m_rtt[i].get_image(); + Image face = m_layers_merge.rtt(i).get_image(); std::string path = fmt::format("{}/{}-{}.png", App::I->work_path, file_name, plane_names[i]); face.save_png(path); pb->increment(); @@ -2405,7 +2405,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[i]) + !m_layers[layer_index]->face(i)) continue; if (!ShaderManager::ext_framebuffer_fetch) { @@ -2415,9 +2415,9 @@ Image Canvas::thumbnail_generate(int w, int h) ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode); ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity); glActiveTexture(GL_TEXTURE0); - m_layers[layer_index]->m_rtt[i].bindTexture(); + m_layers[layer_index]->rtt(i).bindTexture(); m_face_plane.draw_fill(); - m_layers[layer_index]->m_rtt[i].unbindTexture(); + m_layers[layer_index]->rtt(i).unbindTexture(); } if (!ShaderManager::ext_framebuffer_fetch) @@ -2517,16 +2517,16 @@ void Canvas::draw_objects_direct(std::functionm_box[i] = bounds; } - action->m_old_box[i] = layer.m_dirty_box[i]; - action->m_old_dirty[i] = layer.m_dirty_face[i]; + action->m_old_box[i] = layer.box(i); + action->m_old_dirty[i] = layer.face(i); // draw the tmp layer into the actual layer if (has_data) @@ -2608,11 +2608,11 @@ void Canvas::draw_objects(std::function(reinterpret_cast(m_rtt[i].readTextureData())); - glm::ivec2 bbmin(w,h); - glm::ivec2 bbmax(0); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - if (data[x + y * w].a > 0) - { - bbmin = glm::min(bbmin, { x, y }); - bbmax = glm::max(bbmax, { x + 1, y + 1 }); - } - } - } - glm::vec2 bbsz = bbmax - bbmin; - glm::vec2 old_size = zw(m_dirty_box[i]) - xy(m_dirty_box[i]); - glm::vec2 diff; - if (bbsz.x <= 0 || bbmax.y <= 0) - { - m_dirty_face[i] = false; - m_dirty_box[i] = glm::vec4(0); - diff = old_size; - } - else - { - m_dirty_box[i] = { bbmin, bbmax }; - - diff = old_size - bbsz; - } - saved_bytes += (int)(diff.x * diff.y * 4); - } - LOG("optimized %d bytes", saved_bytes); -} - -void Layer::restore(const Snapshot& snap) -{ - clear({ 0, 0, 0, 0 }); - for (int i = 0; i < 6; i++) - { - if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0) - { - m_dirty_box[i] = glm::vec4(snap.width, snap.height, 0, 0); - m_dirty_face[i] = false; - continue; - } - - m_dirty_box[i] = snap.m_dirty_box[i]; - m_dirty_face[i] = snap.m_dirty_face[i]; - - // TODO: this should not be recreated here! - // Sorry I messed up with this, - // it's just a quick fix DON'T SHIP!! - //m_rtt[i].recreate(); - - App::I->render_task_async([this,i,&snap] - { - m_rtt[i].bindTexture(); - glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]); - glTexSubImage2D(GL_TEXTURE_2D, 0, - m_dirty_box[i].x, m_dirty_box[i].y, - box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, - snap.image[i].get()); - m_rtt[i].unbindTexture(); - LOG("restore face %d - %d bytes (%dx%d)", i, - (int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y); - }); - } - App::I->render_sync(); -} - -Layer::Snapshot Layer::snapshot(std::array * dirty_box /*= nullptr*/, std::array * dirty_face /*= nullptr*/) -{ - Snapshot snap; - snap.width = w; - snap.height = h; - for (int i = 0; i < 6; i++) - { - snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : m_dirty_box[i]; - snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : m_dirty_face[i]; - - if (!snap.m_dirty_face[i]) - continue; - - snap.image[i] = std::make_unique(m_rtt[i].bytes()); - - App::I->render_task_async([this,i,&snap] - { - m_rtt[i].bindFramebuffer(); - glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]); - glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y, - box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get()); - m_rtt[i].unbindFramebuffer(); - }); - } - App::I->render_sync(); - return snap; -} - -void Layer::clear(const glm::vec4& c) -{ - App::I->render_task([&] - { - // push clear color state - GLfloat cc[4]; - glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); - glClearColor(c.r, c.g, c.b, c.a); - - bool erase = (c.a == 0.f); - - for (int i = 0; i < 6; i++) - { - m_rtt[i].bindFramebuffer(); - glClear(GL_COLOR_BUFFER_BIT); - m_rtt[i].unbindFramebuffer(); - - if (erase) - { - m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box - m_dirty_face[i] = false; - } - else - { - m_dirty_box[i] = glm::vec4(0, 0, w, h); // reset bounding box - m_dirty_face[i] = true; - } - } - - // restore clear color state - glClearColor(cc[0], cc[1], cc[2], cc[3]); - }); -} - -bool Layer::create(int width, int height, std::string name) -{ - m_name = name; - w = width; - h = height; - App::I->render_task([&] - { - for (int i = 0; i < 6; i++) - { - m_rtt[i].create(width, height); - m_rtt[i].bindFramebuffer(); - m_rtt[i].clear(); - m_rtt[i].unbindFramebuffer(); - m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box - m_dirty_face[i] = false; - } - }); - return true; -} - -void Layer::resize(int width, int height) -{ - glm::vec2 ratio = glm::vec2(width, height) / glm::vec2(w, h); - w = width; - h = height; - for (int i = 0; i < 6; i++) - { - m_rtt[i].resize(width, height); - m_dirty_box[i] = m_dirty_box[i] * glm::vec4(ratio, ratio); - //m_dirty_face[i] = true; - } -} diff --git a/src/canvas.h b/src/canvas.h index a9c5106..df6e447 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -127,13 +127,13 @@ public: Texture2D m_tex2[6]; RTT m_merge_rtt; Texture2D m_merge_tex; - bool m_pick_ready[6]; + bool m_pick_ready[6] = SIXPLETTE(false); std::unique_ptr m_pick_data[6] = SIXPLETTE(nullptr); static glm::vec3 m_plane_origin[6]; static glm::vec3 m_plane_normal[6]; static glm::vec3 m_plane_tangent[6]; static glm::mat4 m_plane_transform[6]; - glm::vec2 m_pattern_offset; + glm::vec2 m_pattern_offset{ 0 }; Sampler m_sampler; Sampler m_sampler_nearest; Sampler m_sampler_linear; @@ -145,7 +145,7 @@ public: float m_cam_fov = 85.f; const float m_cam_fov_min = 5.f; const float m_cam_fov_max = 150.f; - glm::vec2 m_cur_pos; + glm::vec2 m_cur_pos{ 0 }; std::shared_ptr m_current_brush; diff --git a/src/canvas_actions.cpp b/src/canvas_actions.cpp index bf4cc11..71fabdd 100644 --- a/src/canvas_actions.cpp +++ b/src/canvas_actions.cpp @@ -17,18 +17,18 @@ void ActionStroke::undo() LOG("undo box %d dirty=%s [%d,%d,%d,%d] to dirty=%s [%d,%d,%d,%d]", i, - m_canvas->m_layers[m_layer_idx]->m_dirty_face[i] ? "true" : "false", - (int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].x, - (int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].y, - (int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].z, - (int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].w, + m_canvas->m_layers[m_layer_idx]->face(i) ? "true" : "false", + (int)m_canvas->m_layers[m_layer_idx]->box(i).x, + (int)m_canvas->m_layers[m_layer_idx]->box(i).y, + (int)m_canvas->m_layers[m_layer_idx]->box(i).z, + (int)m_canvas->m_layers[m_layer_idx]->box(i).w, m_old_dirty[i] ? "true" : "false", (int)m_old_box[i].x, (int)m_old_box[i].y, (int)m_old_box[i].z, (int)m_old_box[i].w); - m_canvas->m_layers[m_layer_idx]->m_dirty_box[i] = m_old_box[i]; - m_canvas->m_layers[m_layer_idx]->m_dirty_face[i] = m_old_dirty[i]; + m_canvas->m_layers[m_layer_idx]->box(i) = m_old_box[i]; + m_canvas->m_layers[m_layer_idx]->face(i) = m_old_dirty[i]; glm::vec2 box_sz = zw(m_box[i]) - xy(m_box[i]); @@ -36,9 +36,9 @@ void ActionStroke::undo() { App::I->render_task([&] { - m_canvas->m_layers[m_layer_idx]->m_rtt[i].bindTexture(); + m_canvas->m_layers[m_layer_idx]->rtt(i).bindTexture(); glTexSubImage2D(GL_TEXTURE_2D, 0, (int)m_box[i].x, (int)m_box[i].y, (int)box_sz.x, (int)box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image[i].get()); - m_canvas->m_layers[m_layer_idx]->m_rtt[i].unbindTexture(); + m_canvas->m_layers[m_layer_idx]->rtt(i).unbindTexture(); }); } else @@ -65,11 +65,11 @@ Action* ActionStroke::get_redo() auto& layer = m_canvas->m_layers[m_layer_idx]; for (int i = 0; i < 6; i++) { - if (!layer->m_dirty_face[i] && !m_image[i]) + if (!layer->face(i) && !m_image[i]) continue; // no stroke on this face, skip it - auto box = clear_layer ? glm::ivec4(layer->m_dirty_box[i]) : m_box[i]; + auto box = clear_layer ? glm::ivec4(layer->box(i)) : m_box[i]; // save image before commit glm::vec2 box_or = xy(box); @@ -79,9 +79,9 @@ Action* ActionStroke::get_redo() action->m_image[i] = std::make_unique(box_sz.x * box_sz.y * 4); App::I->render_task([&] { - layer->m_rtt[i].bindFramebuffer(); + layer->rtt(i).bindFramebuffer(); glReadPixels(box_or.x, box_or.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get()); - layer->m_rtt[i].unbindFramebuffer(); + layer->rtt(i).unbindFramebuffer(); }); } else @@ -90,8 +90,8 @@ Action* ActionStroke::get_redo() } action->m_box[i] = box; - action->m_old_box[i] = layer->m_dirty_box[i]; - action->m_old_dirty[i] = layer->m_dirty_face[i]; + action->m_old_box[i] = layer->box(i); + action->m_old_dirty[i] = layer->face(i); } // save history action->m_layer_idx = m_layer_idx; diff --git a/src/canvas_layer.cpp b/src/canvas_layer.cpp index 844eeb3..f84df79 100644 --- a/src/canvas_layer.cpp +++ b/src/canvas_layer.cpp @@ -5,6 +5,26 @@ uint32_t Layer::s_count = 0; +RTT& Layer::rtt(int i) +{ + return m_frames[m_frame_index].m_rtt[i]; +} + +glm::vec4& Layer::box(int i) +{ + return m_frames[m_frame_index].m_dirty_box[i]; +} + +bool& Layer::face(int i) +{ + return m_frames[m_frame_index].m_dirty_face[i]; +} + +LayerFrame& Layer::frame() +{ + return m_frames[m_frame_index]; +} + TextureCube Layer::gen_cube() { TextureCube ret; @@ -14,9 +34,9 @@ TextureCube Layer::gen_cube() ret.bind(); for (int i = 0; i < 6; i++) { - m_rtt[i].bindFramebuffer(); + rtt(i).bindFramebuffer(); glCopyTexSubImage2D(TextureCube::m_faces_map[i], 0, 0, 0, 0, 0, w, w); - m_rtt[i].unbindFramebuffer(); + rtt(i).unbindFramebuffer(); } }); return ret; @@ -69,6 +89,189 @@ Texture2D Layer::gen_equirect() return ret; } +void Layer::destroy() +{ + for (int i = 0; i < 6; i++) + rtt(i).destroy(); +} + +void Layer::optimize() +{ + int saved_bytes = 0; + for (int i = 0; i < 6; i++) + { + if (!face(i)) + continue; + + auto data = std::unique_ptr(reinterpret_cast(rtt(i).readTextureData())); + glm::ivec2 bbmin(w, h); + glm::ivec2 bbmax(0); + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + if (data[x + y * w].a > 0) + { + bbmin = glm::min(bbmin, { x, y }); + bbmax = glm::max(bbmax, { x + 1, y + 1 }); + } + } + } + glm::vec2 bbsz = bbmax - bbmin; + glm::vec2 old_size = zw(box(i)) - xy(box(i)); + glm::vec2 diff; + if (bbsz.x <= 0 || bbmax.y <= 0) + { + face(i) = false; + box(i) = glm::vec4(0); + diff = old_size; + } + else + { + box(i) = { bbmin, bbmax }; + + diff = old_size - bbsz; + } + saved_bytes += (int)(diff.x * diff.y * 4); + } + LOG("optimized %d bytes", saved_bytes); +} + +void Layer::restore(const Snapshot& snap) +{ + clear({ 0, 0, 0, 0 }); + for (int i = 0; i < 6; i++) + { + if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0) + { + box(i) = glm::vec4(snap.width, snap.height, 0, 0); + face(i) = false; + continue; + } + + box(i) = snap.m_dirty_box[i]; + face(i) = snap.m_dirty_face[i]; + + // TODO: this should not be recreated here! + // Sorry I messed up with this, + // it's just a quick fix DON'T SHIP!! + //m_rtt[i].recreate(); + + App::I->render_task_async([this, i, &snap] + { + rtt(i).bindTexture(); + glm::vec2 box_sz = zw(box(i)) - xy(box(i)); + glTexSubImage2D(GL_TEXTURE_2D, 0, + box(i).x, box(i).y, + box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, + snap.image[i].get()); + rtt(i).unbindTexture(); + LOG("restore face %d - %d bytes (%dx%d)", i, + (int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y); + }); + } + App::I->render_sync(); +} + +Layer::Snapshot Layer::snapshot(std::array* dirty_box /*= nullptr*/, std::array* dirty_face /*= nullptr*/) +{ + Snapshot snap; + snap.width = w; + snap.height = h; + for (int i = 0; i < 6; i++) + { + snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : box(i); + snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : face(i); + + if (!snap.m_dirty_face[i]) + continue; + + snap.image[i] = std::make_unique(rtt(i).bytes()); + + App::I->render_task_async([this, i, &snap] + { + rtt(i).bindFramebuffer(); + glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]); + glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y, + box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get()); + rtt(i).unbindFramebuffer(); + }); + } + App::I->render_sync(); + return snap; +} + +void Layer::clear(const glm::vec4& c) +{ + App::I->render_task([&] + { + // push clear color state + GLfloat cc[4]; + glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); + glClearColor(c.r, c.g, c.b, c.a); + + bool erase = (c.a == 0.f); + + for (int i = 0; i < 6; i++) + { + rtt(i).bindFramebuffer(); + glClear(GL_COLOR_BUFFER_BIT); + rtt(i).unbindFramebuffer(); + + if (erase) + { + box(i) = glm::vec4(w, h, 0, 0); // reset bounding box + face(i) = false; + } + else + { + box(i) = glm::vec4(0, 0, w, h); // reset bounding box + face(i) = true; + } + } + + // restore clear color state + glClearColor(cc[0], cc[1], cc[2], cc[3]); + }); +} + +bool Layer::create(int width, int height, std::string name) +{ + m_name = name; + w = width; + h = height; + if (m_frames.empty()) + m_frames.emplace_back(); + App::I->render_task([&] + { + for (int i = 0; i < 6; i++) + { + rtt(i).create(width, height); + rtt(i).bindFramebuffer(); + rtt(i).clear(); + rtt(i).unbindFramebuffer(); + box(i) = glm::vec4(w, h, 0, 0); // reset bounding box + face(i) = false; + } + }); + return true; +} + +bool Layer::add_frame() +{ + return true; +} + +void Layer::resize(int width, int height) +{ + w = width; + h = height; + for (auto& frame : m_frames) + frame.resize(width, height); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + void Layer::Snapshot::create(int w, int h) { width = w; @@ -129,3 +332,30 @@ int Layer::Snapshot::memsize() const } return ret; } + +/////////////////////////////////////////////////////////////////////////////////////////// + +bool LayerFrame::create(int width, int height, int duration /*= 1*/) +{ + for (auto& rtt : m_rtt) + if (!rtt.create(width, height)) + return false; + m_duration = duration; + w = width; + h = height; + return true; +} + +bool LayerFrame::resize(int width, int height) +{ + glm::vec2 ratio = glm::vec2(width, height) / glm::vec2(w, h); + for (int i = 0; i < 6; i++) + { + if (!m_rtt[i].resize(width, height)) + return false; + m_dirty_box[i] = m_dirty_box[i] * glm::vec4(ratio, ratio); + } + w = width; + h = height; + return true; +} diff --git a/src/canvas_layer.h b/src/canvas_layer.h index 2451c87..c1f4f16 100644 --- a/src/canvas_layer.h +++ b/src/canvas_layer.h @@ -3,9 +3,16 @@ #include "log.h" #include "texture.h" -class LayerFrame +struct LayerFrame { - + std::array m_rtt; + std::array m_dirty_box = SIXPLETTE(glm::vec4(0)); + std::array m_dirty_face = SIXPLETTE(false); + int m_duration = 1; + int w = 0, h = 0; + LayerFrame() = default; + bool create(int width, int height, int duration = 1); + bool resize(int width, int height); }; class Layer @@ -14,11 +21,9 @@ class Layer public: Layer() { id = s_count++; } Layer(const Layer&) = delete; - ~Layer() { LOG("LAYER AUTO DESTROY"); destroy(); } uint32_t id; - RTT m_rtt[6]; - std::array m_dirty_box = SIXPLETTE(glm::vec4(0)); - std::array m_dirty_face = SIXPLETTE(false); + std::vector m_frames; + int m_frame_index = 0; bool m_visible = true; bool m_alpha_locked = false; float m_opacity = 1.f; @@ -39,8 +44,13 @@ public: void optimize(); int memsize() const; }; + RTT& rtt(int i); + glm::vec4& box(int i); + bool& face(int i); + LayerFrame& frame(); void resize(int width, int height); bool create(int width, int height, std::string name); + bool add_frame(); void clear(const glm::vec4& c); Snapshot snapshot(std::array* dirty_box = nullptr, std::array* dirty_face = nullptr); TextureCube gen_cube(); diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 1360511..6e2bba8 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -1243,12 +1243,12 @@ void CanvasModeTransform::enter(kCanvasMode prev) App::I->render_task([&] { m_shape[plane].update_vertices(shape3d.data(), (int)shape3d.size()); - Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->m_rtt[plane].bindFramebuffer(); + Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->rtt(plane).bindFramebuffer(); m_tex[plane].create(bb_sz.x, bb_sz.y); m_tex[plane].bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); m_tex[plane].unbind(); - Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->m_rtt[plane].unbindFramebuffer(); + Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->rtt(plane).unbindFramebuffer(); }); m_commit_on_leave = true; @@ -1293,13 +1293,13 @@ void CanvasModeTransform::enter(kCanvasMode prev) action->m_image[i] = std::make_unique(bb_sz.x * bb_sz.y * 4); action->m_box[i] = { bb_min, bb_max }; - action->m_old_box[i] = layer->m_dirty_box[i]; - action->m_old_dirty[i] = layer->m_dirty_face[i]; + action->m_old_box[i] = layer->box(i); + action->m_old_dirty[i] = layer->face(i); - layer->m_dirty_face[i] = true; - layer->m_dirty_box[i] = { - glm::min(xy(layer->m_dirty_box[i]), bb_min), - glm::max(zw(layer->m_dirty_box[i]), bb_max), + layer->face(i) = true; + layer->box(i) = { + glm::min(xy(layer->box(i)), bb_min), + glm::max(zw(layer->box(i)), bb_max), }; App::I->render_task([&] @@ -1311,12 +1311,12 @@ void CanvasModeTransform::enter(kCanvasMode prev) ShaderManager::use(kShader::Color); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 0 }); - layer->m_rtt[i].bindFramebuffer(); + layer->rtt(i).bindFramebuffer(); // copy framebuffer to action data glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get()); for (int j = 0; j < 6; j++) m_shape[j].draw_fill(); - layer->m_rtt[i].unbindFramebuffer(); + layer->rtt(i).unbindFramebuffer(); }); } @@ -1391,23 +1391,23 @@ void CanvasModeTransform::leave(kCanvasMode next) action->m_image[i] = std::make_unique(bb_sz.x * bb_sz.y * 4); action->m_box[i] = { bb_min, bb_max }; - action->m_old_box[i] = layer->m_dirty_box[i]; - action->m_old_dirty[i] = layer->m_dirty_face[i]; + action->m_old_box[i] = layer->box(i); + action->m_old_dirty[i] = layer->face(i); - layer->m_dirty_face[i] = true; - layer->m_dirty_box[i] = { - glm::min(xy(layer->m_dirty_box[i]), bb_min), - glm::max(zw(layer->m_dirty_box[i]), bb_max), + layer->face(i) = true; + layer->box(i) = { + glm::min(xy(layer->box(i)), bb_min), + glm::max(zw(layer->box(i)), bb_max), }; App::I->render_task([&] { - layer->m_rtt[i].bindFramebuffer(); + layer->rtt(i).bindFramebuffer(); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - glViewport(0, 0, layer->m_rtt[i].getWidth(), layer->m_rtt[i].getHeight()); + glViewport(0, 0, layer->rtt(i).getWidth(), layer->rtt(i).getHeight()); // save fb content for history glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get()); @@ -1437,7 +1437,7 @@ void CanvasModeTransform::leave(kCanvasMode next) m_shape[j].draw_fill(); m_tex[j].unbind(); } - layer->m_rtt[i].unbindFramebuffer(); + layer->rtt(i).unbindFramebuffer(); }); } @@ -1674,8 +1674,8 @@ void CanvasModeFloodFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) a->m_layer_index = Canvas::I->m_current_layer_idx; a->m_threshold = m_tool->get_threshold(); a->m_plane = plane; - a->m_dirty_box = plane_data.layer->m_dirty_box; - a->m_dirty_face = plane_data.layer->m_dirty_face; + a->m_dirty_box = plane_data.layer->frame().m_dirty_box; + a->m_dirty_face = plane_data.layer->frame().m_dirty_face; ActionManager::add(a); plane_data.apply(); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 49e83eb..6518a30 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -164,9 +164,9 @@ void NodeCanvas::draw() ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture(); + m_canvas->m_layers_merge.rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture(); + m_canvas->m_layers_merge.rtt(plane_index).unbindTexture(); } } else @@ -217,7 +217,7 @@ void NodeCanvas::draw() 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[plane_index])) + !m_canvas->m_layers[layer_index]->face(plane_index))) continue; if (use_blend) @@ -249,17 +249,17 @@ void NodeCanvas::draw() 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]->m_rtt[plane_index].bindTexture(); + 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.m_rtt[plane_index].bindTexture(); + m_canvas->m_smask.rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); + 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]->m_rtt[plane_index].unbindTexture(); + 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) { @@ -299,11 +299,11 @@ void NodeCanvas::draw() ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset); glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + 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.m_rtt[plane_index].bindTexture(); + m_canvas->m_smask.rtt(plane_index).bindTexture(); glActiveTexture(GL_TEXTURE3); if (b->m_dual_enabled) m_canvas->m_tmp_dual[plane_index].bindTexture(); @@ -316,11 +316,11 @@ void NodeCanvas::draw() if (b->m_dual_enabled) m_canvas->m_tmp_dual[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE2); - m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); + 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]->m_rtt[plane_index].unbindTexture(); + m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else { @@ -332,9 +332,9 @@ void NodeCanvas::draw() ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); - m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture(); + m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture(); + m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture(); } if (use_blend) @@ -380,7 +380,7 @@ void NodeCanvas::draw() #ifdef _DEBUG // draw dirty area { - auto bb = m_canvas->m_layers[layer_index]->m_dirty_box[plane_index] / (float)m_canvas->m_layers[layer_index]->w; + auto bb = m_canvas->m_layers[layer_index]->box(plane_index) / (float)m_canvas->m_layers[layer_index]->w; glm::vec2 bbmin = xy(bb); glm::vec2 bbsz = zw(bb) - xy(bb); ShaderManager::use(kShader::Color); @@ -463,9 +463,9 @@ void NodeCanvas::draw() glm::translate(glm::vec3(0, 0, -1.f)); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); - m_canvas->m_smask.m_rtt[plane_index].bindTexture(); + m_canvas->m_smask.rtt(plane_index).bindTexture(); m_face_plane.draw_fill(); - m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); + m_canvas->m_smask.rtt(plane_index).unbindTexture(); } diff --git a/src/node_panel_layer.cpp b/src/node_panel_layer.cpp index 18a5123..2d75eac 100644 --- a/src/node_panel_layer.cpp +++ b/src/node_panel_layer.cpp @@ -402,12 +402,12 @@ void NodePanelLayer::merge(int src_index, int dst_index, bool create_history) a->m_direction = ActionLayerMerge::Direction::Undo; for (int i = 0; i < 6; i++) { - a->m_dirty_box[i] = Canvas::I->m_layers[dst_index]->m_dirty_box[i]; - a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->m_dirty_face[i]; + a->m_dirty_box[i] = Canvas::I->m_layers[dst_index]->box(i); + a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->face(i); } a->m_snap = std::make_shared(); *a->m_snap = Canvas::I->m_layers[dst_index]->snapshot( - &Canvas::I->m_layers[src_index]->m_dirty_box, &Canvas::I->m_layers[src_index]->m_dirty_face); + &Canvas::I->m_layers[src_index]->frame().m_dirty_box, &Canvas::I->m_layers[src_index]->frame().m_dirty_face); a->m_layer = Canvas::I->m_layers[src_index]; a->m_layer_node = std::static_pointer_cast(m_layers_container->m_children[src_index]); a->m_layer_node->m_selected = false; @@ -491,8 +491,8 @@ void ActionLayerMerge::undo() Canvas::I->m_layers[m_dst_index]->restore(*m_snap); for (int i = 0; i < 6; i++) { - Canvas::I->m_layers[m_dst_index]->m_dirty_box[i] = m_dirty_box[i]; - Canvas::I->m_layers[m_dst_index]->m_dirty_face[i] = m_dirty_face[i]; + Canvas::I->m_layers[m_dst_index]->box(i) = m_dirty_box[i]; + Canvas::I->m_layers[m_dst_index]->face(i) = m_dirty_face[i]; } auto name = m_layer->m_name; m_panel->add_layer(name.c_str(), false, true, m_layer, m_layer_node, m_src_index); diff --git a/src/rtt.cpp b/src/rtt.cpp index 9da0f1d..abef629 100644 --- a/src/rtt.cpp +++ b/src/rtt.cpp @@ -35,8 +35,9 @@ RTT::~RTT() LOG("RTT not destroyed"); } -void RTT::resize(int width, int height) +bool RTT::resize(int width, int height) { + bool ret = false; RTT new_rtt; App::I->render_task([&] @@ -44,7 +45,12 @@ void RTT::resize(int width, int height) glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID); glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID); - new_rtt.create(width, height, -1, int_fmt, rboID != 0); + ret = new_rtt.create(width, height, -1, int_fmt, rboID != 0); + if (!ret) + { + LOG("failed to resize rtt from %dx%d to %dx%d", w, h, width, height); + return; + } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, new_rtt.fboID); glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); @@ -55,6 +61,9 @@ void RTT::resize(int width, int height) destroy(); }); + + if (!ret) + return false; oldRFboID = 0; oldDFboID = 0; @@ -64,6 +73,8 @@ void RTT::resize(int width, int height) int_fmt = new_rtt.int_fmt; w = new_rtt.w; h = new_rtt.h; + + return true; } void RTT::destroy() diff --git a/src/rtt.h b/src/rtt.h index aeaa869..66e1bd4 100644 --- a/src/rtt.h +++ b/src/rtt.h @@ -24,7 +24,7 @@ public: void copy(const RTT& source); // copy a region void copy(const RTT& source, const glm::vec4& rect); - void resize(int width, int height); + bool resize(int width, int height); bool create(int width, int height, int tex = -1, GLint internal_format = GL_RGBA8, bool depth_buffer = false); bool recreate() { return create(w, h); } void clear(glm::vec4 color = glm::vec4(0));